Search in sources :

Example 1 with EditableValueHolder

use of jakarta.faces.component.EditableValueHolder in project myfaces by apache.

the class ComponentTagHandlerDelegate method apply.

/**
 * Method handles UIComponent tree creation in accordance with the JSF 1.2 spec.
 * <ol>
 * <li>First determines this UIComponent's id by calling {@link #getId(FaceletContext) getId(FaceletContext)}.</li>
 * <li>Search the parent for an existing UIComponent of the id we just grabbed</li>
 * <li>If found, {@link FaceletCompositionContext#markForDeletion(UIComponent) mark} its children for deletion.</li>
 * <li>If <i>not</i> found, call {@link #createComponent(FaceletContext) createComponent}.
 * <ol>
 * <li>Only here do we apply TagHandler#setAttributes(FaceletCompositionContext, Object)</li>
 * <li>Set the UIComponent's id</li>
 * <li>Set the RendererType of this instance</li>
 * </ol>
 * </li>
 * <li>Now apply the nextHandler, passing the UIComponent we've created/found.</li>
 * <li>Now add the UIComponent to the passed parent</li>
 * <li>Lastly, if the UIComponent already existed (found),
 * then #finalizeForDeletion(FaceletCompositionContext, UIComponent)
 * for deletion.</li>
 * </ol>
 *
 * See jakarta.faces.view.facelets.FaceletHandler#apply(jakarta.faces.view.facelets.FaceletContext,
 * jakarta.faces.component.UIComponent)
 *
 * @throws TagException
 *             if the UIComponent parent is null
 */
