// our id
String id = ctx.generateUniqueId(_delegate.getTagId());
// Cast to use UniqueIdVendor stuff
FaceletCompositionContext mctx = (FaceletCompositionContext) FaceletCompositionContext.getCurrentInstance(ctx);
// grab our component
UIComponent c = null;
//boolean componentFoundInserted = false;
//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 = (VisitContext) mctx.getVisitContextFactory().
getVisitContext(facesContext, null, VISIT_HINTS_DYN_REFRESH);
c.visitTree(visitContext, new PublishFaceletDynamicComponentRefreshTransientBuildCallback());
}
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)
{
mctx.pushUniqueIdVendorToStack((UniqueIdVendor)c);
}
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 (!componentFoundInserted)
//{
if (mctx.isRefreshingSection())
{
facesContext.setProcessingEvents(false);
if (_relocatableResourceHandler != null &&
parent != null && !parent.equals(c.getParent()))
{
// Replace parent with the relocated parent.
parent = c.getParent();
}
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)
{
// add default validators here, because this feature
// is only available in facelets (see MYFACES-2362 for details)
addEnclosingAndDefaultValidators(ctx, mctx, facesContext, (EditableValueHolder) c);
}
}
_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();
}
}