Resource ccResource) {
// PENDING this implementation is terribly wasteful.
// Must find a better way.
CompositeComponentBeanInfo result;
FaceletContext ctx = (FaceletContext)
context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
FaceletFactory factory = (FaceletFactory)
RequestStateManager.get(context, RequestStateManager.FACELET_FACTORY);
VariableMapper orig = ctx.getVariableMapper();
// create tmp and facetComponent
UIComponent tmp = context.getApplication().createComponent("javax.faces.NamingContainer");
UIPanel facetComponent = (UIPanel)
context.getApplication().createComponent("javax.faces.Panel");
// PENDING I think this can be skipped because we don't render
// this component instance.
facetComponent.setRendererType("javax.faces.Group");
// PENDING This could possibly be skipped too. However, I think
// this is important because other tag handlers, within
// <cc:interface> expect it will be there.
tmp.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, facetComponent);
// We have to put the resource in here just so the classes that eventually
// get called by facelets have access to it.
tmp.getAttributes().put(Resource.COMPONENT_RESOURCE_KEY,
ccResource);
Facelet f;
try {
f = factory.getFacelet(ccResource.getURL());
VariableMapper wrapper = new VariableMapperWrapper(orig) {
@Override
public ValueExpression resolveVariable(String variable) {
return super.resolveVariable(variable);
}
};
ctx.setVariableMapper(wrapper);
context.getAttributes().put(IS_BUILDING_METADATA, Boolean.TRUE);
// Because mojarra currently requires a <cc:interface>
// element within the compcomp markup, we can rely on the
// fact that its tag handler, InterfaceHandler.apply(), is
// called. In this method, we first imbue facetComponent
// with any config information present on the <cc:interface>
// element.
// Then we do the normal facelet thing:
// this.nextHandler.apply(). This causes any child tag
// handlers of the <cc:interface> to be called. The
// compcomp spec says each such tag handler is responsible
// for adding to the compcomp metadata, referenced from the
// facetComponent parent.
f.apply(context, facetComponent);
// When f.apply() returns (and therefore
// InterfaceHandler.apply() returns), the compcomp metadata
// pointed to by facetComponent is fully populated.
} catch (Exception e) {
if (e instanceof FacesException) {
throw (FacesException) e;
} else {
throw new FacesException(e);
}
}
finally {
context.getAttributes().remove(IS_BUILDING_METADATA);
ctx.setVariableMapper(orig);
}
// we extract the compcomp metadata and return it, making sure
// to discard tmp and facetComponent. The compcomp metadata
// should be cacheable and shareable across threads, but this is
// not yet implemented.