如何创建复合组件的实例以及如何获取它
How is an instance of composite component created and how can I get it
我正在使用 Mojarra 2.1。阅读 this 关于何时使用自定义标签和复合组件的回答,我遇到了有关组件内部结构的问题。
因此,自定义标签和复合组件之间最重要的区别是每个复合组件都有一个 UIComponent
实例,在 查看构建时间 [=34] 之后在组件树中表示它=] 完成了。自定义标签反过来在树中没有一个 UIComponent
实例代表它。
那么,class 代表树中的复合组件是什么?它是如何创建的?那是一些匿名的 class 吗?让我们考虑来自 wiki 页面的示例:
<ui:component
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
>
<cc:interface>
<!-- Define component attributes here -->
</cc:interface>
<cc:implementation>
<!-- Define component body here -->
</cc:implementation>
</ui:component>
如何获取代表该复合组件的 UIComponent
的实例?
深入研究 UIComponent
的源代码,我发现了以下方法:
public static boolean isCompositeComponent(UIComponent component) {
if (component == null) {
throw new NullPointerException();
}
boolean result = false;
if (null != component.isCompositeComponent) {
result = component.isCompositeComponent.booleanValue();
} else {
result = component.isCompositeComponent =
(component.getAttributes().containsKey(
Resource.COMPONENT_RESOURCE_KEY));
}
return result;
}
我怀疑它的实现详细说明了如何创建复合组件 class。事实上,我想找到 Mojarra 实现在哪里生成复合组件 class 实例。
UPD:复合组件的定义已替换为未明确定义 componentType
属性的定义。
基本上是UIPanel
instance which you can just get via UIComponent#findComponent()
the usual way, passing the composite component client ID. In case of Mojarra, you can find the code responsible for creating it in com.sun.faces.facelets.tag.jsf.CompositeComponentTagHandler
which has in Mojarra 2.2.11下面的逻辑:
360 if (ComponentHandler.isNew(c)) {
361 facetComponent = (UIPanel)
362 facesContext.getApplication().createComponent("javax.faces.Panel");
363 facetComponent.setRendererType("javax.faces.Group");
364 c.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, facetComponent);
365 }
366 else {
367 facetComponent = (UIPanel)
368 c.getFacets().get(UIComponent.COMPOSITE_FACET_NAME);
369 }
我正在使用 Mojarra 2.1。阅读 this 关于何时使用自定义标签和复合组件的回答,我遇到了有关组件内部结构的问题。
因此,自定义标签和复合组件之间最重要的区别是每个复合组件都有一个 UIComponent
实例,在 查看构建时间 [=34] 之后在组件树中表示它=] 完成了。自定义标签反过来在树中没有一个 UIComponent
实例代表它。
那么,class 代表树中的复合组件是什么?它是如何创建的?那是一些匿名的 class 吗?让我们考虑来自 wiki 页面的示例:
<ui:component
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
>
<cc:interface>
<!-- Define component attributes here -->
</cc:interface>
<cc:implementation>
<!-- Define component body here -->
</cc:implementation>
</ui:component>
如何获取代表该复合组件的 UIComponent
的实例?
深入研究 UIComponent
的源代码,我发现了以下方法:
public static boolean isCompositeComponent(UIComponent component) {
if (component == null) {
throw new NullPointerException();
}
boolean result = false;
if (null != component.isCompositeComponent) {
result = component.isCompositeComponent.booleanValue();
} else {
result = component.isCompositeComponent =
(component.getAttributes().containsKey(
Resource.COMPONENT_RESOURCE_KEY));
}
return result;
}
我怀疑它的实现详细说明了如何创建复合组件 class。事实上,我想找到 Mojarra 实现在哪里生成复合组件 class 实例。
UPD:复合组件的定义已替换为未明确定义 componentType
属性的定义。
基本上是UIPanel
instance which you can just get via UIComponent#findComponent()
the usual way, passing the composite component client ID. In case of Mojarra, you can find the code responsible for creating it in com.sun.faces.facelets.tag.jsf.CompositeComponentTagHandler
which has in Mojarra 2.2.11下面的逻辑:
360 if (ComponentHandler.isNew(c)) {
361 facetComponent = (UIPanel)
362 facesContext.getApplication().createComponent("javax.faces.Panel");
363 facetComponent.setRendererType("javax.faces.Group");
364 c.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, facetComponent);
365 }
366 else {
367 facetComponent = (UIPanel)
368 c.getFacets().get(UIComponent.COMPOSITE_FACET_NAME);
369 }