@SuppressWarnings("unchecked")
@Override
public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
    // make sure our parent is not null
    if (parent == null) {
        throw new TagException(_delegate.getTag(), "Parent UIComponent was null");
    }
    FacesContext facesContext = ctx.getFacesContext();
    // possible facet scoped
    String facetName = this.getFacetName(ctx, parent);
    // our id
    String id = ctx.generateUniqueId(_delegate.getTagId());
    // Cast to use UniqueIdVendor stuff
    FaceletCompositionContext mctx = (FaceletCompositionContext) FaceletCompositionContext.getCurrentInstance(ctx);
    // grab our component
    UIComponent c = null;
    // Used to preserve the original parent. Note when the view is being refreshed, the real parent could be
    // another component.
    UIComponent oldParent = parent;
    if (mctx.isRefreshingSection()) {
        if (_relocatableResourceHandler != null) {
            c = _relocatableResourceHandler.findChildByTagId(ctx, parent, id);
        } else {
            if (facetName != null) {
                c = ComponentSupport.findChildInFacetByTagId(parent, id, facetName);
            } else {
                c = ComponentSupport.findChildInChildrenByTagId(parent, id);
            }
        }
    }
    boolean componentFound = false;
    if (c != null) {
        componentFound = true;
        // preserve the same context
        if (_delegate.getBinding() != null && c.getAttributes().containsKey(FaceletDynamicComponentRefreshTransientBuildEvent.DYNAMIC_COMPONENT_BINDING_NEEDS_REFRESH)) {
            VisitContext visitContext = (VisitContext) mctx.getVisitContextFactory().getVisitContext(facesContext, null, MyFacesVisitHints.SET_SKIP_ITERATION);
            c.visitTree(visitContext, PublishFaceletDynamicComponentRefreshTransientBuildCallback.INSTANCE);
        }
        mctx.incrementUniqueComponentId();
        // mark all children for cleaning
        if (log.isLoggable(Level.FINE)) {
            log.fine(_delegate.getTag() + " Component[" + id + "] Found, marking children for cleanup");
        }
        // The call for mctx.markForDeletion(c) is always necessary, because
        // component resource relocation occur as an effect of PostAddToViewEvent,
        // so at this point it is unknown if the component was relocated or not.
        mctx.markForDeletion(c);
        if (_relocatableResourceHandler != null) {
            mctx.markRelocatableResourceForDeletion(c);
        }
    } else {
        c = this.createComponent(ctx);
        if (log.isLoggable(Level.FINE)) {
            log.fine(_delegate.getTag() + " Component[" + id + "] Created: " + c.getClass().getName());
        }
        _delegate.setAttributes(ctx, c);
        // mark it owned by a facelet instance
        c.getAttributes().put(ComponentSupport.MARK_CREATED, id);
        if (facesContext.isProjectStage(ProjectStage.Development)) {
            c.getAttributes().put(UIComponent.VIEW_LOCATION_KEY, _delegate.getTag().getLocation());
        }
        // assign our unique id
        if (this._id != null) {
            mctx.incrementUniqueComponentId();
            c.setId(this._id.getValue(ctx));
        } else {
            String componentId = mctx.generateUniqueComponentId();
            UniqueIdVendor uniqueIdVendor = mctx.getUniqueIdVendorFromStack();
            if (uniqueIdVendor == null) {
                uniqueIdVendor = facesContext.getViewRoot();
                if (uniqueIdVendor == null) {
                    // facesContext.getViewRoot() returns null here if we are in
                    // phase restore view, so we have to try to get the view root
                    // via the method in ComponentSupport and our parent
                    uniqueIdVendor = ComponentSupport.getViewRoot(ctx, parent);
                }
            }
            if (uniqueIdVendor != null) {
                // UIViewRoot implements UniqueIdVendor, so there is no need to cast to UIViewRoot
                // and call createUniqueId()
                String uid = uniqueIdVendor.createUniqueId(facesContext, componentId);
                c.setId(uid);
            }
        }
        if (this._rendererType != null) {
            c.setRendererType(this._rendererType);
        }
        // hook method
        _delegate.onComponentCreated(ctx, c, parent);
        if (_relocatableResourceHandler != null && _relocatableResourceHandler instanceof ComponentRelocatableResourceHandler) {
            UIComponent parentCompositeComponent = mctx.getCompositeComponentFromStack();
            if (parentCompositeComponent != null) {
                c.getAttributes().put(CompositeComponentELUtils.LOCATION_KEY, parentCompositeComponent.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY));
            }
        }
        if (mctx.isRefreshingTransientBuild() && _relocatableResourceHandler != null) {
            mctx.markRelocatableResourceForDeletion(c);
        }
    }
    c.pushComponentToEL(facesContext, c);
    if (c instanceof UniqueIdVendor) {
        mctx.pushUniqueIdVendorToStack((UniqueIdVendor) c);
    }
    if (mctx.isDynamicComponentTopLevel()) {
        mctx.setDynamicComponentTopLevel(false);
        _delegate.applyNextHandler(ctx, c);
        mctx.setDynamicComponentTopLevel(true);
    } else {
        // first allow c to get populated
        _delegate.applyNextHandler(ctx, c);
    }
    boolean oldProcessingEvents = facesContext.isProcessingEvents();
    // finish cleaning up orphaned children
    if (componentFound && !mctx.isDynamicComponentTopLevel()) {
        mctx.finalizeForDeletion(c);
        if (mctx.isRefreshingSection()) {
            facesContext.setProcessingEvents(false);
            if (_relocatableResourceHandler != null && parent != null && !parent.equals(c.getParent())) {
                // Replace parent with the relocated parent.
                parent = c.getParent();
                // Since we changed the parent, the facetName becomes invalid, because it points
                // to the component before relocation. We need to find the right facetName (if any) so we can
                // refresh the component properly.
                UIComponent c1 = ComponentSupport.findChildInChildrenByTagId(parent, id);
                if (c1 == null) {
                    facetName = ComponentSupport.findChildInFacetsByTagId(parent, id);
                } else {
                    facetName = null;
                }
            }
            ComponentSupport.setCachedFacesContext(c, facesContext);
        }
        if (facetName == null) {
            parent.getChildren().remove(c);
        } else {
            ComponentSupport.removeFacet(ctx, parent, c, facetName);
        }
        if (mctx.isRefreshingSection()) {
            ComponentSupport.setCachedFacesContext(c, null);
            facesContext.setProcessingEvents(oldProcessingEvents);
        }
    }
    if (!componentFound) {
        if (c instanceof ClientBehaviorHolder && !UIComponent.isCompositeComponent(c)) {
            Iterator<AjaxHandler> it = ((AbstractFaceletContext) ctx).getAjaxHandlers();
            if (it != null) {
                while (it.hasNext()) {
                    it.next().applyAttachedObject(facesContext, c);
                }
            }
        }
        if (c instanceof EditableValueHolder) {
            // add default validators here, because this feature
            // is only available in facelets (see MYFACES-2362 for details)
            addEnclosingAndDefaultValidators(ctx, mctx, facesContext, (EditableValueHolder) c);
        }
    }
    _delegate.onComponentPopulated(ctx, c, oldParent);
    if (!mctx.isDynamicComponentTopLevel() || !componentFound) {
        if (componentFound && mctx.isRefreshingSection()) {
            facesContext.setProcessingEvents(false);
            ComponentSupport.setCachedFacesContext(c, facesContext);
        }
        if (facetName == null) {
            parent.getChildren().add(c);
        } else {
            ComponentSupport.addFacet(ctx, parent, c, facetName);
        }
        if (componentFound && mctx.isRefreshingSection()) {
            ComponentSupport.setCachedFacesContext(c, null);
            facesContext.setProcessingEvents(oldProcessingEvents);
        }
    }
    if (c instanceof UniqueIdVendor) {
        mctx.popUniqueIdVendorToStack();
    }
    c.popComponentFromEL(facesContext);
    if (mctx.isMarkInitialState()) {
        // Call it only if we are using partial state saving
        c.markInitialState();
    }
}
Also used : FacesContext(jakarta.faces.context.FacesContext) FaceletCompositionContext(org.apache.myfaces.view.facelets.FaceletCompositionContext) VisitContext(jakarta.faces.component.visit.VisitContext) UIComponent(jakarta.faces.component.UIComponent) ClientBehaviorHolder(jakarta.faces.component.behavior.ClientBehaviorHolder) UniqueIdVendor(jakarta.faces.component.UniqueIdVendor) AbstractFaceletContext(org.apache.myfaces.view.facelets.AbstractFaceletContext) AjaxHandler(org.apache.myfaces.view.facelets.tag.faces.core.AjaxHandler) TagException(jakarta.faces.view.facelets.TagException) EditableValueHolder(jakarta.faces.component.EditableValueHolder)

