private static void printComponent()

in impl/src/main/java/org/apache/myfaces/util/DebugUtils.java [156:345]


    private static void printComponent(UIComponent comp, PrintStream stream, int indent, boolean withChildrenAndFacets,
                                       String facetName)
    {
        printIndent(stream, indent);
        stream.print('<');

        String compType = comp.getClass().getName();
        if (compType.startsWith(JSF_COMPONENT_PACKAGE))
        {
            compType = compType.substring(JSF_COMPONENT_PACKAGE.length());
        }
        else if (compType.startsWith(MYFACES_COMPONENT_PACKAGE))
        {
            compType = compType.substring(MYFACES_COMPONENT_PACKAGE.length());
        }
        stream.print(compType);
        
        printAttribute(stream, "id", comp.getId());

        if (facetName != null)
        {
            printAttribute(stream, "facetName", facetName);
        }
        
        for (Map.Entry<String, Object> entry : comp.getAttributes().entrySet())
        {
            if (!"id".equals(entry.getKey()))
            {
                printAttribute(stream, entry.getKey(), entry.getValue());
            }
        }
        
        // HACK: comp.getAttributes() only returns attributes, that are NOT backed
        // by a corresponding component property. So, we must explicitly get the
        // available properties by Introspection:
        BeanInfo beanInfo;
        try
        {
            beanInfo = Introspector.getBeanInfo(comp.getClass());
        }
        catch (IntrospectionException e)
        {
            throw new RuntimeException(e);
        }

        if (!compType.startsWith("org.apache.myfaces.view.facelets.compiler"))
        {
            PropertyDescriptor[] propDescriptors = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < propDescriptors.length; i++)
            {
                if (propDescriptors[i].getReadMethod() != null)
                {
                    String name = propDescriptors[i].getName();
                    if (!"id".equals(name))
                    {
                        ValueExpression ve = comp.getValueExpression(name);
                        if (ve != null)
                        {
                            printAttribute(stream, name, ve.getExpressionString());
                        }
                        else
                        {
                            if (name.equals("value") && comp instanceof ValueHolder)
                            {
                                // -> localValue
                            }
                            else if (!IGNORE_ATTRIBUTES.contains(name))
                            {
                                try
                                {
                                    Object value = comp.getAttributes().get(name);
                                    printAttribute(stream, name, value);
                                }
                                catch (Exception e)
                                {
                                    log.log(Level.SEVERE, e.getMessage() , e);
                                    printAttribute(stream, name, null);
                                }
                            }
                        }
                    }
                }
            }
        }

        boolean mustClose = true;
        boolean nestedObjects = false;

        if (comp instanceof UICommand command)
        {
            FacesListener[] listeners = command.getActionListeners();
            if (listeners != null && listeners.length > 0)
            {
                nestedObjects = true;
                stream.println('>');
                mustClose = false;
                for (int i = 0; i < listeners.length; i++)
                {
                    FacesListener listener = listeners[i];
                    printIndent(stream, indent + 1);
                    stream.print('<');
                    stream.print(listener.getClass().getName());
                    stream.println("/>");
                }
            }
        }

        if (comp instanceof UIInput input)
        {
            FacesListener[] listeners = input.getValueChangeListeners();
            if (listeners != null && listeners.length > 0)
            {
                nestedObjects = true;
                stream.println('>');
                mustClose = false;
                for (int i = 0; i < listeners.length; i++)
                {
                    FacesListener listener = listeners[i];
                    printIndent(stream, indent + 1);
                    stream.print('<');
                    stream.print(listener.getClass().getName());
                    stream.println("/>");
                }
            }

            Validator[] validators = input.getValidators();
            if (validators != null && validators.length > 0)
            {
                nestedObjects = true;
                stream.println('>');
                mustClose = false;
                for (int i = 0; i < validators.length; i++)
                {
                    Validator validator = validators[i];
                    printIndent(stream, indent + 1);
                    stream.print('<');
                    stream.print(validator.getClass().getName());
                    stream.println("/>");
                }
            }
        }

        if (withChildrenAndFacets)
        {
            int childCount = comp.getChildCount();
            if (childCount > 0 || comp.getFacetCount() > 0)
            {
                Map<String, UIComponent> facetsMap = comp.getFacets();
                nestedObjects = true;
                if (mustClose)
                {
                    stream.println('>');
                    mustClose = false;
                }

                if (childCount > 0)
                {
                    for (int i = 0; i < childCount; i++)
                    {
                        UIComponent child = comp.getChildren().get(i);
                        printComponent(child, stream, indent + 1, true, null);
                    }
                }

                for (Map.Entry<String, UIComponent> entry : facetsMap.entrySet())
                {
                    printComponent(entry.getValue(), stream, indent + 1, true, entry.getKey());
                }
            }
        }

        if (nestedObjects)
        {
            if (mustClose)
            {
                stream.println("/>");
            }
            else
            {
                printIndent(stream, indent);
                stream.print("</");
                stream.print(compType);
                stream.println('>');
            }
        }
        else
        {
            stream.println("/>");
        }
    }