All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.webui.jsf.component.Tree Maven / Gradle / Ivy

/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the License).  You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the license at
 * https://woodstock.dev.java.net/public/CDDLv1.0.html.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL
 * Header Notice in each file and include the License file
 * at https://woodstock.dev.java.net/public/CDDLv1.0.html.
 * If applicable, add the following below the CDDL Header,
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
 */
package com.sun.webui.jsf.component;

import com.sun.faces.annotation.Component;
import com.sun.faces.annotation.Property;
import com.sun.webui.jsf.util.CookieUtils;
import com.sun.webui.jsf.util.LogUtil;
import com.sun.webui.jsf.util.RenderingUtilities;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.application.FacesMessage;
import javax.faces.component.EditableValueHolder;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;
import javax.faces.validator.Validator;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;


/**
 * The Tree component is used to display a tree structure in the rendered HTML
 * page.
 */
@Component(type = "com.sun.webui.jsf.Tree", family = "com.sun.webui.jsf.Tree",
displayName = "Tree", tagName = "tree",
helpKey = "projrave_ui_elements_palette_wdstk-jsf1.2_tree",
propertiesHelpKey = "projrave_ui_elements_palette_wdstk-jsf1.2_propsheets_tree_props")
public class Tree extends TreeNode implements EditableValueHolder {

    private static final long serialVersionUID = -3186310519238174661L;

    /**
     *	Constructor.
     */
    public Tree() {
        super();
        setRendererType("com.sun.webui.jsf.Tree");
    }