Example 2 with EditableValueHolder

use of jakarta.faces.component.EditableValueHolder in project myfaces by apache.

the class ValidatorTagHandlerDelegate method applyAttachedObject.

@SuppressWarnings("unchecked")
@Override
public void applyAttachedObject(FacesContext context, UIComponent parent) {
    // Retrieve the current FaceletContext from FacesContext object
    FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
    // id from beeing registered on the component.
    if (_delegate.isDisabled(faceletContext)) {
        // tag is disabled --> add its validatorId to the parent's exclusion list
        String validatorId = _delegate.getValidatorConfig().getValidatorId();
        if (validatorId != null && !validatorId.isEmpty()) {
            List<String> exclusionList = (List<String>) parent.getAttributes().get(VALIDATOR_ID_EXCLUSION_LIST_KEY);
            if (exclusionList == null) {
                exclusionList = new ArrayList<String>();
                parent.getAttributes().put(VALIDATOR_ID_EXCLUSION_LIST_KEY, exclusionList);
            }
            exclusionList.add(validatorId);
        }
    } else {
        // tag is enabled --> create the validator and attach it
        // cast to a ValueHolder
        EditableValueHolder evh = (EditableValueHolder) parent;
        ValueExpression ve = null;
        Validator v = null;
        if (_delegate.getBinding() != null) {
            ve = _delegate.getBinding().getValueExpression(faceletContext, Validator.class);
            v = (Validator) ve.getValue(faceletContext);
        }
        if (v == null) {
            v = this.createValidator(faceletContext);
            if (ve != null) {
                ve.setValue(faceletContext, v);
            }
        }
        if (v == null) {
            throw new TagException(_delegate.getTag(), "No Validator was created");
        }
        _delegate.setAttributes(faceletContext, v);
        if (shouldBeanBeforeJsfValidationEnabled(context)) {
            parent.getAttributes().put(BEAN_BEFORE_JSF_PROPERTY, Boolean.TRUE);
        }
        evh.addValidator(v);
    }
}
Also used : TagException(jakarta.faces.view.facelets.TagException) ValueExpression(jakarta.el.ValueExpression) FaceletContext(jakarta.faces.view.facelets.FaceletContext) ArrayList(java.util.ArrayList) List(java.util.List) Validator(jakarta.faces.validator.Validator) EditableValueHolder(jakarta.faces.component.EditableValueHolder)

Example 3 with EditableValueHolder

use of jakarta.faces.component.EditableValueHolder in project myfaces by apache.

