com.sun.webui.jsf.component.RbCbSelector Maven / Gradle / Ivy
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2007-2018 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://oss.oracle.com/licenses/CDDL+GPL-1.1 * or LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package com.sun.webui.jsf.component; import com.sun.faces.annotation.Property; import com.sun.webui.jsf.util.ComponentUtilities; import com.sun.webui.jsf.util.ConversionUtilities; import java.io.IOException; import javax.el.ValueExpression; import javax.faces.component.UIComponent; import javax.faces.component.NamingContainer; import javax.faces.context.FacesContext; import javax.faces.convert.ConverterException; import javax.faces.render.Renderer; /** * This renderer meta-data is not mapped one to one with a component. * A renderer of this name does exist as the super class of the * RadioButton and Checkbox renderers. */ public class RbCbSelector extends Selector implements NamingContainer { /** * Image facet name. */ public final static String IMAGE_FACET = "image"; //NOI18N // Properties to transfer from "this" to the image subcomponent // private final static String IMAGE_URL_PROP = "imageURL"; private final static String URL_PROP = "url"; private final static String ALT_PROP = "alt"; /** * Label facet name. */ public final static String LABEL_FACET = "label"; //NOI18N // Properties to transfer from "this" to the label subcomponent // private final static String LABEL_PROP = "label"; private final static String TEXT_PROP = "text"; private final static String LABEL_LEVEL_PROP = "labelLevel"; // Props for both subcomponents // private final static String TOOLTIP_PROP = "toolTip"; private final static String VISIBLE_PROP = "visible"; private final static String RENDERED_PROP = "rendered"; private final static String ID_SEPARATOR = "_"; //NOI18N // This is the default value for selectedValue. // Because of the generation and alias of "items" // (Need to reconsider this inheritance) // its not possible to set up a default value. // If selectedValue is not set, then allow this // component to behave as a boolean control. // The component is selected if both "selected" and // "selectedValue" are "true". // private final static Boolean trueSelectedValue = Boolean.TRUE; /** * Default constructor. */ public RbCbSelector() { super(); setRendererType("com.sun.webui.jsf.RbCbSelectorRenderer"); } /** *
com.sun.webui.jsf.component.ImageComponent * to represent the image for this component. */ protected UIComponent createImageComponent() { String iurl = getImageURL(); if (iurl == null) { /* Not saving the facet yet. ComponentUtilities.removePrivateFacet(this, IMAGE_FACET); */ return null; } ImageComponent image = new ImageComponent(); image.setId( ComponentUtilities.createPrivateFacetId(this, IMAGE_FACET)); image.setUrl(getImageURL()); image.setToolTip(getToolTip()); image.setAlt(getToolTip()); /* This wasn't done previously. * But need to set parent. I'm not sure the Label * for stuff will work, or even if it should for individual * rb's and cb's * ComponentUtilities.putPrivateFacet(this, LABEL_FACET, flabel); */ image.setParent(this); return image; } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Tag attribute methods // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** *Return the family for this component.
*/ @Override public String getFamily() { return "com.sun.webui.jsf.RbCbSelector"; } /** * Implemented by subclasses in order to reflect the selection * state of this component id part of a group. * This method is called if the component is part of a group. * * @param context the context for this request. * @param groupName the value of thename
property. */ protected void addToRequestMap(FacesContext context, String groupName) { } /** * Encode the component. ** If this component is part of a group, ensure that the initial * state is reflected in the request map by calling *
* @param context the context for this request. */ // Implement this here to initialize the RequestMap ArrayList // of selected grouped checkboxes, so that initially selected // check boxes are available on the first render cycle // @Override public void encodeBegin(FacesContext context) throws IOException { if (context == null) { throw new NullPointerException(); } if (!isRendered()) { return; } // If the checkbox or radio button isn't valid, or // not in a group or not // selected, don't put it in the RequestMap. // String groupName = getName(); if (groupName == null || !isValid() || !isChecked()) { return; } addToRequestMap(context, groupName); String rendererType = getRendererType(); if (rendererType != null) { getRenderer(context).encodeBegin(context, this); } } /** * Convert theaddToRequestMap
. *submittedValue
argument. ** If there is a renderer for this component, * its
*getConvertedValue()
method is called and * the value returned by that method is returned. ** If there is no renderer, and
*submittedValue
is not * an instance ofString[]
or *String
aConverterException
is thrown. ** The
* If not selected andsubmittedValue
indicates selected if it is *String[1].length() != 0
or *String.length() != 0
. *getSelectedValue()
returns an * instance ofBoolean
,Boolean.FALSE
is * returned. * ** If not selected and it's not a boolean control then an unselected * value is returned appropriate for the type of the
*selected
* property. If the type of theselected
property evaluates * to a primitive type by virtue of a value binding the appropriate *MIN_VALUE
constant is returned. For example if the * type isint
,new Integer(Integer.MIN_VALUE)
* is returned.
* If the type is not a primitive value""
is returned. ** If the control is selected *
*ConversionUtilities.convertValueToObject()
is called to * convertsubmittedValue
. ** If
* @param context the context of this request. * @param submittedValue the submitted String value of this component. */ @Override public Object getConvertedValue(FacesContext context, Object submittedValue) throws ConverterException { // First defer to the renderer. // Renderer renderer = getRenderer(context); if (renderer != null) { return renderer.getConvertedValue(context, this, submittedValue); } return getConvertedValue(context, this, submittedValue); } /** * Convert theConversionUtilities.convertValueToObject()
returns *submittedValue
, the value of the *getSelectedValue()
property * is returned, else the value returned by *ConversionUtilities.convertValueToObject()
is returned. *submittedValue
argument. ** If
*submittedValue
is not * an instance ofString[]
or *String
aConverterException
is thrown. ** The
* If not selected andsubmittedValue
indicates selected if it is *String[1].length() != 0
or *String.length() != 0
. *getSelectedValue()
returns an * instance ofBoolean
,Boolean.FALSE
is * returned. * ** If not selected and it's not a boolean control then an unselected * value is returned appropriate for the type of the
*selected
* property. If the type of theselected
property evaluates * to a primitive type by virtue of a value binding the appropriate *MIN_VALUE
constant is returned. For example if the * type isint
,new Integer(Integer.MIN_VALUE)
* is returned.
* If the type is not a primitive value""
is returned. ** If the control is selected *
*ConversionUtilities.convertValueToObject()
is called to * convertsubmittedValue
. ** If
* @param context the context of this request. * @param component an RbCbSelector instance. * @param submittedValue the submitted String value of this component. */ public Object getConvertedValue(FacesContext context, RbCbSelector component, Object submittedValue) throws ConverterException { // This would indicate minimally not selected // if (submittedValue == null) { throw new ConverterException( "The submitted value is null. " + //NOI18N "The submitted value must be a String or String array.");//NOI18N } // Expect a String or String[] // Should be made to be just String. // boolean isStringArray = submittedValue instanceof String[]; boolean isString = submittedValue instanceof String; if (!(isStringArray || isString)) { throw new ConverterException( "The submitted value must be a String or String array.");//NOI18N } String rawValue = null; if (isStringArray) { if (((String[]) submittedValue).length > 0) { rawValue = ((String[]) submittedValue)[0]; } } else if (isString) { rawValue = (String) submittedValue; } // Need to determine if the submitted value is not checked // and unchanged. If it is unchecked, rawValue == null or // rawValue == "". Compare with the rendered value. If the // rendered value is "" or null, then the component is unchanged // and if the rendered value was not null, try and convert it. // boolean unselected = rawValue == null || rawValue.length() == 0; // If the component was unselected then we need to know if it // was rendered unselected due to a value that was an empty // string or null. If it is was submitted as unselected // and rendered as unselected, we need the rendered value that // implied unselected, since it may not null, just different // than "selectedValue" // Object newValue = null; Object selectedValue = getSelectedValue(); if (unselected) { newValue = ConversionUtilities.convertRenderedValue(context, rawValue, this); // Determine the unselected value for Boolean controls // if the converted value is null but the the component // value wasn't rendered as null. // For example if the control rendered as null, and is // still unselected, then we don't want to return FALSE // for a Boolean control, since it is unchanged. // But if it has changed and is unselected then return // the unselected value of FALSE. // if (!ConversionUtilities.renderedNull(component) && selectedValue instanceof Boolean && newValue == null) { // return the complement of the selectedValue // Boolean value. // newValue = ((Boolean) selectedValue).booleanValue() ? Boolean.FALSE : Boolean.TRUE; } return getUnselectedValue(context, component, newValue); } else { newValue = ConversionUtilities.convertValueToObject(component, rawValue, context); return newValue == rawValue ? selectedValue : newValue; } } private Object getUnselectedValue(FacesContext context, UIComponent component, Object noValue) { // Determine the type of the component's value object ValueExpression valueExpr = component.getValueExpression("value"); //NOI18N // If there's no value binding we don't care // since the local value is an object and can support null or "" // if (valueExpr == null) { return noValue; } // We have found a valuebinding. Class clazz = valueExpr.getType(context.getELContext()); // Null class if (clazz == null) { return noValue; } // Pass noValue for use in primitive boolean case. // If the "selectedValue" was Boolean.FALSE, unselected // will be Boolean.TRUE. // if (clazz.isPrimitive()) { return getPrimitiveUnselectedValue(clazz, noValue); } // bail out return noValue; } private Object getPrimitiveUnselectedValue(Class clazz, Object booleanUnselectedValue) { // it MUST be at least one of these // if (clazz.equals(Boolean.TYPE)) { return booleanUnselectedValue; } else if (clazz.equals(Byte.TYPE)) { return new Integer(Byte.MIN_VALUE); } else if (clazz.equals(Double.TYPE)) { return new Double(Double.MIN_VALUE); } else if (clazz.equals(Float.TYPE)) { return new Float(Float.MIN_VALUE); } else if (clazz.equals(Integer.TYPE)) { return new Integer(Integer.MIN_VALUE); } else if (clazz.equals(Character.TYPE)) { return new Character(Character.MIN_VALUE); } else if (clazz.equals(Short.TYPE)) { return new Short(Short.MIN_VALUE); } else { // if (clazz.equals(Long.TYPE)) return new Long(Long.MIN_VALUE); } } /** * Return the value of theConversionUtilities.convertValueToObject()
returns *submittedValue
, the value of the *getSelectedValue()
property * is returned, else the value returned by *ConversionUtilities.convertValueToObject()
is returned. *selectedValue
property. * IfselectedValue
is null, then aBoolean
* true instance is returned and the control will behave as a * boolean control. */ public Object getSelectedValue() { Object sv = _getSelectedValue(); return sv == null ? trueSelectedValue : sv; } // Hack to overcome introspection of "isSelected" // /** * Returntrue
if the control is checked. * A control is checked when theselectedValue
property is * equal to theselected
property. */ public boolean isChecked() { Object selectedValue = getSelectedValue(); Object selected = getSelected(); if (selectedValue == null || selected == null) { return false; } // Need to support "selected" set to a constant String // such as "true" or "false" when it is a boolean control. // This does not include when selected is bound to a String // if (getValueExpression("selected") == null && //NOI18N selected instanceof String && selectedValue instanceof Boolean) { return selectedValue.equals(Boolean.valueOf((String) selected)); } else { return selected.equals(selectedValue); } } /** * Return a component that implements an image. * If a facet namedimage
is found * that component is returned. * If a facet is not found and *getImageURL()
returns a non null value * anImageComponent
component instance is * returned with the id *getId() + "_image"
. * TheImageComponent
instance is * intialized with the values from **
*
* *- *
getImageURL()
- *
getToolTip()
for the toolTip and alt property* If a facet is not defined then the returned
* @return - the image facet or an ImageComponent instance or null */ public UIComponent getImageComponent() { UIComponent imageComponent = getFacet(IMAGE_FACET); if (imageComponent != null) { return imageComponent; } return (createImageComponent()); } /** * Return a component that implements a label. * If a facet namedImageComponent
* component is created every time this method is called. *label
is found * that component is returned. * If a facet is not found andgetLabel()
returns a non * null value, aLabel
* component instance is returned with the id *getId() + "_label"
. * TheLabel
instance is * intialized with the values from **
*
* *- *
getLabel()
- *
getLabelLevel()
* If a facet is not defined then the returned
* @return - the label facet or a Label instance or null */ public UIComponent getLabelComponent() { UIComponent labelComponent = getFacet(LABEL_FACET); if (labelComponent != null) { return labelComponent; } return createLabelComponent(); } /** * Create aLabel
* component is created every time this method is called. *com.sun.webui.jsf.component.Label
to implement * a label for this component. * IfgetLabel()
returns null, null is returned else * aLabel
component is created each time this method * is called. */ protected UIComponent createLabelComponent() { // This diverges from previous behavior if a subsequent // request yields a null label. Previously if a private // facet was created, and getLabel() returned null // the previous facet was returned. // String label = getLabel(); if (label == null) { /* Not saving the facet yet. ComponentUtilities.removePrivateFacet(this, LABEL_FACET); */ return null; } Label flabel = new Label(); if (flabel == null) { return null; } flabel.setId( ComponentUtilities.createPrivateFacetId(this, LABEL_FACET)); flabel.setFor(getClientId(getFacesContext())); flabel.setText(label); flabel.setLabelLevel(getLabelLevel()); flabel.setToolTip(getToolTip()); /* This wasn't done previously. * But need to set parent. I'm not sure the Label * for stuff will work, or even if it should for individual * rb's and cb's * ComponentUtilities.putPrivateFacet(this, LABEL_FACET, flabel); */ flabel.setParent(this); return flabel; } /** * Create aReturn the
* * @param name Name of value binding expression to retrieve */ @Override public ValueExpression getValueExpression(String name) { if (name.equals("selected")) { return super.getValueExpression("value"); } if (name.equals("selectedValue")) { return super.getValueExpression("items"); } return super.getValueExpression(name); } /** *ValueExpression
stored for the * specified name (if any), respecting any property aliases.Set the
* * @param name Name of value binding to set * @param binding ValueExpression to set, or null to remove */ @Override public void setValueExpression(String name, ValueExpression binding) { if (name.equals("selected")) { super.setValueExpression("value", binding); return; } if (name.equals("selectedValue")) { super.setValueExpression("items", binding); return; } super.setValueExpression(name, binding); } /** *ValueExpression
stored for the * specified name (if any), respecting any property * aliases.* A context relative path of an image to be displayed with * the control. If you want to be able to specify attributes * for the image, specify an
*/ @Property(name = "imageURL", category = "Appearance", editorClassName = "com.sun.rave.propertyeditors.ImageUrlPropertyEditor") private String imageURL = null; /** *image
facet instead * of theimageURL
attribute.* A context relative path of an image to be displayed with * the control. If you want to be able to specify attributes * for the image, specify an
*/ public String getImageURL() { if (this.imageURL != null) { return this.imageURL; } ValueExpression _vb = getValueExpression("imageURL"); if (_vb != null) { return (String) _vb.getValue(getFacesContext().getELContext()); } return null; } /** *image
facet instead * of theimageURL
attribute.* A context relative path of an image to be displayed with * the control. If you want to be able to specify attributes * for the image, specify an
* @see #getImageURL() */ public void setImageURL(String imageURL) { this.imageURL = imageURL; } /** *image
facet instead * of theimageURL
attribute.Specifies the options that the web application user can choose * from. The value must be one of an array, Map or Collection * whose members are all subclasses of
*/ @Property(name = "items", displayName = "Items", category = "Data", editorClassName = "com.sun.rave.propertyeditors.binding.ValueBindingPropertyEditor") private Object items = null; /** *com.sun.webui.jsf.model.Option
.Specifies the options that the web application user can choose * from. The value must be one of an array, Map or Collection * whose members are all subclasses of
*/ @Override public Object getItems() { if (this.items != null) { return this.items; } ValueExpression _vb = getValueExpression("items"); if (_vb != null) { return (Object) _vb.getValue(getFacesContext().getELContext()); } return null; } /** *com.sun.webui.jsf.model.Option
.Specifies the options that the web application user can choose * from. The value must be one of an array, Map or Collection * whose members are all subclasses of
* @see #getItems() */ @Override public void setItems(Object items) { this.items = items; } /** *com.sun.webui.jsf.model.Option
.* Identifies the control as participating as part * of a group. The
*/ @Property(name = "name", displayName = "Group Name", category = "Advanced", editorClassName = "com.sun.rave.propertyeditors.StringPropertyEditor") private String name = null; /** *RadioButton
andCheckbox
* classes determine the behavior of the group, * that are assigned the same value to thename
* property. The value of this property must be unique for components * in the group, within the scope of theForm
* parent component containing the grouped components.* Identifies the control as participating as part * of a group. The
*/ public String getName() { if (this.name != null) { return this.name; } ValueExpression _vb = getValueExpression("name"); if (_vb != null) { return (String) _vb.getValue(getFacesContext().getELContext()); } return null; } /** *RadioButton
andCheckbox
* classes determine the behavior of the group, * that are assigned the same value to thename
* property. The value of this property must be unique for components * in the group, within the scope of theForm
* parent component containing the grouped components.* Identifies the control as participating as part * of a group. The
* @see #getName() */ public void setName(String name) { this.name = name; } /** *RadioButton
andCheckbox
* classes determine the behavior of the group, * that are assigned the same value to thename
* property. The value of this property must be unique for components * in the group, within the scope of theForm
* parent component containing the grouped components.The object that represents the selections made from the * available options. If multiple selections are allowed, this * must be bound to ArrayList, an Object array, or an array of * primitives.
*/ @Property(name = "selected", displayName = "Selected", category = "Data", editorClassName = "com.sun.webui.jsf.component.propertyeditors.RbCbSelectedPropertyEditor") @Override public Object getSelected() { return getValue(); } /** *The object that represents the selections made from the * available options. If multiple selections are allowed, this * must be bound to ArrayList, an Object array, or an array of * primitives.
* @see #getSelected() */ @Override public void setSelected(Object selected) { setValue(selected); } /** ** The value of the component when it is selected. The value of this * property is assigned to the
*/ @Property(name = "selectedValue", category = "Advanced", editorClassName = "com.sun.rave.propertyeditors.StringPropertyEditor") private Object _getSelectedValue() { return getItems(); } /** *selected
property when * the component is selected. The component is selected * when theselected
property is equal to this value. * This attribute can be bound to aString
, or* Object
value. * If this property is not assigned a value, the component behaves * as a boolean component. A boolean component * is selected when theselected
property is equal to a * trueBoolean
instance.
* If a boolean component is not selected, theselected
* property value is a falseBoolean
instance.* The value of the component when it is selected. The value of this * property is assigned to the
* @see #getSelectedValue() */ public void setSelectedValue(Object selectedValue) { setItems(selectedValue); } /** *selected
property when * the component is selected. The component is selected * when theselected
property is equal to this value. * This attribute can be bound to aString
, or* Object
value. * If this property is not assigned a value, the component behaves * as a boolean component. A boolean component * is selected when theselected
property is equal to a * trueBoolean
instance.
* If a boolean component is not selected, theselected
* property value is a falseBoolean
instance.Restore the state of this component.
*/ @Override public void restoreState(FacesContext _context, Object _state) { Object _values[] = (Object[]) _state; super.restoreState(_context, _values[0]); this.imageURL = (String) _values[1]; this.items = (Object) _values[2]; this.name = (String) _values[3]; } /** *Save the state of this component.
*/ @Override public Object saveState(FacesContext _context) { Object _values[] = new Object[4]; _values[0] = super.saveState(_context); _values[1] = this.imageURL; _values[2] = this.items; _values[3] = this.name; return _values; } }