    /**
     * 

Return the family for this component.

*/ @Override public String getFamily() { return "com.sun.webui.jsf.Tree"; } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Tag attribute methods // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * The component identifier for this component. This value must be unique * within the closest parent component that is a naming container. */ @Property(name = "id") @Override public void setId(String id) { super.setId(id); } /** * Use the rendered attribute to indicate whether the HTML code for the * component should be included in the rendered HTML page. If set to false, * the rendered HTML page does not include the HTML for the component. If * the component is not rendered, it is also not processed on any subsequent * form submission. */ @Property(name = "rendered") @Override public void setRendered(boolean rendered) { super.setRendered(rendered); } /** * The resource at the specified URL is displayed in the frame that is * specified with the target attribute. Values such as "_blank" that are * valid for the target attribute of the HTML element are also valid for * this attribute in the tree components. The target attribute is useful * only with the url attribute, and does not apply when a facet is used. */ @Property(isHidden = true, isAttribute = true) @Override public String getTarget() { return super.getTarget(); } /** * Indicates that the text that is specified with the text attribute * should be rendered as a hyperlink that resolves to the specified URL. * If the imageURL attribute is used with the url attribute, the image is * hyperlinked. The url attribute does not apply to facets. */ @Property(isHidden = true, isAttribute = true) @Override public String getUrl() { return super.getUrl(); } /** * Absolute or relative URL to the image to be rendered for the tree node. * Note that you cannot use the imageURL to display a theme image in the * tree. You should use an image facet that contains a ui:image or * ui:imageHyperlink tag to use a theme image. The imageURL attribute is * overridden by the image facet. *

When the imageURL attribute is used with the url attribute, the image * is hyperlinked.

*/ @Property(isHidden = true, isAttribute = true) @Override public String getImageURL() { return super.getImageURL(); } /** * The actionListener attribute is used to specify a method to handle an * action event that is triggered when a component is activated by the user. * The actionListener attribute value must be a JavaServer Faces EL * expression that resolves to a method in a backing bean. The method must * take a single parameter that is an ActionEvent, and its return type must * be void. The class that defines the method must implement * the java.io.Serializable interface or * javax.faces.component.StateHolder interface. *

In the TreeNode component, the method specified with the actionListener * atttribute is invoked when the node's handle icon is clicked.

*/ @Property(isHidden = true, isAttribute = true) @Override public MethodExpression getActionListenerExpression() { return super.getActionListenerExpression(); } /** * The action attribute is used to specify the action to take when this * component is activated by the user. The value of the action attribute * must be one of the following: *
    *
  • an outcome string, used to indicate which page to display next, * as defined by a navigation rule in the application configuration * resource file (faces-config.xml). *
  • *
  • a JavaServer Faces EL expression that resolves to a backing bean * method. The method must take no parameters and return an outcome string. * The class that defines the method must implement the * java.io.Serializable interface or * javax.faces.component.StateHolder interface. *
*

In the Tree and TreeNode components, the action applies only when * attributes are used to define the tree and tree nodes. When facets are * used, the action attribute does not apply to the facets.

*/ @Property(isHidden = true, isAttribute = true) @Override public MethodExpression getActionExpression() { return super.getActionExpression(); } // Hide expanded @Property(isHidden = true, isAttribute = false) @Override public boolean isExpanded() { return super.isExpanded(); } // clientSide /** *

* Set the clientSide attribute to true to specify that the Tree component * should run on the client. By default, this attribute is false, so the * Tree component interacts * with the server. In a client-side tree, expanding and collapsing of the * tree nodes happens only in the browser. In a server-side tree, a request * is made to the server each time the tree nodes are expanded or collapsed. * If you use the actionListener attribute to fire events, you must use a * server side tree so that the event can be processed. *

*/ @Property(name = "clientSide", displayName = "ClientSide", category = "Behavior") private boolean clientSide = false; private boolean clientSide_set = false; /** *

* Set the clientSide attribute to true to specify that the Tree component * should run on the client. By default, this attribute is false, so the * Tree component interacts * with the server. In a client-side tree, expanding and collapsing of the * tree nodes happens only in the browser. In a server-side tree, a request * is made to the server each time the tree nodes are expanded or collapsed. * If you use the actionListener attribute to fire events, you must use a * server side tree so that the event can be processed. *

*/ public boolean isClientSide() { if (this.clientSide_set) { return this.clientSide; } ValueExpression _vb = getValueExpression("clientSide"); if (_vb != null) { Object _result = _vb.getValue(getFacesContext().getELContext()); if (_result == null) { return false; } else { return ((Boolean) _result).booleanValue(); } } return false; } /** *

* Set the clientSide attribute to true to specify that the Tree component * should run on the client. By default, this attribute is false, so the * Tree component interacts * with the server. In a client-side tree, expanding and collapsing of the * tree nodes happens only in the browser. In a server-side tree, a request * is made to the server each time the tree nodes are expanded or collapsed. * If you use the actionListener attribute to fire events, you must use a * server side tree so that the event can be processed. *

* @see #isClientSide() */ public void setClientSide(boolean clientSide) { this.clientSide = clientSide; this.clientSide_set = true; } // expandOnSelect /** *

Flag indicating that folder / container nodes will automatically expand * when they are selected. This attribute is true by default. If you want a tree's container * nodes to expand only when the handle icons are clicked, set expandOnSelect to false.

*/ @Property(name = "expandOnSelect", displayName = "Expand On Select", category = "Behavior") private boolean expandOnSelect = false; private boolean expandOnSelect_set = false; /** *

Flag indicating that folder / container nodes will automatically expand * when they are selected. This attribute is true by default. If you want a tree's container * nodes to expand only when the handle icons are clicked, set expandOnSelect to false.

*/ public boolean isExpandOnSelect() { if (this.expandOnSelect_set) { return this.expandOnSelect; } ValueExpression _vb = getValueExpression("expandOnSelect"); if (_vb != null) { Object _result = _vb.getValue(getFacesContext().getELContext()); if (_result == null) { return false; } else { return ((Boolean) _result).booleanValue(); } } return true; } /** *

Flag indicating that folder / container nodes will automatically expand * when they are selected. This attribute is true by default. If you want a tree's container * nodes to expand only when the handle icons are clicked, set expandOnSelect to false.

* @see #isExpandOnSelect() */ public void setExpandOnSelect(boolean expandOnSelect) { this.expandOnSelect = expandOnSelect; this.expandOnSelect_set = true; } // immediate /** *

Flag indicating that event handling for this component should be * handled immediately (in Apply Request Values phase) rather than * waiting until Invoke Application phase. * May be desired for this component when required is true (although most * likely not).

*/ @Property(name = "immediate", displayName = "Immediate", category = "Advanced") private boolean immediate = false; private boolean immediate_set = false; /** *

Flag indicating that event handling for this component should be * handled immediately (in Apply Request Values phase) rather than * waiting until Invoke Application phase. * May be desired for this component when required is true (although most * likely not).

*/ public boolean isImmediate() { if (this.immediate_set) { return this.immediate; } ValueExpression _vb = getValueExpression("immediate"); if (_vb != null) { Object _result = _vb.getValue(getFacesContext().getELContext()); if (_result == null) { return false; } else { return ((Boolean) _result).booleanValue(); } } return false; } /** *

Flag indicating that event handling for this component should be * handled immediately (in Apply Request Values phase) rather than * waiting until Invoke Application phase. * May be desired for this component when required is true (although most * likely not).

* @see #isImmediate() */ public void setImmediate(boolean immediate) { this.immediate = immediate; this.immediate_set = true; } // required /** *

Flag indicating that the user must select a value for this tree. * Default value is false.

*/ @Property(name = "required", displayName = "Required", category = "Behavior") private boolean required = false; private boolean required_set = false; /** *

Flag indicating that the user must select a value for this tree. * Default value is false.

*/ public boolean isRequired() { if (this.required_set) { return this.required; } ValueExpression _vb = getValueExpression("required"); if (_vb != null) { Object _result = _vb.getValue(getFacesContext().getELContext()); if (_result == null) { return false; } else { return ((Boolean) _result).booleanValue(); } } return false; } /** *

Flag indicating that the user must select a value for this tree. * Default value is false.

* @see #isRequired() */ public void setRequired(boolean required) { this.required = required; this.required_set = true; } // style /** *

CSS style(s) to be applied to the outermost HTML element when this * component is rendered.

*/ @Property(name = "style", displayName = "CSS Style(s)", category = "Appearance", editorClassName = "com.sun.jsfcl.std.css.CssStylePropertyEditor") private String style = null; /** *

CSS style(s) to be applied to the outermost HTML element when this * component is rendered.

*/ @Override public String getStyle() { if (this.style != null) { return this.style; } ValueExpression _vb = getValueExpression("style"); if (_vb != null) { return (String) _vb.getValue(getFacesContext().getELContext()); } return null; } /** *

CSS style(s) to be applied to the outermost HTML element when this * component is rendered.

* @see #getStyle() */ @Override public void setStyle(String style) { this.style = style; } // styleClass /** *

CSS style class(es) to be applied to the outermost HTML element when this * component is rendered.

*/ @Property(name = "styleClass", displayName = "CSS Style Class(es)", category = "Appearance", editorClassName = "com.sun.rave.propertyeditors.StyleClassPropertyEditor") private String styleClass = null; /** *

CSS style class(es) to be applied to the outermost HTML element when this * component is rendered.

*/ @Override public String getStyleClass() { if (this.styleClass != null) { return this.styleClass; } ValueExpression _vb = getValueExpression("styleClass"); if (_vb != null) { return (String) _vb.getValue(getFacesContext().getELContext()); } return null; } /** *

CSS style class(es) to be applied to the outermost HTML element when this * component is rendered.

* @see #getStyleClass() */ @Override public void setStyleClass(String styleClass) { this.styleClass = styleClass; } // visible /** *

Use the visible attribute to indicate whether the component should be * viewable by the user in the rendered HTML page. If set to false, the * HTML code for the component is present in the page, but the component * is hidden with style attributes. By default, visible is set to true, so * HTML for the component HTML is included and visible to the user. If the * component is not visible, it can still be processed on subsequent form * submissions because the HTML is present.

*/ @Property(name = "visible", displayName = "Visible", category = "Behavior") private boolean visible = false; private boolean visible_set = false; /** *

Use the visible attribute to indicate whether the component should be * viewable by the user in the rendered HTML page. If set to false, the * HTML code for the component is present in the page, but the component * is hidden with style attributes. By default, visible is set to true, so * HTML for the component HTML is included and visible to the user. If the * component is not visible, it can still be processed on subsequent form * submissions because the HTML is present.

*/ @Override public boolean isVisible() { if (this.visible_set) { return this.visible; } ValueExpression _vb = getValueExpression("visible"); if (_vb != null) { Object _result = _vb.getValue(getFacesContext().getELContext()); if (_result == null) { return false; } else { return ((Boolean) _result).booleanValue(); } } return true; } /** *

Use the visible attribute to indicate whether the component should be * viewable by the user in the rendered HTML page. If set to false, the * HTML code for the component is present in the page, but the component * is hidden with style attributes. By default, visible is set to true, so * HTML for the component HTML is included and visible to the user. If the * component is not visible, it can still be processed on subsequent form * submissions because the HTML is present.

* @see #isVisible() */ @Override public void setVisible(boolean visible) { this.visible = visible; this.visible_set = true; } /** * This component renders its children */ @Override public boolean getRendersChildren() { return true; } /** *

Returns the id of the selected tree node. Should be cast to a String and * nothing else.

*/ @Property(name = "selected", displayName = "Selected", category = "Data", editorClassName = "com.sun.webui.jsf.component.propertyeditors.TreeNodeIdsEditor") public String getSelected() { return (String) getValue(); } /** *

Specify the id of the selected tree node. Should specify a String object. * Also note that this should NOT be the client ID of the selected node.

* @see #getSelected() */ public void setSelected(String selected) { if (selected == null || selected.length() == 0) { FacesContext context = FacesContext.getCurrentInstance(); Cookie cookie = CookieUtils.getCookieValue(context, getClientId(context) + COOKIE_SUFFIX); if (cookie != null) { if (!RenderingUtilities.isPortlet(context)) { ExternalContext extCtx = context.getExternalContext(); HttpServletResponse res = (HttpServletResponse) extCtx.getResponse(); cookie.setMaxAge(0); cookie.setPath("/"); res.addCookie(cookie); setValue(null); } } } setValue(selected); } /** *

Return the ValueExpression stored for the * specified name (if any), respecting any property aliases.

* * @param name Name of value binding to retrieve */ @Override public ValueExpression getValueExpression(String name) { if (name.equals("selected")) { return super.getValueExpression("value"); } return super.getValueExpression(name); } /** *

Set the ValueExpression stored for the * specified name (if any), respecting any property * aliases.

* * @param name Name of value binding to set * @param binding ValueBinding to set, or null to remove */ @Override public void setValueExpression(String name, ValueExpression binding) { if (name.equals("selected")) { super.setValueExpression("value", binding); return; } super.setValueExpression(name, binding); } ////////////////////////////////////////////////////////////////////// // ValueHolder Methods ////////////////////////////////////////////////////////////////////// /** *

Return the Converter (if any) that is registered for * this UIComponent.

* *

Not implemented for this component.

*/ public Converter getConverter() { return converter; } /** *

Set the Converter (if any) that is registered for * this UIComponent.

* *

Not implemented for this component.

* * @param conv New Converter (or null) */ public void setConverter(Converter conv) { converter = conv; // Do nothing... throw exception? } /** *

Return the local value of this UIComponent (if any), * without evaluating any associated ValueBinding.

*/ public Object getLocalValue() { return value; } /** *

Gets the value of this UIComponent. First, consult the * local value property of this component. If non-null * return it. If non-null, see if we have a ValueBinding * for the value property. If so, return the result of * evaluating the property, otherwise return null.

*/ public Object getValue() { if (value != null) { return value; } ValueExpression _vb = getValueExpression("value"); if (_vb != null) { Object _result = _vb.getValue(getFacesContext().getELContext()); return _result; } return null; } /** *

Set the value of this UIComponent (if any).

* * @param val The new local value */ public void setValue(Object val) { value = val; // Mark the local value as set. setLocalValueSet(true); } ////////////////////////////////////////////////////////////////////// // EditableValueHolder Methods ////////////////////////////////////////////////////////////////////// /** *

Return the submittedValue value of this component. This method * should only be used by the encodeBegin() and/or * encodeEnd() methods of this component, or its * corresponding Renderer.

*/ public Object getSubmittedValue() { return submittedValue; } /** *

Set the submittedValue value of this component. This method should * only be used by the decode() and * validate() method of this component, or its * corresponding Renderer.

* * @param value The new submitted value. */ public void setSubmittedValue(Object value) { submittedValue = value; } /** *

Return the "local value set" state for this component. Calls to * setValue() automatically reset this property to * true. */ public boolean isLocalValueSet() { return localValueSet; } /** *

Sets the "local value set" state for this component.

*/ public void setLocalValueSet(boolean value) { localValueSet = value; } /** *

Return a flag indicating whether the local value of this component * is valid (no conversion error has occurred).

*/ public boolean isValid() { return valid; } /** *

Set a flag indicating whether the local value of this component * is valid (no conversion error has occurred).

* * @param value The new valid flag. */ public void setValid(boolean value) { valid = value; } /** *

Return a MethodBinding pointing at a method that will * be used to validate the current value of this component. This * method will be called during the Process Validations or * Apply Request Values phases (depending on the value of * the immediate property).

* *

Not implemented for this component.

*/ public MethodBinding getValidator() { return validatorBinding; } /** *

Set a MethodBinding pointing at a method that will be * used to validate the current value of this component. This method * will be called during the Process Validations or * Apply Request Values phases (depending on the value of * the immediate property).

* *

Any method referenced by such an expression must be public, with a * return type of void, and accept parameters of type * FacesContext, UIComponent, and * Object.

* *

Not implemented for this component.

* * @param valBinding The new MethodBinding instance. */ public void setValidator(MethodBinding valBinding) { validatorBinding = valBinding; } /** *

Add a Validator instance to the set associated with * this component.

* *

Not implemented for this component.

* * @param validator The Validator to add. */ public void addValidator(Validator validator) { if (validator == null) { throw new NullPointerException(); } if (validators == null) { validators = new ArrayList(); } validators.add(validator); } /** *

Return the set of registered Validators for this * component instance. If there are no registered validators, a * zero-length array is returned.

* *

Not implemented for this component.

*/ public Validator[] getValidators() { if (validators == null) { return (new Validator[0]); } return ((Validator[]) validators.toArray( new Validator[validators.size()])); } /** *

Remove a Validator instance from the set associated * with this component, if it was previously associated. Otherwise, * do nothing.

* *

Not implemented for this component.

* * @param validator The Validator to remove. */ public void removeValidator(Validator validator) { if (validators != null) { validators.remove(validator); } } /** *

Return a MethodBinding instance method that will be * called after any registered ValueChangeListeners have * been notified of a value change. This method will be called during * the Process Validations or Apply Request Values * phases (depending on the value of the immediate * property).

*/ public MethodBinding getValueChangeListener() { return valueChangeMethod; } /** *

Set a MethodBinding instance method that will be * called after any registered ValueChangeListeners have * been notified of a value change. This method will be called * during the Process Validations or Apply Request * Values phases (depending on the value of the * immediate property).

* * @param method The new MethodBinding instance. */ public void setValueChangeListener(MethodBinding method) { valueChangeMethod = method; } /** *

Add a new ValueChangeListener to the set of listeners * interested in being notified when ValueChangeEvents * occur.

* * @param listener The ValueChangeListener to be added. */ public void addValueChangeListener(ValueChangeListener listener) { addFacesListener(listener); } /** *

Return the set of registered ValueChangeListeners for * this component instance. If there are no registered listeners, a * zero-length array is returned.

*/ public ValueChangeListener[] getValueChangeListeners() { return (ValueChangeListener[]) getFacesListeners(ValueChangeListener.class); } /** *

Remove an existing ValueChangeListener (if any) from * the set of listeners interested in being notified when * ValueChangeEvents occur.

* * @param listener The ValueChangeListener to be removed. */ public void removeValueChangeListener(ValueChangeListener listener) { removeFacesListener(listener); } ////////////////////////////////////////////////////////////////////// // Other Methods ////////////////////////////////////////////////////////////////////// /** *

Decode any new state of this UIComponent from the * request contained in the specified FacesContext, and * store this state as needed.

* *

During decoding, events may be enqueued for later processing (by * event listeners who have registered an interest), by calling * queueEvent().

* * @param context {@link FacesContext} for the request we are processing. */ @Override public void decode(FacesContext context) { setValid(true); super.decode(context); } /** *

In addition to to the default UIComponent#broadcast * processing, pass the ValueChangeEvent being broadcast * to the method referenced by valueChangeListener.

* * @param event FacesEvent to be broadcast * * @exception AbortProcessingException Signal the JSF implementation * that no further processing on the current event should be performed */ @Override public void broadcast(FacesEvent event) throws AbortProcessingException { // Perform standard superclass processing super.broadcast(event); if (event instanceof ValueChangeEvent) { MethodBinding method = getValueChangeListener(); if (method != null) { FacesContext context = getFacesContext(); method.invoke(context, new Object[]{event}); } } } /** *

Perform the component tree processing required by the Update * Model Values phase of the request processing lifecycle for * all facets of this component, all children of this component, * and this component itself, as follows.

* *
  • If the rendered property of this * UIComponent is false, skip * further processing.
  • *
  • Call the processUpdates() method of all * facets and children of this UIComponent, in the * order determined by a call to * getFacetsAndChildren().
* * @param context FacesContext for this request */ @Override public void processUpdates(FacesContext context) { // Skip processing if our rendered flag is false if (!isRendered()) { return; } // Do the super stuff... super.processUpdates(context); // Save model stuff... try { updateModel(context); } catch (RuntimeException ex) { context.renderResponse(); throw new RuntimeException(ex); } } /** *

Perform the following algorithm to update the model data * associated with this component, if any, as appropriate.

* *
  • If the valid property of this component is * false, take no further action.
  • *
  • If the localValueSet property of this * component is false, take no further action.
  • *
  • If no ValueBinding for value * exists, take no further action.
  • *
  • Call setValue() method of the * ValueBinding to update the value that the * ValueBinding points at.
  • *
  • If the setValue() method returns successfully: *
    • Clear the local value of this component.
    • *
    • Set the localValueSet property of * this component to false.
  • *
  • If the setValue() method call fails: *
    • Queue an error message by calling * addMessage() on the specified * FacesContext instance.
    • *
    • Set the valid property of this * component to false.
  • *
* * @param context FacesContext for the request we are * processing. */ public void updateModel(FacesContext context) { // Sanity Checks... if (context == null) { throw new NullPointerException(); } if (!isValid() || !isLocalValueSet()) { return; } ValueBinding vb = getValueBinding("value"); if (vb == null) { return; } try { vb.setValue(context, getLocalValue()); setValue(null); setLocalValueSet(false); return; } catch (Exception ex) { String messageStr = ex.getMessage(); if (messageStr != null) { FacesMessage message = null; message = new FacesMessage(messageStr); message.setSeverity(FacesMessage.SEVERITY_ERROR); context.addMessage(getClientId(context), message); } setValid(false); if (LogUtil.configEnabled()) { LogUtil.config("Unable to update Model!", ex); // NOI18N } } } /** *

Perform the component tree processing required by the Apply * Request Values phase of the request processing lifecycle for * all facets of this component, all children of this component, and * this component itself, as follows.

* *
  • If the rendered property of this * UIComponent is false, skip * further processing.
  • *
  • Call the processDecodes() method of all * facets and children of this UIComponent, in the * order determined by a call to * getFacetsAndChildren().
  • *
  • Call the decode() method of this * component.
  • *
  • If a RuntimeException is thrown during decode * processing, call FacesContext.renderResponse * and re-throw the exception.
* * @param context FacesContext for the request. */ @Override public void processDecodes(FacesContext context) { // Skip processing if our rendered flag is false if (!isRendered()) { return; } super.processDecodes(context); if (isImmediate()) { executeValidate(context); } } /** *

In addition to the standard processValidators behavior * inherited from UIComponentBases, calls * validate() if the immediate property is * false (which is the default); if the component is invalid * afterwards, calls FacesContext.renderResponse. If a * RuntimeException is thrown during validation * processing, calls FacesContext.renderResponse and * re-throws the exception.

*/ @Override public void processValidators(FacesContext context) { if (context == null) { throw new NullPointerException(); } // Skip processing if our rendered flag is false if (!isRendered()) { return; } super.processValidators(context); if (!isImmediate()) { executeValidate(context); } } /** * Executes validation logic. */ private void executeValidate(FacesContext context) { try { validate(context); } catch (RuntimeException e) { context.renderResponse(); throw e; } if (!isValid()) { context.renderResponse(); } } /** *

Perform the following algorithm to validate the local value of * this UIInput.

* *
  • Retrieve the submitted value with * getSubmittedValue(). If this returns null, * exit without further processing. (This indicates that no * value was submitted for this component.)
  • * *
  • Convert the submitted value into a "local value" of the * appropriate data type by calling * getConvertedValue.
  • * *
  • Validate the property by calling * validateValue.
  • * *
  • If the valid property of this component is * still true, retrieve the previous value of * the component (with getValue()), store the new * local value using setValue(), and reset the * submitted value to null. If the local value is different * from the previous value of this component, fire a * ValueChangeEvent to be broadcast to all * interested listeners.
* * @param context FacesContext for the current request. */ public void validate(FacesContext context) { if (context == null) { throw new NullPointerException(); } // Submitted value == null means "the component was not submitted // at all"; validation should not continue Object submittedValue = getSubmittedValue(); if (submittedValue == null) { return; } Object newValue = submittedValue; /* FIXME: Decide if we ever want to the Tree to support Converters try { newValue = getConvertedValue(context, submittedValue); } catch (ConverterException ce) { addConversionErrorMessage(context, ce, submittedValue); setValid(false); } */ // Validate the value (check for required for now) validateValue(context, newValue); // If our value is valid, store the new value, erase the // "submitted" value, and emit a ValueChangeEvent if appropriate if (isValid()) { Object previous = getValue(); setValue(newValue); setSubmittedValue(null); if (isDifferent(previous, newValue)) { queueEvent(new ValueChangeEvent(this, previous, newValue)); } } } /** *

Return true if the objects are not equal.

* * @param val1 Value 1 * @param val1 Value 2 * * @return true if the 2 values are not equal */ protected boolean isDifferent(Object val1, Object val2) { if (val1 == val2) { // Same object, they're equal return false; } if (val1 == null) { // Not equal, and one is null return true; } return !val1.equals(val2); } protected void validateValue(FacesContext context, Object newValue) { if (!isValid()) { return; } if (isRequired() && ((newValue == null) || (newValue.toString().trim().equals("")))) { // FIXME: Add a message // FacesMessage message = // message.setSeverity(FacesMessage.SEVERITY_ERROR); // context.addMessage(getClientId(context), message); setValid(false); } // FIXME: Decide if we ever want to the Tree to support Validators (See UIInput) } /** *

This method accepts the {@link TreeNode} which is to be selected. * The previous {@link TreeNode} that was selected will unselected. * No state is saved with this operation, the state is maintained on * the client.

* * @deprecated Use #setValue(Object) * * @param treeNode The {@link TreeNode} to be selected. */ public void selectTreeNode(TreeNode treeNode) { setSelected(treeNode.getId()); // selectTreeNode(treeNode.getClientId(FacesContext.getCurrentInstance())); } /** *

This method accepts the clientId of a {@link TreeNode} which is to * be selected. The previous {@link TreeNode} that was selected will * unselected. No state is saved with this operation, the state is * maintained on the client-side.

* * @deprecated Use #setValue(Object) * * @param id The id of the {@link TreeNode} to be selected. */ public void selectTreeNode(String id) { setSelected(id); } /** *

This method returns the {@link TreeNode} client ID that is * selected according the browser cookie. This method is generally * only useful during the decode process.

* * @return The selected tree node (according to the cookie). */ public String getCookieSelectedTreeNode() { FacesContext context = FacesContext.getCurrentInstance(); // If look at cookies... Cookie cookie = CookieUtils.getCookieValue(context, getClientId(context) + COOKIE_SUFFIX); if (cookie != null) { return cookie.getValue(); } // Not found, return null return null; } /** *

This method will return the {@link TreeNode} client ID that is * selected according the browser cookie. This method is only * useful during the decode process as the cookie will typically be * reset to null immediately after the request is processed.

* * @return The selected tree node (according to the cookie). */ public String getCookieExpandNode() { FacesContext context = FacesContext.getCurrentInstance(); Cookie cookie = CookieUtils.getCookieValue(context, getClientId(context) + COOKIE_SUFFIX_EXPAND); if (cookie != null) { return cookie.getValue(); } // Not found, return null return null; } ////////////////////////////////////////////////////////////////////// // ValueHolder Methods ////////////////////////////////////////////////////////////////////// /** * */ @Override public Object saveState(FacesContext context) { Object _values[] = new Object[20]; _values[0] = super.saveState(context); _values[1] = this.clientSide ? Boolean.TRUE : Boolean.FALSE; _values[2] = this.clientSide_set ? Boolean.TRUE : Boolean.FALSE; _values[3] = this.expandOnSelect ? Boolean.TRUE : Boolean.FALSE; _values[4] = this.expandOnSelect_set ? Boolean.TRUE : Boolean.FALSE; _values[5] = this.immediate ? Boolean.TRUE : Boolean.FALSE; _values[6] = this.immediate_set ? Boolean.TRUE : Boolean.FALSE; _values[7] = this.required ? Boolean.TRUE : Boolean.FALSE; _values[8] = this.required_set ? Boolean.TRUE : Boolean.FALSE; _values[9] = this.style; _values[10] = this.styleClass; _values[11] = this.visible ? Boolean.TRUE : Boolean.FALSE; _values[12] = this.visible_set ? Boolean.TRUE : Boolean.FALSE; _values[13] = saveAttachedState(context, converter); _values[14] = this.value; _values[15] = localValueSet ? Boolean.TRUE : Boolean.FALSE; _values[16] = this.valid ? Boolean.TRUE : Boolean.FALSE; _values[17] = saveAttachedState(context, validators); _values[18] = saveAttachedState(context, validatorBinding); _values[19] = saveAttachedState(context, valueChangeMethod); return (_values); } /** *

Restore the state of this component.

*/ @Override public void restoreState(FacesContext _context, Object _state) { Object _values[] = (Object[]) _state; super.restoreState(_context, _values[0]); this.clientSide = ((Boolean) _values[1]).booleanValue(); this.clientSide_set = ((Boolean) _values[2]).booleanValue(); this.expandOnSelect = ((Boolean) _values[3]).booleanValue(); this.expandOnSelect_set = ((Boolean) _values[4]).booleanValue(); this.immediate = ((Boolean) _values[5]).booleanValue(); this.immediate_set = ((Boolean) _values[6]).booleanValue(); this.required = ((Boolean) _values[7]).booleanValue(); this.required_set = ((Boolean) _values[8]).booleanValue(); this.style = (String) _values[9]; this.styleClass = (String) _values[10]; this.visible = ((Boolean) _values[11]).booleanValue(); this.visible_set = ((Boolean) _values[12]).booleanValue(); converter = (Converter) restoreAttachedState(_context, _values[13]); this.value = _values[14]; localValueSet = ((Boolean) _values[15]).booleanValue(); valid = ((Boolean) _values[16]).booleanValue(); List restoredValidators = null; Iterator iter = null; if (null != (restoredValidators = (List) restoreAttachedState(_context, _values[17]))) { // if there were some validators registered prior to this // method being invoked, merge them with the list to be // restored. if (null != validators) { iter = restoredValidators.iterator(); while (iter.hasNext()) { validators.add(iter.next()); } } else { validators = restoredValidators; } } validatorBinding = (MethodBinding) restoreAttachedState(_context, _values[18]); valueChangeMethod = (MethodBinding) restoreAttachedState(_context, _values[19]); } /** *

Converter.

*/ private Converter converter = null; /** *

The set of {@link Validator}s associated with this * UIComponent.

*/ private List validators = null; /** * */ private MethodBinding validatorBinding = null; /** *

The submittedValue value of this component.

*/ private Object submittedValue = null; /** *

Toggle indicating validity of this component.

*/ private boolean valid = true; /** *

The "localValueSet" state for this component.

*/ private boolean localValueSet; /** *

The "valueChange" MethodBinding for this component. */ private MethodBinding valueChangeMethod = null; /** *

The value of the Tree. This should be a String * representing the client id of the selected * TreeNode.

*/ private Object value = null; /** *

This is the {@link com.sun.webui.theme.Theme} key used to retrieve * the JavaScript needed for this component.

* * @see com.sun.webui.theme.Theme#getPathToJSFile(String) */ public static final String JAVA_SCRIPT_THEME_KEY = "tree"; /** *

This is the suffix appended to the client id when forming a request * attribute key. The value associated with the generated key * indicates which node should be selected. The renderer uses this * information to generate JavaScript to select this node, overriding * the previous selection.

*/ public static final String SELECTED_SUFFIX = "_select"; /** *

This is the suffix appended to the client id to form the key to the * cookie Map needed to retrieve the tree selection.

*/ public static final String COOKIE_SUFFIX = "-hi"; /** *

This is the suffix appended to the client id to form the key to the * cookie Map needed to retrieve the node that may need to be * expanded (because it was just selected).

*/ public static final String COOKIE_SUFFIX_EXPAND = "-expand"; /** *

String constant representing the content facet name.

*/ public static final String TREE_CONTENT_FACET_NAME = "content"; /** *

String constant representing the image facet name.

*/ public static final String TREE_IMAGE_FACET_NAME = "image"; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy