As soon as I define a composite component in a .taglib.xml to have a <handler-class>
, the .xhtml file is ignored.
What I need is a xhtml/facelet based component with a component-type (UIComponent-derived class) and(!) also with a taghandler class. My aim is to catch all working on its child tags in order to be able to activate a custom cdi scope during this.
I found a way by looking at the richfaces impl.jar.
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<factory>
<tag-handler-delegate-factory>de.sundn.regionscoped.jsf.BehaviorsTagHandlerDelegateFactoryImpl</tag-handler-delegate-factory>
</factory>
</faces-config>
Implement the factory
package de.sundn.regionscoped.jsf;
import javax.faces.FacesWrapper;
import javax.faces.view.facelets.BehaviorHandler;
import javax.faces.view.facelets.ComponentHandler;
import javax.faces.view.facelets.ConverterHandler;
import javax.faces.view.facelets.TagHandlerDelegate;
import javax.faces.view.facelets.TagHandlerDelegateFactory;
import javax.faces.view.facelets.ValidatorHandler;
/**
* @author Nick Belaevski
*/
public class BehaviorsTagHandlerDelegateFactoryImpl extends TagHandlerDelegateFactory implements
FacesWrapper<TagHandlerDelegateFactory> {
private TagHandlerDelegateFactory factory;
public BehaviorsTagHandlerDelegateFactoryImpl(TagHandlerDelegateFactory factory) {
this.factory = factory;
}
@Override
public TagHandlerDelegate createBehaviorHandlerDelegate(BehaviorHandler owner) {
return factory.createBehaviorHandlerDelegate(owner);
}
@Override
public TagHandlerDelegate createComponentHandlerDelegate(ComponentHandler owner) {
// TagHandlers structure is created when view is compiled
// so there's no need to check for BehaviorsStack
if (owner instanceof BehaviorsAddingComponentHandlerWrapper) {
// this is to avoid StackOverflowError because of ComponentHandler constructor call
return null;
}
ComponentHandler wrappedHandler = new BehaviorsAddingComponentHandlerWrapper(owner);
return factory.createComponentHandlerDelegate(wrappedHandler);
}
@Override
public TagHandlerDelegate createConverterHandlerDelegate(ConverterHandler owner) {
return factory.createConverterHandlerDelegate(owner);
}
@Override
public TagHandlerDelegate createValidatorHandlerDelegate(ValidatorHandler owner) {
return factory.createValidatorHandlerDelegate(owner);
}
@Override
public TagHandlerDelegateFactory getWrapped() {
return factory;
}
}