public UIComponent createComponent()

in impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java [2464:2620]


    public UIComponent createComponent(FacesContext context, 
        String taglibURI, String tagName, Map<String, Object> attributes)
    {
        Assert.notNull(context, "context");
        UIComponent createdComponent = null;
        try
        {
            Facelet componentFacelet;
            FaceletFactory.setInstance(faceletFactory);
            try
            {
                componentFacelet
                        = faceletFactory.compileComponentFacelet(taglibURI, tagName, attributes);
            }
            finally
            {
                FaceletFactory.setInstance(null);
            }
            if (componentFacelet == null)
            {
                return null;
            }
            // Create a temporal component base class where all components will be put, but we are only
            // interested in the inner UIComponent and if multiple are created, return this one.
            boolean requiresDynamicRefresh = false;
            boolean requiresFaceletDynamicRefresh = false;
            UIPanel tempParent
                    = (UIPanel) context.getApplication().createComponent(
                    context, UIPanel.COMPONENT_TYPE, null);
            tempParent.setId(context.getViewRoot().createUniqueId(context, null));
            String baseKey = tempParent.getId();
            baseKey = baseKey.startsWith(UIViewRoot.UNIQUE_ID_PREFIX) ? baseKey.substring(4) : baseKey;

            try
            {
                tempParent.pushComponentToEL(context, tempParent);
                ((AbstractFacelet)componentFacelet).applyDynamicComponentHandler(
                    context, tempParent, baseKey);
            }
            finally
            {
                tempParent.popComponentFromEL(context);
                // There are two cases:
                // 1. If we are under facelets algorithm control (binding case), the refreshing logic will be done
                // outside this block. We can check that condition easily with FaceletCompositionContext
                // 2. If we are not under facelets algorithm control, check if the dynamic component requires refresh,
                // if that so, mark the view to be refreshed and reset the flag, otherwise continue. This check
                // allows us to decide if we add a third listener to refresh on transient build.
                    // Check if the current component requires dynamic refresh and if that so,
                FaceletCompositionContext fcc = FaceletCompositionContext.getCurrentInstance(context);
                if (fcc != null)
                {
                    requiresFaceletDynamicRefresh = true;
                }
                else if (FaceletViewDeclarationLanguageBase.isDynamicComponentNeedsRefresh(context))
                {
                    FaceletViewDeclarationLanguageBase.activateDynamicComponentRefreshTransientBuild(context);
                    FaceletViewDeclarationLanguageBase.resetDynamicComponentNeedsRefreshFlag(context);
                    requiresDynamicRefresh = true;
                }
            }
            if (tempParent.getChildCount() > 1)
            {
                // Multiple child. The tempParent will be returned. No need to
                // save MARK_CREATED.
                createdComponent = tempParent;
                tempParent.getAttributes().put(DYN_WRAPPER, baseKey);
                tempParent.subscribeToEvent(PostRestoreStateEvent.class, new 
                    RefreshDynamicComponentListener(taglibURI, tagName, attributes, baseKey));
                if (requiresFaceletDynamicRefresh)
                {
                    FaceletViewDeclarationLanguageBase.dynamicComponentNeedsRefresh(context);
                }
            }
            else if (tempParent.getChildCount() == 1)
            {
                createdComponent = tempParent.getChildren().get(0);
                boolean requiresRefresh = false;
                // One child. In that case there are three choices:
                if (UIComponent.isCompositeComponent(createdComponent))
                {
                    // 1. Composite component. Needs special handling because
                    // facets will be added programmatically. The algorithm that
                    // process the composite component content should occur
                    // after the component is added to the view (PostAddToViewEvent).
                    // Requires refresh. To do that, we need to save the MARK_CREATED
                    // value and set it only when the full component is refreshed after 
                    // restore it.
                    createdComponent.getAttributes().put(GEN_MARK_ID,
                        createdComponent.getAttributes().get(ComponentSupport.MARK_CREATED));
                    createdComponent.getAttributes().put(ComponentSupport.MARK_CREATED, null);
                    createdComponent.subscribeToEvent(PostAddToViewEvent.class, new 
                        CreateDynamicCompositeComponentListener(taglibURI, tagName, attributes, baseKey));
                    requiresRefresh = true;
                    if (requiresFaceletDynamicRefresh)
                    {
                        FaceletViewDeclarationLanguageBase.dynamicComponentNeedsRefresh(context);
                    }
                }
                else if (createdComponent.getChildCount() > 0)
                {
                    // 2. Single component with children inside.
                    // Requires refresh. To do that, we need to save the MARK_CREATED
                    // value and set it only when the full component is refreshed after 
                    // restore it.
                    createdComponent.getAttributes().put(GEN_MARK_ID,
                        createdComponent.getAttributes().get(ComponentSupport.MARK_CREATED));
                    createdComponent.getAttributes().put(ComponentSupport.MARK_CREATED, null);
                    requiresRefresh = true;
                    if (requiresFaceletDynamicRefresh)
                    {
                        FaceletViewDeclarationLanguageBase.dynamicComponentNeedsRefresh(context);
                    }
                }
                else if (createdComponent.isTransient())
                {
                    // Just transient markup inside. It is necessary to wrap
                    // that content into a component. Requires refresh. No need to
                    // save MARK_CREATED. No requires dynamic refresh.
                    createdComponent = tempParent;
                    tempParent.getAttributes().put(DYN_WRAPPER, baseKey);
                    requiresRefresh = true;
                }
                else
                {
                    // 4. Single component without children: 
                    // Remove MARK_CREATED because it does not requires
                    // refresh on restore. When it is added to the component
                    // tree, it will be saved and restored as if was a programmatically
                    // added component.
                    createdComponent.getAttributes().put(ComponentSupport.MARK_CREATED, null);
                }
                if (requiresRefresh)
                {
                    createdComponent.subscribeToEvent(PostRestoreStateEvent.class, new 
                        RefreshDynamicComponentListener(taglibURI, tagName, attributes, baseKey));
                }
                if (requiresDynamicRefresh)
                {
                    createdComponent.subscribeToEvent(DynamicComponentRefreshTransientBuildEvent.class, new 
                        RefreshDynamicComponentListener(taglibURI, tagName, attributes, baseKey));
                    createdComponent.getAttributes().put(
                            DynamicComponentRefreshTransientBuildEvent.DYN_COMP_REFRESH_FLAG, Boolean.TRUE);
                }
                if (requiresFaceletDynamicRefresh)
                {
                    createdComponent.subscribeToEvent(FaceletDynamicComponentRefreshTransientBuildEvent.class, new 
                        RefreshDynamicComponentListener(taglibURI, tagName, attributes, baseKey));
                }
            }
        }
        catch (IOException e)
        {
            throw new FacesException(e);
        }
        return createdComponent;
    }