the class ValueChangeListenerHandler method applyAttachedObject.

@Override
public void applyAttachedObject(FacesContext context, UIComponent parent) {
    // Retrieve the current FaceletContext from FacesContext object
    FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
    EditableValueHolder evh = (EditableValueHolder) parent;
    ValueExpression b = null;
    if (this.binding != null) {
        b = this.binding.getValueExpression(faceletContext, ValueChangeListener.class);
    }
    ValueChangeListener listener = new LazyValueChangeListener(this.listenerType, b);
    evh.addValueChangeListener(listener);
}
Also used : ValueChangeListener(jakarta.faces.event.ValueChangeListener) ValueExpression(jakarta.el.ValueExpression) FaceletContext(jakarta.faces.view.facelets.FaceletContext) EditableValueHolder(jakarta.faces.component.EditableValueHolder)

Example 4 with EditableValueHolder

use of jakarta.faces.component.EditableValueHolder in project myfaces by apache.

the class FaceletViewDeclarationLanguage method applyValueChangeListenerMethodExpressionTarget.

private void applyValueChangeListenerMethodExpressionTarget(FacesContext context, FaceletCompositionContext mctx, ELContext elContext, UIComponent topLevelComponent, UIComponent innerComponent, String attributeName, String targetAttributeName, String attributeExpressionString, ValueExpression attributeNameValueExpression, boolean ccAttrMeRedirection) {
    ValueChangeListener o = (ValueChangeListener) mctx.removeMethodExpressionTargeted(innerComponent, targetAttributeName);
    if (o != null) {
        ((EditableValueHolder) innerComponent).removeValueChangeListener(o);
    }
    // target is EditableValueHolder
    ValueChangeListener valueChangeListener = null;
    // If it is a redirection, a wrapper is used to locate the right instance and call it properly.
    if (ccAttrMeRedirection) {
        valueChangeListener = new RedirectMethodExpressionValueExpressionValueChangeListener(attributeNameValueExpression);
    } else {
        MethodExpression methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().createMethodExpression(elContext, attributeExpressionString, Void.TYPE, VALUE_CHANGE_LISTENER_SIGNATURE), attributeNameValueExpression);
        MethodExpression methodExpression2 = reWrapMethodExpression(context.getApplication().getExpressionFactory().createMethodExpression(elContext, attributeExpressionString, Void.TYPE, EMPTY_CLASS_ARRAY), attributeNameValueExpression);
        if (mctx.isUsingPSSOnThisView()) {
            valueChangeListener = new PartialMethodExpressionValueChangeListener(methodExpression, methodExpression2);
        } else {
            valueChangeListener = new MethodExpressionValueChangeListener(methodExpression, methodExpression2);
        }
    }
    ((EditableValueHolder) innerComponent).addValueChangeListener(valueChangeListener);
    mctx.addMethodExpressionTargeted(innerComponent, targetAttributeName, valueChangeListener);
}
Also used : PartialMethodExpressionValueChangeListener(org.apache.myfaces.view.facelets.tag.faces.PartialMethodExpressionValueChangeListener) ValueChangeListener(jakarta.faces.event.ValueChangeListener) PartialMethodExpressionValueChangeListener(org.apache.myfaces.view.facelets.tag.faces.PartialMethodExpressionValueChangeListener) MethodExpressionValueChangeListener(jakarta.faces.event.MethodExpressionValueChangeListener) RedirectMethodExpressionValueExpressionValueChangeListener(org.apache.myfaces.view.facelets.el.RedirectMethodExpressionValueExpressionValueChangeListener) PartialMethodExpressionValueChangeListener(org.apache.myfaces.view.facelets.tag.faces.PartialMethodExpressionValueChangeListener) MethodExpressionValueChangeListener(jakarta.faces.event.MethodExpressionValueChangeListener) RedirectMethodExpressionValueExpressionValueChangeListener(org.apache.myfaces.view.facelets.el.RedirectMethodExpressionValueExpressionValueChangeListener) LocationMethodExpression(org.apache.myfaces.view.facelets.el.LocationMethodExpression) MethodExpression(jakarta.el.MethodExpression) ValueExpressionMethodExpression(org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression) MethodExpressionMethodExpression(org.apache.myfaces.view.facelets.el.MethodExpressionMethodExpression) EditableValueHolder(jakarta.faces.component.EditableValueHolder)

