use of jakarta.faces.view.BehaviorHolderAttachedObjectTarget in project myfaces by apache.
the class FaceletViewDeclarationLanguage method retargetAttachedObjects.
/**
* In short words, this method take care of "target" an "attached object".
* <ul>
* <li>The "attached object" is instantiated by a tag handler.</li>
* <li>The "target" is an object used as "marker", that exposes a List<UIComponent></li>
* </ul>
* This method should be called from some composite component tag handler, after
* all children of composite component has been applied.
*/
@Override
@SuppressWarnings("unchecked")
public void retargetAttachedObjects(FacesContext context, UIComponent topLevelComponent, List<AttachedObjectHandler> handlerList) {
Assert.notNull(context, "context");
Assert.notNull(topLevelComponent, "topLevelComponent");
Assert.notNull(handlerList, "handlerList");
BeanInfo compositeComponentMetadata = (BeanInfo) topLevelComponent.getAttributes().get(UIComponent.BEANINFO_KEY);
if (compositeComponentMetadata == null) {
log.severe("Composite component metadata not found for: " + topLevelComponent.getClientId(context));
return;
}
BeanDescriptor compositeComponentDescriptor = compositeComponentMetadata.getBeanDescriptor();
List<AttachedObjectTarget> targetList = (List<AttachedObjectTarget>) compositeComponentDescriptor.getValue(AttachedObjectTarget.ATTACHED_OBJECT_TARGETS_KEY);
if (targetList == null || targetList.isEmpty()) {
return;
}
for (int i = 0, size = handlerList.size(); i < size; i++) {
AttachedObjectHandler currentHandler = handlerList.get(i);
// In the spec javadoc this variable is referred as forAttributeValue, but
// note it is also called curTargetName
String forValue = currentHandler.getFor();
// and ClientBehaviorHandler.apply
for (int k = 0, targetsSize = targetList.size(); k < targetsSize; k++) {
AttachedObjectTarget currentTarget = targetList.get(k);
FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance();
if ((forValue != null && forValue.equals(currentTarget.getName())) && ((currentTarget instanceof ActionSource2AttachedObjectTarget && currentHandler instanceof ActionSource2AttachedObjectHandler) || (currentTarget instanceof EditableValueHolderAttachedObjectTarget && currentHandler instanceof EditableValueHolderAttachedObjectHandler) || (currentTarget instanceof ValueHolderAttachedObjectTarget && currentHandler instanceof ValueHolderAttachedObjectHandler))) {
// perf: getTargets return ArrayList - see getTargets implementations
List<UIComponent> targets = currentTarget.getTargets(topLevelComponent);
for (int l = 0, targetsCount = targets.size(); l < targetsCount; l++) {
UIComponent component = targets.get(l);
// its tag handler is applied.
if (UIComponent.isCompositeComponent(component)) {
// How we obtain the list of AttachedObjectHandler for
// the current composite component? It should be a component
// attribute or retrieved by a key inside component.getAttributes
// map. Since api does not specify any attribute, we suppose
// this is an implementation detail and it should be retrieved
// from component attribute map.
// But this is only the point of the iceberg, because we should
// define how we register attached object handlers in this list.
// ANS: see CompositeComponentResourceTagHandler.
// The current handler should be added to the list, to be chained.
// Note that the inner component should have a target with the same name
// as "for" attribute
mctx.addAttachedObjectHandler(component, currentHandler);
List<AttachedObjectHandler> handlers = mctx.getAttachedObjectHandlers(component);
retargetAttachedObjects(context, component, handlers);
handlers.remove(currentHandler);
} else {
currentHandler.applyAttachedObject(context, component);
}
if (mctx.isUsingPSSOnThisView() && mctx.isMarkInitialState()) {
component.markInitialState();
}
}
} else if ((currentTarget instanceof BehaviorHolderAttachedObjectTarget && currentHandler instanceof BehaviorHolderAttachedObjectHandler)) {
String eventName = ((BehaviorHolderAttachedObjectHandler) currentHandler).getEventName();
boolean isDefaultEvent = ((BehaviorHolderAttachedObjectTarget) currentTarget).isDefaultEvent();
if ((eventName != null && eventName.equals(currentTarget.getName())) || (eventName == null && isDefaultEvent)) {
List<UIComponent> targets = currentTarget.getTargets(topLevelComponent);
for (int j = 0, targetssize = targets.size(); j < targetssize; j++) {
UIComponent component = targets.get(j);
// its tag handler is applied.
if (UIComponent.isCompositeComponent(component)) {
if (currentTarget instanceof ClientBehaviorAttachedObjectTarget) {
mctx.addAttachedObjectHandler(component, new ClientBehaviorRedirectBehaviorAttachedObjectHandlerWrapper((BehaviorHolderAttachedObjectHandler) currentHandler, ((ClientBehaviorAttachedObjectTarget) currentTarget).getEvent()));
} else {
mctx.addAttachedObjectHandler(component, currentHandler);
}
List<AttachedObjectHandler> handlers = mctx.getAttachedObjectHandlers(component);
retargetAttachedObjects(context, component, handlers);
handlers.remove(currentHandler);
} else {
if (currentHandler instanceof ClientBehaviorRedirectBehaviorAttachedObjectHandlerWrapper) {
ClientBehaviorRedirectBehaviorAttachedObjectHandlerWrapper wrapper = (ClientBehaviorRedirectBehaviorAttachedObjectHandlerWrapper) currentHandler;
currentHandler.applyAttachedObject(context, new ClientBehaviorRedirectEventComponentWrapper(topLevelComponent, component, wrapper.getWrappedEventName(), eventName));
} else {
currentHandler.applyAttachedObject(context, component);
}
}
if (mctx.isUsingPSSOnThisView() && mctx.isMarkInitialState()) {
component.markInitialState();
}
}
}
}
}
}
}
use of jakarta.faces.view.BehaviorHolderAttachedObjectTarget in project mojarra by eclipse-ee4j.
the class BehaviorTagHandlerDelegateImpl method apply.
@Override
public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
// only process if it's been created
if (parent == null || !(parent.getParent() == null)) {
return;
}
ComponentSupport.copyPassthroughAttributes(ctx, parent, owner.getTag());
if (UIComponent.isCompositeComponent(parent)) {
// Check composite component event name:
BeanInfo componentBeanInfo = (BeanInfo) parent.getAttributes().get(UIComponent.BEANINFO_KEY);
if (null == componentBeanInfo) {
throw new TagException(owner.getTag(), "Error: enclosing composite component does not have BeanInfo attribute");
}
BeanDescriptor componentDescriptor = componentBeanInfo.getBeanDescriptor();
if (null == componentDescriptor) {
throw new TagException(owner.getTag(), "Error: enclosing composite component BeanInfo does not have BeanDescriptor");
}
List<AttachedObjectTarget> targetList = (List<AttachedObjectTarget>) componentDescriptor.getValue(AttachedObjectTarget.ATTACHED_OBJECT_TARGETS_KEY);
if (null == targetList) {
throw new TagException(owner.getTag(), "Error: enclosing composite component does not support behavior events");
}
String eventName = owner.getEventName();
boolean supportedEvent = false;
for (AttachedObjectTarget target : targetList) {
if (target instanceof BehaviorHolderAttachedObjectTarget) {
BehaviorHolderAttachedObjectTarget behaviorTarget = (BehaviorHolderAttachedObjectTarget) target;
if (null != eventName && eventName.equals(behaviorTarget.getName()) || null == eventName && behaviorTarget.isDefaultEvent()) {
supportedEvent = true;
break;
}
}
}
if (supportedEvent) {
CompositeComponentTagHandler.getAttachedObjectHandlers(parent).add(owner);
} else {
throw new TagException(owner.getTag(), "Error: enclosing composite component does not support event " + eventName);
}
} else if (parent instanceof ClientBehaviorHolder) {
owner.applyAttachedObject(ctx.getFacesContext(), parent);
} else {
throw new TagException(owner.getTag(), "Parent not an instance of ClientBehaviorHolder: " + parent);
}
}
use of jakarta.faces.view.BehaviorHolderAttachedObjectTarget in project mojarra by eclipse-ee4j.
the class FaceletViewHandlingStrategy method retargetAttachedObjects.
/**
* @see ViewHandlingStrategy#retargetAttachedObjects(jakarta.faces.context.FacesContext,
* jakarta.faces.component.UIComponent, java.util.List)
*/
@SuppressWarnings({ "unchecked" })
@Override
public void retargetAttachedObjects(FacesContext context, UIComponent topLevelComponent, List<AttachedObjectHandler> handlers) {
notNull("context", context);
notNull("topLevelComponent", topLevelComponent);
notNull("handlers", handlers);
if (handlers == null || handlers.isEmpty()) {
return;
}
BeanInfo componentBeanInfo = (BeanInfo) topLevelComponent.getAttributes().get(BEANINFO_KEY);
if (componentBeanInfo == null) {
return;
}
BeanDescriptor componentDescriptor = componentBeanInfo.getBeanDescriptor();
// There is an entry in targetList for each attached object in the
// <composite:interface> section of the composite component.
List<AttachedObjectTarget> targetList = (List<AttachedObjectTarget>) componentDescriptor.getValue(ATTACHED_OBJECT_TARGETS_KEY);
// Each entry in targetList will vend one or more UIComponent instances
// that is to serve as the target of an attached object in the consuming
// page.
List<UIComponent> targetComponents;
String forAttributeValue, curTargetName;
// For each of the attached object handlers...
for (AttachedObjectHandler curHandler : handlers) {
// Get the name given to this attached object by the page author
// in the consuming page.
forAttributeValue = curHandler.getFor();
// of this composite component...
for (AttachedObjectTarget curTarget : targetList) {
// Get the name given to this attached object target by the
// composite component author
curTargetName = curTarget.getName();
targetComponents = curTarget.getTargets(topLevelComponent);
if (curHandler instanceof ActionSource2AttachedObjectHandler && curTarget instanceof ActionSource2AttachedObjectTarget) {
if (forAttributeValue.equals(curTargetName)) {
for (UIComponent curTargetComponent : targetComponents) {
retargetHandler(context, curHandler, curTargetComponent);
}
break;
}
} else if (curHandler instanceof EditableValueHolderAttachedObjectHandler && curTarget instanceof EditableValueHolderAttachedObjectTarget) {
if (forAttributeValue.equals(curTargetName)) {
for (UIComponent curTargetComponent : targetComponents) {
retargetHandler(context, curHandler, curTargetComponent);
}
break;
}
} else if (curHandler instanceof ValueHolderAttachedObjectHandler && curTarget instanceof ValueHolderAttachedObjectTarget) {
if (forAttributeValue.equals(curTargetName)) {
for (UIComponent curTargetComponent : targetComponents) {
retargetHandler(context, curHandler, curTargetComponent);
}
break;
}
} else if (curHandler instanceof BehaviorHolderAttachedObjectHandler && curTarget instanceof BehaviorHolderAttachedObjectTarget) {
BehaviorHolderAttachedObjectHandler behaviorHandler = (BehaviorHolderAttachedObjectHandler) curHandler;
BehaviorHolderAttachedObjectTarget behaviorTarget = (BehaviorHolderAttachedObjectTarget) curTarget;
String eventName = behaviorHandler.getEventName();
if (null != eventName && eventName.equals(curTargetName) || null == eventName && behaviorTarget.isDefaultEvent()) {
for (UIComponent curTargetComponent : targetComponents) {
retargetHandler(context, curHandler, curTargetComponent);
}
}
}
}
}
}
use of jakarta.faces.view.BehaviorHolderAttachedObjectTarget in project mojarra by eclipse-ee4j.
the class AjaxBehaviorListenerImpl method applyNested.
// Applies a nested AjaxHandler by adding the AjaxBehavior to the
// parent component.
private void applyNested(FaceletContext ctx, UIComponent parent, String eventName) {
if (!ComponentHandler.isNew(parent)) {
return;
}
// Composite component case
if (UIComponent.isCompositeComponent(parent)) {
// Check composite component event name:
boolean tagApplied = false;
if (parent instanceof ClientBehaviorHolder) {
// error here will propagate up
applyAttachedObject(ctx, parent, eventName);
tagApplied = true;
}
BeanInfo componentBeanInfo = (BeanInfo) parent.getAttributes().get(UIComponent.BEANINFO_KEY);
if (null == componentBeanInfo) {
throw new TagException(tag, "Error: enclosing composite component does not have BeanInfo attribute");
}
BeanDescriptor componentDescriptor = componentBeanInfo.getBeanDescriptor();
if (null == componentDescriptor) {
throw new TagException(tag, "Error: enclosing composite component BeanInfo does not have BeanDescriptor");
}
List<AttachedObjectTarget> targetList = (List<AttachedObjectTarget>) componentDescriptor.getValue(AttachedObjectTarget.ATTACHED_OBJECT_TARGETS_KEY);
if (null == targetList && !tagApplied) {
throw new TagException(tag, "Error: enclosing composite component does not support behavior events");
}
boolean supportedEvent = false;
for (AttachedObjectTarget target : targetList) {
if (target instanceof BehaviorHolderAttachedObjectTarget) {
BehaviorHolderAttachedObjectTarget behaviorTarget = (BehaviorHolderAttachedObjectTarget) target;
if (null != eventName && eventName.equals(behaviorTarget.getName()) || null == eventName && behaviorTarget.isDefaultEvent()) {
supportedEvent = true;
break;
}
}
}
if (supportedEvent) {
CompositeComponentTagHandler.getAttachedObjectHandlers(parent).add(this);
} else {
if (!tagApplied) {
throw new TagException(tag, "Error: enclosing composite component does not support event " + eventName);
}
}
} else if (parent instanceof ClientBehaviorHolder) {
applyAttachedObject(ctx, parent, eventName);
} else {
throw new TagException(tag, "Unable to attach <f:ajax> to non-ClientBehaviorHolder parent");
}
}
Aggregations