public void apply()

in impl/src/main/java/org/apache/myfaces/view/facelets/tag/faces/ComponentTagHandlerDelegate.java [195:470]


    public void apply(FaceletContext ctx, UIComponent parent) throws IOException
    {
        // make sure our parent is not null
        if (parent == null)
        {
            throw new TagException(_delegate.getTag(), "Parent UIComponent was null");
        }
        
        FacesContext facesContext = ctx.getFacesContext();

        // possible facet scoped
        String facetName = this.getFacetName(ctx, parent);

        // our id
        String id = ctx.generateUniqueId(_delegate.getTagId());

        // Cast to use UniqueIdVendor stuff
        FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(ctx);
                
        // grab our component
        UIComponent c = null;

        //Used to preserve the original parent. Note when the view is being refreshed, the real parent could be
        //another component.
        UIComponent oldParent = parent;
        
        if (mctx.isRefreshingSection())
        {
            if (_relocatableResourceHandler != null)
            {
                c = _relocatableResourceHandler.findChildByTagId(ctx, parent, id);
            }
            else
            {
                if (facetName != null)
                {
                    c = ComponentSupport.findChildInFacetByTagId(parent, id, facetName);
                }
                else
                {
                    c = ComponentSupport.findChildInChildrenByTagId(parent, id);
                }
            }
        }

        boolean componentFound = false;
        if (c != null)
        {
            componentFound = true;
            // Check if the binding needs dynamic refresh and if that so, invoke the refresh from this location, to
            // preserve the same context
            if (_delegate.getBinding() != null &&
                c.getAttributes().containsKey(
                    FaceletDynamicComponentRefreshTransientBuildEvent.DYNAMIC_COMPONENT_BINDING_NEEDS_REFRESH))
            {
                VisitContext visitContext = mctx.getVisitContextFactory().
                    getVisitContext(facesContext, null, MyFacesVisitHints.SET_SKIP_ITERATION);
                c.visitTree(visitContext, PublishFaceletDynamicComponentRefreshTransientBuildCallback.INSTANCE);
            }
            
            mctx.incrementUniqueComponentId();
            
            // mark all children for cleaning
            if (log.isLoggable(Level.FINE))
            {
                log.fine(_delegate.getTag() + " Component[" + id + "] Found, marking children for cleanup");
            }

            // The call for mctx.markForDeletion(c) is always necessary, because
            // component resource relocation occur as an effect of PostAddToViewEvent,
            // so at this point it is unknown if the component was relocated or not.
            mctx.markForDeletion(c);

            if (_relocatableResourceHandler != null)
            {
                mctx.markRelocatableResourceForDeletion(c);
            }
        }
        else
        {
            c = this.createComponent(ctx);
            if (log.isLoggable(Level.FINE))
            {
                log.fine(_delegate.getTag() + " Component[" + id + "] Created: " + c.getClass().getName());
            }
            
            _delegate.setAttributes(ctx, c);

            // mark it owned by a facelet instance
            c.getAttributes().put(ComponentSupport.MARK_CREATED, id);

            if (facesContext.isProjectStage(ProjectStage.Development))
            {
                c.getAttributes().put(UIComponent.VIEW_LOCATION_KEY, _delegate.getTag().getLocation());
            }

            // assign our unique id
            if (this._id != null)
            {
                mctx.incrementUniqueComponentId();
                c.setId(this._id.getValue(ctx));
            }
            else
            {
                String componentId = mctx.generateUniqueComponentId();
                UniqueIdVendor uniqueIdVendor = mctx.getUniqueIdVendorFromStack();
                if (uniqueIdVendor == null)
                {
                    uniqueIdVendor = facesContext.getViewRoot();
                    
                    if (uniqueIdVendor == null)
                    {
                        // facesContext.getViewRoot() returns null here if we are in
                        // phase restore view, so we have to try to get the view root
                        // via the method in ComponentSupport and our parent
                        uniqueIdVendor = ComponentSupport.getViewRoot(ctx, parent);
                    }
                }
                if (uniqueIdVendor != null)
                {
                    // UIViewRoot implements UniqueIdVendor, so there is no need to cast to UIViewRoot
                    // and call createUniqueId()
                    String uid = uniqueIdVendor.createUniqueId(facesContext, componentId);
                    c.setId(uid);
                }
            }

            if (this._rendererType != null)
            {
                c.setRendererType(this._rendererType);
            }

            // hook method
            _delegate.onComponentCreated(ctx, c, parent);
            
            if (_relocatableResourceHandler != null && 
                _relocatableResourceHandler instanceof ComponentRelocatableResourceHandler)
            {
                UIComponent parentCompositeComponent = mctx.getCompositeComponentFromStack();
                if (parentCompositeComponent != null)
                {
                    c.getAttributes().put(CompositeComponentELUtils.LOCATION_KEY,
                            parentCompositeComponent.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY));
                }
            }
            
            if (mctx.isRefreshingTransientBuild() && _relocatableResourceHandler != null)
            {
                mctx.markRelocatableResourceForDeletion(c);
            }
        }
        c.pushComponentToEL(facesContext, c);

        if (c instanceof UniqueIdVendor vendor)
        {
            mctx.pushUniqueIdVendorToStack(vendor);
        }
        
        if (mctx.isDynamicComponentTopLevel())
        {
            mctx.setDynamicComponentTopLevel(false);
            _delegate.applyNextHandler(ctx, c);
            mctx.setDynamicComponentTopLevel(true);
        }
        else
        {
            // first allow c to get populated
            _delegate.applyNextHandler(ctx, c);
        }
        
        boolean oldProcessingEvents = facesContext.isProcessingEvents();
        // finish cleaning up orphaned children
        if (componentFound && !mctx.isDynamicComponentTopLevel())
        {
            mctx.finalizeForDeletion(c);

            if (mctx.isRefreshingSection())
            {
                facesContext.setProcessingEvents(false);
                if (_relocatableResourceHandler != null && parent != null && !parent.equals(c.getParent()))
                {
                    // Replace parent with the relocated parent.
                    parent = c.getParent();
                    // Since we changed the parent, the facetName becomes invalid, because it points
                    // to the component before relocation. We need to find the right facetName (if any) so we can
                    // refresh the component properly.
                    UIComponent c1 = ComponentSupport.findChildInChildrenByTagId(parent, id);
                    if (c1 == null)
                    {
                        facetName = ComponentSupport.findChildInFacetsByTagId(parent, id);
                    }
                    else
                    {
                        facetName = null;
                    }
                }
                ComponentSupport.setCachedFacesContext(c, facesContext);
            }
            
            if (facetName == null)
            {
                parent.getChildren().remove(c);
            }
            else
            {
                ComponentSupport.removeFacet(ctx, parent, c, facetName);
            }
            
            if (mctx.isRefreshingSection())
            {
                ComponentSupport.setCachedFacesContext(c, null);
                facesContext.setProcessingEvents(oldProcessingEvents);
            }
        }

        if (!componentFound)
        {
            if (c instanceof ClientBehaviorHolder && !UIComponent.isCompositeComponent(c))
            {
                Iterator<AjaxHandler> it = ((AbstractFaceletContext) ctx).getAjaxHandlers();
                if (it != null)
                {
                    while(it.hasNext())
                    {
                        it.next().applyAttachedObject(facesContext, c);
                    }
                }
            }
            
            if (c instanceof EditableValueHolder holder)
            {
                // add default validators here, because this feature 
                // is only available in facelets (see MYFACES-2362 for details)
                addEnclosingAndDefaultValidators(ctx, mctx, facesContext, holder);
            }
        }
        
        _delegate.onComponentPopulated(ctx, c, oldParent);

        if (!mctx.isDynamicComponentTopLevel() || !componentFound)
        {
            if (componentFound && mctx.isRefreshingSection())
            {
                facesContext.setProcessingEvents(false);
                ComponentSupport.setCachedFacesContext(c, facesContext);
            }
            
            if (facetName == null)
            {
                parent.getChildren().add(c);
            }
            else
            {
                ComponentSupport.addFacet(ctx, parent, c, facetName);
            }
            
            if (componentFound && mctx.isRefreshingSection())
            {
                ComponentSupport.setCachedFacesContext(c, null);
                facesContext.setProcessingEvents(oldProcessingEvents);
            }
        }

        if (c instanceof UniqueIdVendor)
        {
            mctx.popUniqueIdVendorToStack();
        }

        c.popComponentFromEL(facesContext);
        
        if (mctx.isMarkInitialState())
        {
            //Call it only if we are using partial state saving
            c.markInitialState();
        }
    }