When implementing a custom facelets component which extends some existing component, it is pretty common that your custom component accepts the same attributes as the component being extended. For example extended h:inputText could be as following:
<ui:composition>
<custom:decorate styleClass="input">
<h:inputText id="#{id}" value="#{value}" required="#{required}"
styleClass="#{styleClass}" disabled="#{disabled}" rendered="#{rendered}"
converterMessage="#{converterMessage}"
requiredMessage="#{requiredMessage}"
validatorMessage="#{validatorMessage}" onchange="#{onchange}"
style="#{style}">
<ui:insert/>
</h:inputText>
</custom:decorate></ui:composition>
The goal is to allow component's client to use extended version in the same way as the component being extended. The example above has the following gaps:
- id attribute is required, passing no value will not force auto id generation.
- converterMessage, requiredMessage, validatorMessage, ... - pretty the same as 'id' attribute these attributes should have special meaning if not provided by client
- disabled, rendered, and other boolean attributes - if client does not provide value then '#{attributeName}' is resolved to 'false'.
- action and actionListener - for action source components, facelets are trying to evaluate value specified by client as 'ValueExpression', not as 'MethodExpression'.
There are some simple straightforward solutions (for example to use c:if, c:when, etc. to handle 1-3; passing bean and actionMethodName or implement an action mapper component to handle 4), but when number of attributes is large, component's code become a hell of spaghetti code.
Maybe there are already some solid solutions available for JSF 1.2? It will be also useful for me to see an answer with nice id开发者_开发百科eas how to implement such solution or a part of a solution.
精彩评论