com.sun.webui.jsf.component.Property 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.webui.jsf.util.ComponentUtilities;
import java.beans.Beans;
import java.util.Iterator;
import javax.el.ValueExpression;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
/**
* The Property
component was
* written to be used within thePropertySheetSection
component,
* which is in turn used within the context of a PropertySheet
* component. TheProperty
component allows you to encapsulate a logic
* "property" and help you lay it out on the page. A "property" has a number
* of configuration options, including: the property content; an optional
* label; the ability to stretch the property to include the label area (in
* addition to the content area of the "property"; the ability to mark a
* property required; and the ability to associate help text with the property
* to inform your end user how to interact with the property. Help text
* can be provided for each property by supplying thehelpText
* attribute. This attribute may be a literal String or a
* ValueBinding
expression. The help text will appear
* below the content of the "property". Optionally, the helpText may also
* be provided as a facet named "helpText". This allows advanced users to
* have more control over the types of content provided in the helpText
* area.
The label may be provided via the label
attribute.
* The label will be rendered to the left of the content area of the "property".
* The label area will not exist if the overlapLabel
attribute is
* set to true. Optionally advanced users may provide a label facet named
* "label". This allows developers to have more control over the content of
* the label area.
The labelAlign
attribute can use used to
* specify "left" or "right" alignment of the label table cell.
Setting
* the noWrap
attribute to true specifies that the label should not
* be wraped to a new line.
The overlapLabel
attribute
* causes the content of the property to be stretched into the label area as
* well as the content area. This may be useful for titles which should span
* the entire width, or other cases where you need the whole width of the
* PropertySheet
.
The requiredIndicator
* attribute is only valid when you supply a label via an attribute (not as a
* facet). When this attribute is marked true
, the label that is
* created will have its required attribute marked true.
For an example,
* please see the documentation for the propertySheet
Tag.
*/
@Component(type = "com.sun.webui.jsf.Property", family = "com.sun.webui.jsf.Property",
displayName = "Property", tagName = "property",
helpKey = "projrave_ui_elements_palette_wdstk-jsf1.2_property",
propertiesHelpKey = "projrave_ui_elements_palette_wdstk-jsf1.2_propsheets_property_props")
public class Property extends UIComponentBase implements ComplexComponent,
NamingContainer {
public static final String CONTENT_FACET = "content"; //NOI18N
public static final String HELPTEXT_FACET = "helpText"; //NOI18N
public static final String LABEL_FACET = "label"; //NOI18N
/**
* Constructor.
*/
public Property() {
super();
setRendererType("com.sun.webui.jsf.Property");
}
/**
* Return the family for this component.
*/
public String getFamily() {
return "com.sun.webui.jsf.Property";
}
/**
* Returns the absolute ID of an HTML element suitable for use as
* the value of an HTML LABEL element's for
attribute.
* If the ComplexComponent
has sub-compoents, and one of
* the sub-components is the target of a label, if that sub-component
* is a ComplexComponent
, then
* getLabeledElementId
must called on the sub-component and
* the value returned. The value returned by this
* method call may or may not resolve to a component instance.
*
* @param context The FacesContext used for the request
* @return An abolute id suitable for the value of an HTML LABEL element's
* for
attribute.
*/
public String getLabeledElementId(FacesContext context) {
// Check for "content" facet first
UIComponent contentFacet = getContentComponent();
// The field component is the one that is labelled
UIComponent labeledComponent = null;
if (contentFacet == null) {
// If there is no facet, assume that the content is specified
// as a child of this component. Search for a
// required ComplexComponent among the children
labeledComponent = findLabeledComponent(this, true);
} else {
// If a facet has been specified, see if the facet is a required
// ComplexComponent or search for a required ComplexComponent
// among the children of the facet component
labeledComponent = findLabeledComponent(contentFacet, false);
}
if (labeledComponent != null) {
// NOTE: Don't use ComplexComponent here, the Label component will.
if (Beans.isDesignTime()) {
//6474235: recalculate clientId
UIComponent resetIdComp = labeledComponent;
while (resetIdComp != null) {
resetIdComp.setId(resetIdComp.getId());
resetIdComp = resetIdComp.getParent();
}
}
if (labeledComponent instanceof ComplexComponent) {
return ((ComplexComponent) labeledComponent).getLabeledElementId(context);
} else {
return labeledComponent.getClientId(context);
}
}
return null;
}
/**
* Returns the id of an HTML element suitable to
* receive the focus.
* If the ComplexComponent
has sub-compoents, and one of
* the sub-components is to reveive the focus, if that sub-component
* is a ComplexComponent
, then
* getFocusElementId
must called on the sub-component and
* the value returned. The value returned by this
* method call may or may not resolve to a component instance.
*
* @param context The FacesContext used for the request
*/
public String getFocusElementId(FacesContext context) {
// Just return the same id as the labeled component for now.
//
return getLabeledElementId(context);
}
/**
* This method calculates the proper UIComponent
that
* should be used when the label property is used with this
* component.
*
* This method provides the implementation for
* {@link com.sun.webui.jsf.component.ComplexComponent}
*
* @param context The FacesContext
.
*
* @return The id
of the label target.
*
* @deprecated
* @see #getLabeledElementId
* @see #getFocusElementId
*/
public String getPrimaryElementID(FacesContext context) {
// Check for "content" facet first
UIComponent contentFacet = getContentComponent();
// The field component is the one that is labelled
UIComponent labeledComponent = null;
if (contentFacet == null) {
// If there is no facet, assume that the content is specified
// as a child of this component. Search for a
// required EditableValueHolderamong the children
//
labeledComponent = findLabeledComponent(this, true);
} else {
// If a facet has been specified, see if the facet is a required
// EditableValueHolder or search for a required EditableValueHolder
// among the children of the facet component
labeledComponent = findLabeledComponent(contentFacet, false);
}
if (labeledComponent != null) {
// Return an absolute path (relative is harder to calculate)
// NOTE: Label component does not fully support relative anyway,
// NOTE: the ":" I'm adding isn't necessary... however, it doesn't
// NOTE: hurt and if Label ever does support relative paths, the
// NOTE: ":" prefix is needed to specify a full path.
// NOTE:
// NOTE: Don't use ComplexComponent here, the Label component will.
if (Beans.isDesignTime()) {
//6474235: recalculate clientId
UIComponent resetIdComp = labeledComponent;
while (resetIdComp != null) {
resetIdComp.setId(resetIdComp.getId());
resetIdComp = resetIdComp.getParent();
}
}
return ":" + labeledComponent.getClientId(context); // NOI18N
}
return null;
}
/**
* This method checks the component, children, and facets to see if
* any of them are EditableValueHolder
s. The first one
* found is returned, null
* otherwise.
*
* @param comp The UIComponent
to check.
* @param skip Flag indicating the initial component should be ignored
*
* @return The first EditableValueHolder
, null if not found.
*/
private static UIComponent findLabeledComponent(UIComponent comp,
boolean skip) {
if (!skip) {
// Check to see if comp is an EditableValueHolder
if (comp instanceof EditableValueHolder) {
return comp;
}
}
// Next check children and facets
Iterator it = comp.getFacetsAndChildren();
while (it.hasNext()) {
comp = findLabeledComponent((UIComponent) it.next(), false);
if (comp != null) {
return comp;
}
}
// Not found
return null;
}
/**
* Return the a component that represents the content of the property.
* If a facet called content
does not exist null
* is returned.
*/
public UIComponent getContentComponent() {
return getFacet(CONTENT_FACET);
}
/**
* Return a component that implements help text.
* If a facet named helpText
is found
* that component is returned. Otherwise a HelpInline
* component is returned. It is assigned the id
* getId() + "_helpText"
*
* If the facet is not defined then the returned HelpInline
* component is re-intialized every time this method is called.
*
*
* If getHelpeText
returns null, null is returned.
*
*
* @return a help text facet component
*/
public UIComponent getHelpTextComponent() {
UIComponent component = getFacet(HELPTEXT_FACET);
if (component != null) {
return component;
}
String helpText = getHelpText();
if (helpText == null) {
return null;
}
// Create one every time.
//
component = (UIComponent) new HelpInline();
if (component == null) {
// log severe problem
return null;
}
// Assume helpText is literal
//
((HelpInline) component).setText(helpText);
component.setId(
ComponentUtilities.createPrivateFacetId(this, HELPTEXT_FACET));
component.setParent(this);
((HelpInline) component).setType("field"); //NOI18N
return component;
}
/**
* Return a component that implements a label.
* If a facet named label
is found
* that component is returned. Otherwise a Label
component
* is returned. It is assigned the id
* getId() + "_label"
*
* If the facet is not defined then the returned Label
* component is re-intialized every time this method is called.
*
*
* @return a label facet component
*/
public UIComponent getLabelComponent() {
UIComponent component = getFacet(LABEL_FACET);
if (component != null) {
return component;
}
// If label is null, don't return any component.
// This may need to be revisited but is the common
// behavior of other components, rightly or wrongly
//
String label = getLabel();
if (label == null) {
return null;
}
component = ComponentUtilities.getPrivateFacet(this,
LABEL_FACET, true);
if (component == null) {
// This really should be done using JSF application
// create component, and component type.
//
component = (UIComponent) new Label();
if (component == null) {
// Log severe problem
return null;
}
component.setId(ComponentUtilities.createPrivateFacetId(
this, LABEL_FACET));
ComponentUtilities.putPrivateFacet(this, LABEL_FACET,
component);
}
((Label) component).setText(label);
// Theme should be queried for the label level if
// there isn't an attribute, which there should be.
// The renderer verifies the value.
//
//((Label)component).setLabelLevel(getLabelLevel());
// We need to set the for attribute for this label.
// How do we choose which of the possibly several
// properties to set it on. Easy. The Property component
// should have a "for" attribute whose value is the
// component to associate the label to.
//
// Currently there are heuristics implemented to try
// find the labelled component, continue using that
// for now.
//
String id = getLabeledElementId(getFacesContext());
((Label) component).setFor(id);
return component;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Tag attribute methods
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* The component identifier for this component. This value must be unique
* within the closest parent component that is a naming container.
*/
@com.sun.faces.annotation.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.
*/
@com.sun.faces.annotation.Property(name = "rendered")
@Override
public void setRendered(boolean rendered) {
super.setRendered(rendered);
}
/**
* Flag indicating that the user is not permitted to activate this
* component, and that the component's value will not be submitted with the
* form.
*/
@com.sun.faces.annotation.Property(name = "disabled", displayName = "Disabled", category = "Behavior")
private boolean disabled = false;
private boolean disabled_set = false;
/**
* Flag indicating that the user is not permitted to activate this
* component, and that the component's value will not be submitted with the
* form.
*/
public boolean isDisabled() {
if (this.disabled_set) {
return this.disabled;
}
ValueExpression _vb = getValueExpression("disabled");
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 is not permitted to activate this
* component, and that the component's value will not be submitted with the
* form.
* @see #isDisabled()
*/
public void setDisabled(boolean disabled) {
this.disabled = disabled;
this.disabled_set = true;
}
/**
* The text specified with this attribue is displayed below the content
* of the property in a small font. The value can be a literal String or
* a ValueBinding expression. If you want greater control over the content
* that is displayed in the help text area, use the helpText facet.
*/
@com.sun.faces.annotation.Property(name = "helpText", displayName = "Help Text",
category = "Appearance", editorClassName = "com.sun.rave.propertyeditors.StringPropertyEditor")
private String helpText = null;
/**
* The text specified with this attribue is displayed below the content
* of the property in a small font. The value can be a literal String or
* a ValueBinding expression. If you want greater control over the content
* that is displayed in the help text area, use the helpText facet.
*/
public String getHelpText() {
if (this.helpText != null) {
return this.helpText;
}
ValueExpression _vb = getValueExpression("helpText");
if (_vb != null) {
return (String) _vb.getValue(getFacesContext().getELContext());
}
return null;
}
/**
* The text specified with this attribue is displayed below the content
* of the property in a small font. The value can be a literal String or
* a ValueBinding expression. If you want greater control over the content
* that is displayed in the help text area, use the helpText facet.
* @see #getHelpText()
*/
public void setHelpText(String helpText) {
this.helpText = helpText;
}
/**
* Use this attribute to specify the text of the label of this
* property. The text is displayed in the column that is
* reserved for the label of this property row. The attribute value
* can be a string or a value binding expression. The label is associated with the
* first input element in the content area of the property.
* To label a different component, use the label facet instead.
*/
@com.sun.faces.annotation.Property(name = "label", displayName = "Label",
category = "Appearance", editorClassName = "com.sun.rave.propertyeditors.StringPropertyEditor")
private String label = null;
/**
* Use this attribute to specify the text of the label of this
* property. The text is displayed in the column that is
* reserved for the label of this property row. The attribute value
* can be a string or a value binding expression. The label is associated with the
* first input element in the content area of the property.
* To label a different component, use the label facet instead.
*/
public String getLabel() {
if (this.label != null) {
return this.label;
}
ValueExpression _vb = getValueExpression("label");
if (_vb != null) {
return (String) _vb.getValue(getFacesContext().getELContext());
}
return null;
}
/**
* Use this attribute to specify the text of the label of this
* property. The text is displayed in the column that is
* reserved for the label of this property row. The attribute value
* can be a string or a value binding expression. The label is associated with the
* first input element in the content area of the property.
* To label a different component, use the label facet instead.
* @see #getLabel()
*/
public void setLabel(String label) {
this.label = label;
}
/**
* Specifies the alignment for the property label.
* The label occupies a cell in the first column of a table that is
* used to lay out the properties. Set the labelAlign attribute to make
* the label align to the left or right of the cell. The default alignment
* is left. This attibute applies to labels that are specified with either
* the label attribute or the label facet.
*/
@com.sun.faces.annotation.Property(name = "labelAlign", displayName = "Label Alignment",
category = "Appearance",
editorClassName = "com.sun.webui.jsf.component.propertyeditors.HtmlHorizontalAlignEditor")
private String labelAlign = null;
/**
* Specifies the alignment for the property label.
* The label occupies a cell in the first column of a table that is
* used to lay out the properties. Set the labelAlign attribute to make
* the label align to the left or right of the cell. The default alignment
* is left. This attibute applies to labels that are specified with either
* the label attribute or the label facet.
*/
public String getLabelAlign() {
if (this.labelAlign != null) {
return this.labelAlign;
}
ValueExpression _vb = getValueExpression("labelAlign");
if (_vb != null) {
return (String) _vb.getValue(getFacesContext().getELContext());
}
return null;
}
/**
* Specifies the alignment for the property label.
* The label occupies a cell in the first column of a table that is
* used to lay out the properties. Set the labelAlign attribute to make
* the label align to the left or right of the cell. The default alignment
* is left. This attibute applies to labels that are specified with either
* the label attribute or the label facet.
* @see #getLabelAlign()
*/
public void setLabelAlign(String labelAlign) {
this.labelAlign = labelAlign;
}
/**
* Specifies that the label should not wrap around to another line, if set to
* true. If the label is long, the label column in the table for the property
* sheet section expands to accomodate the label without wrapping to a new line.
* This attibute applies to labels that are specified with either the label
* attribute or the label facet.
*/
@com.sun.faces.annotation.Property(name = "noWrap", displayName = "Label No-Wrap", category = "Appearance")
private boolean noWrap = false;
private boolean noWrap_set = false;
/**
* Specifies that the label should not wrap around to another line, if set to
* true. If the label is long, the label column in the table for the property
* sheet section expands to accomodate the label without wrapping to a new line.
* This attibute applies to labels that are specified with either the label
* attribute or the label facet.
*/
public boolean isNoWrap() {
if (this.noWrap_set) {
return this.noWrap;
}
ValueExpression _vb = getValueExpression("noWrap");
if (_vb != null) {
Object _result = _vb.getValue(getFacesContext().getELContext());
if (_result == null) {
return false;
} else {
return ((Boolean) _result).booleanValue();
}
}
return false;
}
/**
* Specifies that the label should not wrap around to another line, if set to
* true. If the label is long, the label column in the table for the property
* sheet section expands to accomodate the label without wrapping to a new line.
* This attibute applies to labels that are specified with either the label
* attribute or the label facet.
* @see #isNoWrap()
*/
public void setNoWrap(boolean noWrap) {
this.noWrap = noWrap;
this.noWrap_set = true;
}
/**
* Specifies that the content of the property should occupy the label
* area as well as the content area, if set to true. The default value is
* false. This attribute is useful for properties that require the entire
* width of the property sheet.
*/
@com.sun.faces.annotation.Property(name = "overlapLabel", displayName = "Overlap Label", category = "Appearance")
private boolean overlapLabel = false;
private boolean overlapLabel_set = false;
/**
* Specifies that the content of the property should occupy the label
* area as well as the content area, if set to true. The default value is
* false. This attribute is useful for properties that require the entire
* width of the property sheet.
*/
public boolean isOverlapLabel() {
if (this.overlapLabel_set) {
return this.overlapLabel;
}
ValueExpression _vb = getValueExpression("overlapLabel");
if (_vb != null) {
Object _result = _vb.getValue(getFacesContext().getELContext());
if (_result == null) {
return false;
} else {
return ((Boolean) _result).booleanValue();
}
}
return false;
}
/**
* Specifies that the content of the property should occupy the label
* area as well as the content area, if set to true. The default value is
* false. This attribute is useful for properties that require the entire
* width of the property sheet.
* @see #isOverlapLabel()
*/
public void setOverlapLabel(boolean overlapLabel) {
this.overlapLabel = overlapLabel;
this.overlapLabel_set = true;
}
/**
* CSS style(s) to be applied to the outermost HTML element when this
* component is rendered.
*/
@com.sun.faces.annotation.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.
*/
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()
*/
public void setStyle(String style) {
this.style = style;
}
/**
* CSS style class(es) to be applied to the outermost HTML element when this
* component is rendered.
*/
@com.sun.faces.annotation.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.
*/
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()
*/
public void setStyleClass(String styleClass) {
this.styleClass = styleClass;
}
/**
* 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.
*/
@com.sun.faces.annotation.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.
*/
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()
*/
public void setVisible(boolean visible) {
this.visible = visible;
this.visible_set = true;
}
/**
* Restore the state of this component.
*/
@Override
public void restoreState(FacesContext _context, Object _state) {
Object _values[] = (Object[]) _state;
super.restoreState(_context, _values[0]);
this.disabled = ((Boolean) _values[1]).booleanValue();
this.disabled_set = ((Boolean) _values[2]).booleanValue();
this.helpText = (String) _values[3];
this.label = (String) _values[4];
this.labelAlign = (String) _values[5];
this.noWrap = ((Boolean) _values[6]).booleanValue();
this.noWrap_set = ((Boolean) _values[7]).booleanValue();
this.overlapLabel = ((Boolean) _values[8]).booleanValue();
this.overlapLabel_set = ((Boolean) _values[9]).booleanValue();
this.style = (String) _values[10];
this.styleClass = (String) _values[11];
this.visible = ((Boolean) _values[12]).booleanValue();
this.visible_set = ((Boolean) _values[13]).booleanValue();
}
/**
* Save the state of this component.
*/
@Override
public Object saveState(FacesContext _context) {
Object _values[] = new Object[14];
_values[0] = super.saveState(_context);
_values[1] = this.disabled ? Boolean.TRUE : Boolean.FALSE;
_values[2] = this.disabled_set ? Boolean.TRUE : Boolean.FALSE;
_values[3] = this.helpText;
_values[4] = this.label;
_values[5] = this.labelAlign;
_values[6] = this.noWrap ? Boolean.TRUE : Boolean.FALSE;
_values[7] = this.noWrap_set ? Boolean.TRUE : Boolean.FALSE;
_values[8] = this.overlapLabel ? Boolean.TRUE : Boolean.FALSE;
_values[9] = this.overlapLabel_set ? Boolean.TRUE : Boolean.FALSE;
_values[10] = this.style;
_values[11] = this.styleClass;
_values[12] = this.visible ? Boolean.TRUE : Boolean.FALSE;
_values[13] = this.visible_set ? Boolean.TRUE : Boolean.FALSE;
return _values;
}
}