Example 5 with EditableValueHolder

use of jakarta.faces.component.EditableValueHolder in project myfaces by apache.

the class UIRepeat method restoreDescendantComponentStates.

/**
 * Overwrite the state of the child components of this component with data previously saved by method
 * saveDescendantComponentStates.
 * <p>
 * The saved state info only covers those fields that are expected to vary between rows of a table.
 * Other fields are not modified.
 */
@SuppressWarnings("unchecked")
private void restoreDescendantComponentStates(UIComponent parent, boolean iterateFacets, Object state, boolean restoreChildFacets) {
    int descendantStateIndex = -1;
    List<? extends Object[]> stateCollection = null;
    if (iterateFacets && parent.getFacetCount() > 0) {
        Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
        while (childIterator.hasNext()) {
            UIComponent component = childIterator.next();
            // reset the client id (see spec 3.1.6)
            component.setId(component.getId());
            if (!component.isTransient()) {
                if (descendantStateIndex == -1) {
                    stateCollection = ((List<? extends Object[]>) state);
                    descendantStateIndex = stateCollection.isEmpty() ? -1 : 0;
                }
                if (descendantStateIndex != -1 && descendantStateIndex < stateCollection.size()) {
                    Object[] object = stateCollection.get(descendantStateIndex);
                    if (object[0] != null && component instanceof EditableValueHolder) {
                        ((SavedState) object[0]).restoreState((EditableValueHolder) component);
                    }
                    // it is safe to skip iteration.
                    if (object[1] != null) {
                        restoreDescendantComponentStates(component, restoreChildFacets, object[1], true);
                    } else {
                        restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                    }
                } else {
                    restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                }
                descendantStateIndex++;
            }
        }
    }
    if (parent.getChildCount() > 0) {
        for (int i = 0; i < parent.getChildCount(); i++) {
            UIComponent component = parent.getChildren().get(i);
            // reset the client id (see spec 3.1.6)
            component.setId(component.getId());
            if (!component.isTransient()) {
                if (descendantStateIndex == -1) {
                    stateCollection = ((List<? extends Object[]>) state);
                    descendantStateIndex = stateCollection.isEmpty() ? -1 : 0;
                }
                if (descendantStateIndex != -1 && descendantStateIndex < stateCollection.size()) {
                    Object[] object = stateCollection.get(descendantStateIndex);
                    if (object[0] != null && component instanceof EditableValueHolder) {
                        ((SavedState) object[0]).restoreState((EditableValueHolder) component);
                    }
                    // it is safe to skip iteration.
                    if (object[1] != null) {
                        restoreDescendantComponentStates(component, restoreChildFacets, object[1], true);
                    } else {
                        restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                    }
                } else {
                    restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                }
                descendantStateIndex++;
            }
        }
    }
}
Also used : UIComponent(jakarta.faces.component.UIComponent) ArrayList(java.util.ArrayList) List(java.util.List) VisitHint(jakarta.faces.component.visit.VisitHint) EditableValueHolder(jakarta.faces.component.EditableValueHolder)

Aggregations

EditableValueHolder (jakarta.faces.component.EditableValueHolder)35 PrintWriter (java.io.PrintWriter)11 ValueExpression (jakarta.el.ValueExpression)6 UIComponent (jakarta.faces.component.UIComponent)5 TagException (jakarta.faces.view.facelets.TagException)5 MethodExpression (jakarta.el.MethodExpression)4 ValueHolder (jakarta.faces.component.ValueHolder)4 MethodExpressionValueChangeListener (jakarta.faces.event.MethodExpressionValueChangeListener)4 ValueChangeListener (jakarta.faces.event.ValueChangeListener)4 Validator (jakarta.faces.validator.Validator)4 FaceletContext (jakarta.faces.view.facelets.FaceletContext)4 HashMap (java.util.HashMap)4 Map (java.util.Map)4 FacesException (jakarta.faces.FacesException)3 FacesContext (jakarta.faces.context.FacesContext)3 ArrayList (java.util.ArrayList)3 Util.isNestedInIterator (com.sun.faces.util.Util.isNestedInIterator)2 ELContext (jakarta.el.ELContext)2 ActionSource2 (jakarta.faces.component.ActionSource2)2 ClientBehaviorHolder (jakarta.faces.component.behavior.ClientBehaviorHolder)2