полагается на.

ужно программно создавать составные компоненты в JSF 2. После нескольких дней поиска и экспериментов я выясняю этот метод (вдохновленный Лекси на java.net):

/**
 * Method will attach composite component to provided component
 * @param viewPanel parent component of newly created composite component
 */
public void setComponentJ(UIComponent viewPanel) {
    FacesContext context = FacesContext.getCurrentInstance();
    viewPanel.getChildren().clear();

    // load composite component from file
    Resource componentResource = context.getApplication().getResourceHandler().createResource("whatever.xhtml", "components/form");
    UIComponent composite = context.getApplication().createComponent(context, componentResource);

    // push component to el
    composite.pushComponentToEL(context, composite);
    boolean compcompPushed = false;
    CompositeComponentStackManager ccStackManager = CompositeComponentStackManager.getManager(context);
    compcompPushed = ccStackManager.push(composite, CompositeComponentStackManager.StackType.TreeCreation);

    // Populate the component with value expressions 
    Application application = context.getApplication();
    composite.setValueExpression("value", application.getExpressionFactory().createValueExpression(
            context.getELContext(), "#{stringValue.value}",
            String.class));

    // Populate the component with facets and child components (Optional)
    UIOutput foo = (UIOutput) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
    foo.setValue("Foo");
    composite.getFacets().put("foo", foo);
    UIOutput bar = (UIOutput) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
    bar.setValue("Bar");
    composite.getChildren().add(bar);

    // create composite components Root
    UIComponent compositeRoot = context.getApplication().createComponent(UIPanel.COMPONENT_TYPE);
    composite.getAttributes().put(Resource.COMPONENT_RESOURCE_KEY, componentResource);
    compositeRoot.setRendererType("javax.faces.Group");
    composite.setId("compositeID");

    try {
        FaceletFactory factory = (FaceletFactory) RequestStateManager.get(context, RequestStateManager.FACELET_FACTORY);
        Facelet f = factory.getFacelet(componentResource.getURL());
        f.apply(context, compositeRoot); //<==[here]
    } catch (Exception e) {
        log.debug("Error creating composite component!!", e);
    }
    composite.getFacets().put(
            UIComponent.COMPOSITE_FACET_NAME, compositeRoot);

    // attach composite component to parent componet
    viewPanel.getChildren().add(composite);

    // pop component from el
    composite.popComponentFromEL(context);
    if (compcompPushed) {
        ccStackManager.pop(CompositeComponentStackManager.StackType.TreeCreation);
    }
}

Проблема в том, что этот код работает для меня, только когда javax.faces.PROJECT_STAGE установлен в PRODUCTION (мне потребовался целый день, чтобы понять это). Если для javax.faces.PROJECT_STAGE установлено значение DEVELOPMENT, исключение выдается в отмеченной точке (<== [здесь]):

javax.faces.view.facelets.TagException: /resources/components/form/pokus.xhtml @8,19 <cc:interface> Component Not Found for identifier: j_id2.getParent().  
    at com.sun.faces.facelets.tag.composite.InterfaceHandler.validateComponent(InterfaceHandler.java:135)  
    at com.sun.faces.facelets.tag.composite.InterfaceHandler.apply(InterfaceHandler.java:125)  
    at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)  
    at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)  
    at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:82)  
    at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:152)  
    at cz.boza.formcreator.formcore.Try.setComponentJ(Try.java:83)  
    at cz.boza.formcreator.formcore.FormCreator.<init>(FormCreator.java:40)  
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)  
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)  
    at java.lang.reflect.Constructor.newInstance(Constructor.java:532)  

Это некоторая проблема с родительским набором в компоненте CompositeRoot (j_id2 - это автоматически сгенерированный идентификатор CompositeRoot). Также этот код недостаточно протестирован, поэтому я не уверен, что могу на него положиться.

Я думаю, что очень важно иметь возможность манипулировать составными компонентами программно. В противном случае составные компоненты наполовину бесполезны.

Большое спасибо.

Ответы на вопрос(1)

Ваш ответ на вопрос