|
From: <isp...@rh...> - 2009-01-31 00:38:30
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><style type="text/css"><!-- #msg DL { border : 1px #006 solid; background-color : #369; padding : 6px; color : #fff; } #msg DT { float : left; width : 6em; font-weight : bold; } #msg DL, #msg DT, #msg UL, #msg LI { font-family : arial,helvetica,sans-serif; font-size : 10pt; } h3 { font-family : arial,helvetica,sans-serif; font-size : 10pt; font-weight : bold; } #msg PRE { overflow : auto; white-space : normal; background-color : #ffc; border : 1px #fc0 solid; padding : 6px; } #msg UL, PRE, .diff { overflow : auto; } #patch h4 { font-family : arial,helvetica,sans-serif; font-size : 10pt; } #patch h4 { padding: 8px; background : #369; color : #fff; margin : 0; } #patch .propset h4, #patch .binary h4 {margin: 0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {background:#eeeeee;padding: 0 0 10px 0;} #patch .propset .diff, #patch .binary .diff {padding: 10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch .add {background:#ddffdd;} #patch .rem {background:#ffdddd;} #patch .lines, .info {color:#888888;background:#ffffff;} .diff { width : 100%; } #msg DL { border : 1px #006 solid; background-color : #369; padding : 6px; color : #fff; } #msg DT { float : left; width : 6em; font-weight : bold; } #msg DL, #msg DT, #msg UL, #msg LI { font-family : arial,helvetica,sans-serif; font-size : 10pt; } h3 { font-family : arial,helvetica,sans-serif; font-size : 10pt; font-weight : bold; } #msg PRE { overflow : auto; white-space : normal; background-color : #ffc; border : 1px #fc0 solid; padding : 6px; } #msg UL, PRE, .diff { overflow : auto; } #patch h4 { font-family : arial,helvetica,sans-serif; font-size : 10pt; } #patch h4 { padding: 8px; background : #369; color : #fff; margin : 0; } #patch .propset h4, #patch .binary h4 {margin: 0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {background:#eeeeee;padding: 0 0 10px 0;} #patch .propset .diff, #patch .binary .diff {padding: 10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch .add {background:#ddffdd;} #patch .rem {background:#ffdddd;} #patch .lines, .info {color:#888888;background:#ffffff;} .diff { width : 100%; } --></style> <title>[rhq-project.org rhq] [2855] the latest rev of the propertySet/"drilldown" component for the new group config UI</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>2855</dd> <dt>Author</dt> <dd>ispringer</dd> <dt>Date</dt> <dd>2009-01-30 18:38:24 -0600 (Fri, 30 Jan 2009)</dd> </dl> <h3>Log Message</h3> <pre>the latest rev of the propertySet/"drilldown" component for the new group config UI</pre> <h3>Modified Paths</h3> <ul> <li><a href="#rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiconfigurationAbstractPropertyBagUIComponentTreeFactoryjava">rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractPropertyBagUIComponentTreeFactory.java</a></li> <li><a href="#rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiconfigurationConfigRendererjava">rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java</a></li> <li><a href="#rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiconfigurationpropsetPropertySetComponentjava">rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/propset/PropertySetComponent.java</a></li> <li><a href="#rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiconfigurationpropsetPropertySetRendererjava">rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/propset/PropertySetRenderer.java</a></li> <li><a href="#rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiutilFacesComponentUtilityjava">rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/util/FacesComponentUtility.java</a></li> <li><a href="#rhqtrunkmodulesenterpriseguiportalwarsrcmainjavaorgrhqenterpriseguiconfigurationtestTestConfigurationFactoryjava">rhq/trunk/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java</a></li> <li><a href="#rhqtrunkmodulesenterpriseguiportalwarsrcmainwebappjsrhqjs">rhq/trunk/modules/enterprise/gui/portal-war/src/main/webapp/js/rhq.js</a></li> <li><a href="#rhqtrunkmodulesenterpriseguiportalwarsrcmainwebapprhqtestconfigeditconfigxhtml">rhq/trunk/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit-config.xhtml</a></li> <li><a href="#rhqtrunkmodulesenterpriseguiportalwarsrcmainwebapprhqtestconfigeditmapxhtml">rhq/trunk/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit-map.xhtml</a></li> <li><a href="#rhqtrunkmodulesenterpriseguiportalwarsrcmainwebapprhqtestconfigpropsxhtml">rhq/trunk/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/props.xhtml</a></li> </ul> <h3>Added Paths</h3> <ul> <li><a href="#rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiconfigurationCssStyleClassesjava">rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/CssStyleClasses.java</a></li> <li><a href="#rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiconfigurationhelperPropertyRenderingUtilityjava">rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/helper/PropertyRenderingUtility.java</a></li> </ul> <h3>Removed Paths</h3> <ul> <li><a href="#rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiconfigurationhelperPropertySimpleRenderingUtilityjava">rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/helper/PropertySimpleRenderingUtility.java</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiconfigurationAbstractPropertyBagUIComponentTreeFactoryjava"></a> <div class="modfile"><h4>Modified: rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractPropertyBagUIComponentTreeFactory.java (2854 => 2855)</h4> <pre class="diff"> <span class="info">--- rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractPropertyBagUIComponentTreeFactory.java 2009-01-30 23:16:19 UTC (rev 2854) +++ rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractPropertyBagUIComponentTreeFactory.java 2009-01-31 00:38:24 UTC (rev 2855) </span><span class="lines">@@ -26,7 +26,6 @@ </span><span class="cx"> import javax.el.MethodExpression; import javax.el.ValueExpression; </span><span class="rem">- import javax.faces.application.FacesMessage; </span><span class="cx"> import javax.faces.component.UIComponent; import javax.faces.component.UIInput; import javax.faces.component.UIPanel; </span><span class="lines">@@ -35,8 +34,6 @@ </span><span class="cx"> import javax.faces.component.html.HtmlPanelGrid; import javax.faces.component.html.HtmlPanelGroup; import javax.faces.component.html.HtmlSelectBooleanCheckbox; </span><span class="rem">- import javax.faces.context.FacesContext; - import javax.faces.validator.ValidatorException; </span><span class="cx"> import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; </span><span class="lines">@@ -51,14 +48,12 @@ </span><span class="cx"> import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; import org.rhq.core.gui.RequestParameterNameConstants; </span><span class="rem">- import org.rhq.core.gui.configuration.helper.PropertySimpleRenderingUtility; </span><span class="add">+ import org.rhq.core.gui.configuration.helper.PropertyRenderingUtility; </span><span class="cx"> import org.rhq.core.gui.util.FacesComponentUtility; </span><span class="rem">- import org.rhq.core.gui.util.FacesContextUtility; </span><span class="cx"> import org.rhq.core.gui.util.FacesExpressionUtility; import org.rhq.core.gui.util.PropertyIdGeneratorUtility; </span><span class="rem">- import org.rhq.core.gui.validator.PropertySimpleValueValidator; </span><span class="cx"> </span><span class="rem">-/** </span><span class="add">+ /** </span><span class="cx"> * A factory that generates a tree of JSF components that depicts a given collection of JON {@link Property}s. * * @author Ian Springer (with some code snarfed from embedded's <code>org.jboss.on.embedded.ui.WidgetFactory</code>) </span><span class="lines">@@ -84,16 +79,10 @@ </span><span class="cx"> private static final String ADD_NEW_MAP_BUTTON_LABEL = "Add New"; private static final String ADD_NEW_MAP_BUTTON_TITLE = "Add New"; </span><span class="rem">- private static final String PROPERTIES_TABLE_STYLE_CLASS = "properties-table"; </span><span class="cx"> private static final String NESTED_PROPERTIES_TABLE_STYLE_CLASS = "nested-properties-table"; private static final String PROPERTIES_TABLE_HEADER_CELL_STYLE_CLASS = "properties-table-header-cell"; private static final String NESTED_PROPERTIES_TABLE_HEADER_CELL_STYLE_CLASS = "nested-properties-table-header-cell"; </span><span class="rem">- private static final String NESTED_PROPERTIES_TABLE_INDENT_CELL_STYLE_CLASS = "nested-properties-table-indent-cell"; - private static final String DESCRIPTION_STYLE_CLASS = "description"; - private static final String PROPERTY_DISPLAY_NAME_CELL_STYLE_CLASS = "property-display-name-cell"; - private static final String PROPERTY_VALUE_CELL_STYLE_CLASS = "property-value-cell"; - private static final String PROPERTY_DESCRIPTION_CELL_STYLE_CLASS = "property-description-cell"; - private static final String PROPERTY_ENABLED_CELL_STYLE_CLASS = "property-enabled-cell"; </span><span class="add">+ private static final String NESTED_PROPERTIES_TABLE_INDENT_CELL_STYLE_CLASS = "nested-properties-table-indent-cell"; </span><span class="cx"> private static final String PROPERTY_ERROR_CELL_STYLE_CLASS = "property-error-cell"; private static final String OPENMAP_PROPERTIES_TABLE_STYLE_CLASS = "openmap-properties-table"; private static final String OPENMAP_PROPERTY_DISPLAY_NAME_CELL_STYLE_CLASS = "openmap-property-display-name-cell"; </span><span class="lines">@@ -104,17 +93,14 @@ </span><span class="cx"> private static final String LIST_PROPERTY_VALUE_CELL_STYLE_CLASS = "list-property-value-cell"; private static final String LIST_PROPERTY_DESCRIPTION_CELL_STYLE_CLASS = "list-property-description-cell"; private static final String LIST_PROPERTY_ENABLED_CELL_STYLE_CLASS = "list-property-enabled-cell"; </span><span class="rem">- private static final String LIST_PROPERTY_CHILDREN_CELL_STYLE_CLASS = "list-property-children-cell"; - private static final String ERROR_MSG_STYLE_CLASS = "error-msg"; - private static final String PROPERTY_DISPLAY_NAME_TEXT_STYLE_CLASS = "property-display-name-text"; </span><span class="add">+ private static final String LIST_PROPERTY_CHILDREN_CELL_STYLE_CLASS = "list-property-children-cell"; </span><span class="cx"> private static final String PROPERTY_MAP_SUMMARY_TABLE_STYLE_CLASS = "property-map-summary-table"; private static final String PROPERTY_MAP_SUMMARY_DATA_HEADER_CELL_STYLE_CLASS = "property-map-summary-data-header-cell"; private static final String PROPERTY_MAP_SUMMARY_HEADER_TEXT_STYLE_CLASS = "property-map-summary-header-text"; private static final String PROPERTY_MAP_SUMMARY_BUTTONS_CELL_STYLE_CLASS = "property-map-summary-buttons-cell"; private static final String PROPERTY_MAP_SUMMARY_DATA_CELL_STYLE_CLASS = "property-map-summary-data-cell"; private static final String PROPERTY_MAP_SUMMARY_DATA_TEXT_STYLE_CLASS = "property-map-summary-data-text"; </span><span class="rem">- private static final String PROPERTY_MAP_SUMMARY_BUTTON_FOOTER_STYLE_CLASS = "property-buttonfooterrow"; - private static final String REQUIRED_MARKER_TEXT_STYLE_CLASS = "required-marker-text"; </span><span class="add">+ private static final String PROPERTY_MAP_SUMMARY_BUTTON_FOOTER_STYLE_CLASS = "property-buttonfooterrow"; </span><span class="cx"> private static final String BUTTONS_TABLE_STYLE_CLASS = "buttons-table"; private static final String BUTTON_SMALL_STYLE_CLASS = "buttonsmall"; private static final String ROW_ODD_STYLE_CLASS = "OddRow"; </span><span class="lines">@@ -155,7 +141,7 @@ </span><span class="cx"> FacesComponentUtility.NO_STYLE_CLASS); if (!this.propertyDefinitions.isEmpty() || (this.propertyMap instanceof PropertyMap)) { if (!this.propertyDefinitions.isEmpty()) { </span><span class="rem">- String tableStyleClass = this.topLevel ? PROPERTIES_TABLE_STYLE_CLASS </span><span class="add">+ String tableStyleClass = this.topLevel ? CssStyleClasses.PROPERTIES_TABLE </span><span class="cx"> : NESTED_PROPERTIES_TABLE_STYLE_CLASS; FacesComponentUtility.addVerbatimText(rootPanel, "\n\n<table class='" + tableStyleClass + "'>"); int rowCount = 0; </span><span class="lines">@@ -303,34 +289,34 @@ </span><span class="cx"> PropertySimple propertySimple = this.propertyMap.getSimple(propertyDefinitionSimple.getName()); ValueExpression propertyValueExpression = createPropertyValueExpression(propertySimple.getName(), this.valueExpressionFormat); </span><span class="rem">- UIInput input = PropertySimpleRenderingUtility.createInputForSimpleProperty(propertyDefinitionSimple, - propertySimple, propertyValueExpression, getListIndex(), this.config.isReadOnly()); - HtmlSelectBooleanCheckbox unsetCheckbox = FacesComponentUtility.createComponent( - HtmlSelectBooleanCheckbox.class, this.config); </span><span class="add">+ UIInput input = PropertyRenderingUtility.createInputForSimpleProperty(propertyDefinitionSimple, + propertySimple, propertyValueExpression, getListIndex(), this.config.isReadOnly(), + this.config.isPrevalidate()); </span><span class="cx"> // done generating </span><span class="rem">- FacesComponentUtility.addVerbatimText(parent, "<td class='" + PROPERTY_DISPLAY_NAME_CELL_STYLE_CLASS + "'>"); - addPropertyDisplayName(parent, propertyDefinitionSimple); </span><span class="add">+ FacesComponentUtility.addVerbatimText(parent, "<td class='" + CssStyleClasses.PROPERTY_DISPLAY_NAME_CELL + "'>"); + PropertyRenderingUtility.addPropertyDisplayName(parent, propertyDefinitionSimple, this.config.isReadOnly()); </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "</td>"); if (config.isAggregate()) { </span><span class="rem">- FacesComponentUtility.addVerbatimText(parent, "<td class='" + PROPERTY_ENABLED_CELL_STYLE_CLASS + "'>"); - addPropertyOverrideControl(parent, propertyDefinitionSimple, input, unsetCheckbox); </span><span class="add">+ FacesComponentUtility.addVerbatimText(parent, "<td class='" + CssStyleClasses.PROPERTY_ENABLED_CELL + "'>"); + addPropertyOverrideControl(parent, propertyDefinitionSimple, input); </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "</td>"); } </span><span class="rem">- FacesComponentUtility.addVerbatimText(parent, "<td class='" + PROPERTY_ENABLED_CELL_STYLE_CLASS + "'>"); - addPropertyUnsetControl(parent, propertyDefinitionSimple, input, unsetCheckbox); </span><span class="add">+ FacesComponentUtility.addVerbatimText(parent, "<td class='" + CssStyleClasses.PROPERTY_ENABLED_CELL + "'>"); + PropertyRenderingUtility.addUnsetControl(parent, propertyDefinitionSimple, propertySimple, input, + this.config.isReadOnly()); </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "</td>"); </span><span class="rem">- FacesComponentUtility.addVerbatimText(parent, "<td class='" + PROPERTY_VALUE_CELL_STYLE_CLASS + "'>"); </span><span class="add">+ FacesComponentUtility.addVerbatimText(parent, "<td class='" + CssStyleClasses.PROPERTY_VALUE_CELL + "'>"); </span><span class="cx"> parent.getChildren().add(input); FacesComponentUtility.addVerbatimText(parent, "<br/>"); </span><span class="rem">- addErrorMessages(parent, input, propertyDefinitionSimple); </span><span class="add">+ PropertyRenderingUtility.addMessageComponentForInput(parent, input); </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "</td>"); </span><span class="rem">- FacesComponentUtility.addVerbatimText(parent, "<td class='" + PROPERTY_DESCRIPTION_CELL_STYLE_CLASS + "'>"); - addPropertyDescription(parent, propertyDefinitionSimple); </span><span class="add">+ FacesComponentUtility.addVerbatimText(parent, "<td class='" + CssStyleClasses.PROPERTY_DESCRIPTION_CELL + "'>"); + PropertyRenderingUtility.addPropertyDescription(parent, propertyDefinitionSimple); </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "</td>"); FacesComponentUtility.addVerbatimText(parent, "</tr>"); </span><span class="lines">@@ -353,17 +339,15 @@ </span><span class="cx"> FacesComponentUtility.addVerbatimText(panel, "<td class='" + OPENMAP_PROPERTY_DISPLAY_NAME_CELL_STYLE_CLASS + "'>"); FacesComponentUtility.addOutputText(panel, this.config, propertySimple.getName(), </span><span class="rem">- PROPERTY_DISPLAY_NAME_TEXT_STYLE_CLASS); </span><span class="add">+ CssStyleClasses.PROPERTY_DISPLAY_NAME_TEXT); </span><span class="cx"> FacesComponentUtility.addVerbatimText(panel, "</td>"); FacesComponentUtility.addVerbatimText(panel, "<td class='" + OPENMAP_PROPERTY_VALUE_CELL_STYLE_CLASS + "'>"); </span><span class="rem">- UIInput input = PropertySimpleRenderingUtility.createInputForSimpleProperty(propertySimple, </span><span class="add">+ UIInput input = PropertyRenderingUtility.createInputForSimpleProperty(propertySimple, </span><span class="cx"> this.valueExpressionFormat, this.config.isReadOnly()); panel.getChildren().add(input); FacesComponentUtility.addVerbatimText(panel, "</td>"); </span><span class="rem">- addErrorMessages(panel, input, propertySimple); - </span><span class="cx"> if (!isReadOnly(propertyDefinitionMap)) { // add Actions column w/ delete button FacesComponentUtility.addVerbatimText(panel, "<td class='" + OPENMAP_PROPERTY_ACTIONS_CELL_STYLE_CLASS </span><span class="lines">@@ -402,7 +386,7 @@ </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "<td class='" + LIST_PROPERTY_DISPLAY_NAME_CELL_STYLE_CLASS + "'>"); </span><span class="rem">- addPropertyDisplayName(parent, listPropertyDefinition); </span><span class="add">+ PropertyRenderingUtility.addPropertyDisplayName(parent, listPropertyDefinition, this.config.isReadOnly()); </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "</td>"); FacesComponentUtility.addVerbatimText(parent, "<td class='" + LIST_PROPERTY_ENABLED_CELL_STYLE_CLASS + "' />"); </span><span class="lines">@@ -411,7 +395,7 @@ </span><span class="cx"> FacesComponentUtility .addVerbatimText(parent, "<td class='" + LIST_PROPERTY_DESCRIPTION_CELL_STYLE_CLASS + "'>"); </span><span class="rem">- addPropertyDescription(parent, listPropertyDefinition); </span><span class="add">+ PropertyRenderingUtility.addPropertyDescription(parent, listPropertyDefinition); </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "</td>"); FacesComponentUtility.addVerbatimText(parent, "</tr>"); </span><span class="lines">@@ -597,7 +581,7 @@ </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "<td class='" + PROPERTY_MAP_SUMMARY_DATA_CELL_STYLE_CLASS + "'>"); if (mapMemberSimpleProperty.getStringValue() == null) { </span><span class="rem">- FacesComponentUtility.addOutputText(parent, this.config, "not set", REQUIRED_MARKER_TEXT_STYLE_CLASS); </span><span class="add">+ FacesComponentUtility.addOutputText(parent, this.config, "not set", CssStyleClasses.REQUIRED_MARKER_TEXT); </span><span class="cx"> } else { FacesComponentUtility.addOutputText(parent, this.config, mapMemberSimpleProperty.getStringValue(), PROPERTY_MAP_SUMMARY_DATA_TEXT_STYLE_CLASS); </span><span class="lines">@@ -627,7 +611,7 @@ </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "<td class='" + LIST_PROPERTY_DISPLAY_NAME_CELL_STYLE_CLASS + "'>"); </span><span class="rem">- addPropertyDisplayName(parent, propertyDefinitionMap); </span><span class="add">+ PropertyRenderingUtility.addPropertyDisplayName(parent, propertyDefinitionMap, this.config.isReadOnly()); </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "</td>"); FacesComponentUtility.addVerbatimText(parent, "<td class='" + LIST_PROPERTY_ENABLED_CELL_STYLE_CLASS + "' />"); </span><span class="lines">@@ -636,7 +620,7 @@ </span><span class="cx"> FacesComponentUtility .addVerbatimText(parent, "<td class='" + LIST_PROPERTY_DESCRIPTION_CELL_STYLE_CLASS + "'>"); </span><span class="rem">- addPropertyDescription(parent, propertyDefinitionMap); </span><span class="add">+ PropertyRenderingUtility.addPropertyDescription(parent, propertyDefinitionMap); </span><span class="cx"> FacesComponentUtility.addVerbatimText(parent, "</td>"); FacesComponentUtility.addVerbatimText(parent, "</tr>"); </span><span class="lines">@@ -715,88 +699,8 @@ </span><span class="cx"> return input; } </span><span class="rem">- - - - private void addErrorMessages(UIComponent parent, UIInput input, PropertyDefinitionSimple propertyDefinitionSimple) { - addDebug(parent, true, ".addErrorMessages()"); - addMessageComponentForInput(parent, input); - - // Pre-validate the property's value, in case the PC sent us an invalid live config. - PropertySimpleValueValidator validator = new PropertySimpleValueValidator(propertyDefinitionSimple); - PropertySimple propertySimple = this.propertyMap.getSimple(propertyDefinitionSimple.getName()); - prevalidatePropertyValue(input, propertySimple, validator); - - // If there is a PC-detected error associated with the property, associate it with the input. - addPluginContainerDetectedErrorMessage(input, propertySimple); - addDebug(parent, false, ".addErrorMessages()"); - } - - private void addErrorMessages(UIComponent parent, UIInput input, PropertySimple propertySimple) { - addDebug(parent, true, ".addErrorMessages()"); - addMessageComponentForInput(parent, input); - - // Pre-validate the property's value, in case the PC sent us an invalid live config. - PropertySimpleValueValidator validator = new PropertySimpleValueValidator(); - if (this.config.isPrevalidate()) { - prevalidatePropertyValue(input, propertySimple, validator); - } - - // If there is a PC-detected error associated with the property, associate it with the input. - addPluginContainerDetectedErrorMessage(input, propertySimple); - addDebug(parent, false, ".addErrorMessages()"); - } - - private void addMessageComponentForInput(UIComponent parent, UIInput input) { - // <h:message for="#{input-component-id}" showDetail="true" errorClass="error-msg" /> - FacesComponentUtility.addMessage(parent, this.config, input.getId(), ERROR_MSG_STYLE_CLASS); - } - - private void prevalidatePropertyValue(UIInput input, PropertySimple propertySimple, - PropertySimpleValueValidator validator) { - FacesContext facesContext = FacesContextUtility.getFacesContext(); - try { - String value = (propertySimple != null) ? propertySimple.getStringValue() : null; - validator.validate(facesContext, input, value); - } catch (ValidatorException e) { - // NOTE: It's vital to pass the client id, *not* the component id, to addMessage(). - facesContext.addMessage(input.getClientId(facesContext), e.getFacesMessage()); - } - } - - private void addPluginContainerDetectedErrorMessage(UIInput input, PropertySimple propertySimple) { - String errorMsg = (propertySimple != null) ? propertySimple.getErrorMessage() : null; - if ((errorMsg != null) && !errorMsg.equals("")) { - FacesContext facesContext = FacesContextUtility.getFacesContext(); - FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMsg, null); - - // NOTE: It's vital to pass the client id, *not* the component id, to addMessage(). - facesContext.addMessage(input.getClientId(facesContext), facesMsg); - } - } - - // <h:outputLabel value="DISPLAY_NAME" styleClass="..." /> - private void addPropertyDisplayName(UIComponent parent, PropertyDefinition propertyDefinition) { - FacesComponentUtility.addOutputText(parent, this.config, propertyDefinition.getDisplayName(), - PROPERTY_DISPLAY_NAME_TEXT_STYLE_CLASS); - if (!this.config.isReadOnly() && propertyDefinition.isRequired() - && (propertyDefinition instanceof PropertyDefinitionSimple)) { - // Print a required marker next to required simples. - // Ignore the required field for maps and lists, as it is has no significance for them. - FacesComponentUtility.addOutputText(parent, this.config, " * ", REQUIRED_MARKER_TEXT_STYLE_CLASS); - } - } - - private void addPropertyDescription(UIComponent parent, PropertyDefinition propertyDefinition) { - // <span class="description">DESCRIPTION</span> - if (propertyDefinition.getDescription() != null) { - FacesComponentUtility.addOutputText(parent, this.config, propertyDefinition.getDescription(), - DESCRIPTION_STYLE_CLASS); - } - } - </span><span class="cx"> private void addPropertyOverrideControl(UIComponent parent, PropertyDefinitionSimple propertyDefinitionSimple, </span><span class="rem">- UIInput valueInput, HtmlSelectBooleanCheckbox unsetCheckbox) { </span><span class="add">+ UIInput valueInput) { </span><span class="cx"> HtmlSelectBooleanCheckbox overrideCheckbox = createInputOverrideForSimpleProperty(propertyDefinitionSimple); parent.getChildren().add(overrideCheckbox); overrideCheckbox.setValue(isOverride(propertyDefinitionSimple)); </span><span class="lines">@@ -811,40 +715,13 @@ </span><span class="cx"> * unsetCheckbox is NOT unset */ StringBuilder onchange = new StringBuilder(); </span><span class="rem">- for (String valueInputHtmlDomReference : ConfigRenderer.getHtmlDomReferences(valueInput)) { </span><span class="add">+ for (String valueInputHtmlDomReference : PropertyRenderingUtility.getHtmlDomReferences(valueInput)) { </span><span class="cx"> onchange.append("setInputOverride(").append(valueInputHtmlDomReference).append(", this.checked);"); } overrideCheckbox.setOnchange(onchange.toString()); } </span><span class="rem">- private void addPropertyUnsetControl(UIComponent parent, PropertyDefinitionSimple propertyDefinitionSimple, - UIInput valueInput, HtmlSelectBooleanCheckbox unsetCheckbox) { - if (!propertyDefinitionSimple.isRequired()) { - parent.getChildren().add(unsetCheckbox); - unsetCheckbox.setValue(Boolean.valueOf(isUnset(propertyDefinitionSimple))); - if (isReadOnly(propertyDefinitionSimple)) { - FacesComponentUtility.setDisabled(unsetCheckbox, true); - } else { - // Add JavaScript that will disable/enable the corresponding input element when the unset checkbox is - // checked/unchecked. - // IMPORTANT: We must use document.formName.inputName, rather than document.getElementById('inputId'), - // to reference the HTML DOM element, because the id of the HTML DOM input element is not the same as the - // id of the corresponding JSF input component in some cases (e.g. radio buttons). However, the - // name property that JSF renders on the HTML DOM input element does always match the JSF - // component id. (ips, 05/31/07) - StringBuilder onchange = new StringBuilder(); - for (String htmlDomReference : ConfigRenderer.getHtmlDomReferences(valueInput)) { - onchange.append("setInputUnset(").append(htmlDomReference).append(", this.checked);"); - } - - unsetCheckbox.setOnchange(onchange.toString()); - } - } - } - - - </span><span class="cx"> /** * Binds the value of the specified UIInput to an EL expression corresponding to the Configuration property's * override attribute with the specified name. </span></pre></div> <a id="rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiconfigurationConfigRendererjava"></a> <div class="modfile"><h4>Modified: rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java (2854 => 2855)</h4> <pre class="diff"> <span class="info">--- rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java 2009-01-30 23:16:19 UTC (rev 2854) +++ rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java 2009-01-31 00:38:24 UTC (rev 2855) </span><span class="lines">@@ -22,40 +22,34 @@ </span><span class="cx"> */ package org.rhq.core.gui.configuration; </span><span class="rem">- import java.io.IOException; - import java.util.ArrayList; - import java.util.List; - import java.util.Map; </span><span class="add">+import java.io.IOException; +import java.util.List; +import java.util.Map; </span><span class="cx"> </span><span class="rem">- import javax.faces.application.FacesMessage; - import javax.faces.component.NamingContainer; - import javax.faces.component.UIComponent; - import javax.faces.component.UIInput; - import javax.faces.component.UIOutput; - import javax.faces.component.UIParameter; - import javax.faces.component.UISelectItem; - import javax.faces.component.html.HtmlPanelGroup; - import javax.faces.component.html.HtmlSelectOneRadio; - import javax.faces.context.FacesContext; - import javax.faces.render.Renderer; </span><span class="add">+import javax.faces.application.FacesMessage; +import javax.faces.component.UIComponent; +import javax.faces.component.UIParameter; +import javax.faces.component.html.HtmlPanelGroup; +import javax.faces.context.FacesContext; +import javax.faces.render.Renderer; </span><span class="cx"> </span><span class="rem">- import org.apache.commons.logging.Log; - import org.apache.commons.logging.LogFactory; - import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; - import org.rhq.core.domain.configuration.Property; - import org.rhq.core.domain.configuration.PropertyList; - import org.rhq.core.domain.configuration.PropertyMap; - import org.rhq.core.domain.configuration.PropertySimple; - import org.rhq.core.domain.configuration.definition.PropertyDefinition; - import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; - import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; - import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition; - import org.rhq.core.gui.RequestParameterNameConstants; - import org.rhq.core.gui.converter.PropertySimpleValueConverter; - import org.rhq.core.gui.util.FacesComponentUtility; - import org.rhq.core.gui.util.FacesContextUtility; - import org.rhq.core.gui.util.PropertyIdGeneratorUtility; - import org.richfaces.component.html.HtmlSimpleTogglePanel; </span><span class="add">+import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; +import org.rhq.core.domain.configuration.Property; +import org.rhq.core.domain.configuration.PropertyList; +import org.rhq.core.domain.configuration.PropertyMap; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.definition.PropertyDefinition; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; +import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition; +import org.rhq.core.gui.RequestParameterNameConstants; +import org.rhq.core.gui.configuration.helper.PropertyRenderingUtility; +import org.rhq.core.gui.util.FacesComponentUtility; +import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.core.gui.util.PropertyIdGeneratorUtility; +import org.richfaces.component.html.HtmlSimpleTogglePanel; </span><span class="cx"> /** * A renderer that renders a {@link ConfigUIComponent} component as XHTML. </span><span class="lines">@@ -96,12 +90,11 @@ </span><span class="cx"> } } if (config.getConfiguration() != null) { </span><span class="rem">- String id = PropertyIdGeneratorUtility.getIdentifier(config.getConfiguration(), - INIT_INPUTS_JAVA_SCRIPT_COMPONENT_ID_SUFFIX); </span><span class="add">+ String id = getInitInputsJavaScriptComponentId(config); </span><span class="cx"> UIComponent initInputsJavaScriptComponent = config.findComponent(id); if (initInputsJavaScriptComponent != null) { FacesComponentUtility.detachComponent(initInputsJavaScriptComponent); </span><span class="rem">- addInitInputsJavaScript(config, true); </span><span class="add">+ PropertyRenderingUtility.addInitInputsJavaScript(config, id, config.isFullyEditable(), true); </span><span class="cx"> } } } </span><span class="lines">@@ -152,7 +145,8 @@ </span><span class="cx"> addConfiguration(config); } </span><span class="rem">- addInitInputsJavaScript(config, false); </span><span class="add">+ String id = getInitInputsJavaScriptComponentId(config); + PropertyRenderingUtility.addInitInputsJavaScript(config, id, config.isFullyEditable(), false); </span><span class="cx"> } private void addListMemberProperty(ConfigUIComponent config) { </span><span class="lines">@@ -325,110 +319,6 @@ </span><span class="cx"> return groupPanel; } </span><span class="rem">- private void addInitInputsJavaScript(ConfigUIComponent config, boolean postBack) { - List<UIInput> inputs = FacesComponentUtility.getDescendantsOfType(config, UIInput.class); - List<UIInput> overrideInputs = new ArrayList<UIInput>(); - List<UIInput> unsetInputs = new ArrayList<UIInput>(); - List<UIInput> readOnlyInputs = new ArrayList<UIInput>(); - for (UIInput input : inputs) { - // readOnly components can not be overridden - by this point, the override - // status should have only been set if the component *was not* readOnly - if (FacesComponentUtility.isOverride(input)) { - overrideInputs.add(input); - } - - if (postBack) { - boolean inputIsNull = PropertySimpleValueConverter.NULL_INPUT_VALUE.equals(input.getSubmittedValue()); - FacesComponentUtility.setUnset(input, inputIsNull); - } - if (FacesComponentUtility.isUnset(input)) { - unsetInputs.add(input); - } - - if (!config.isFullyEditable() && FacesComponentUtility.isReadonly(input)) { - readOnlyInputs.add(input); - } - } - - StringBuilder script = new StringBuilder(); - - if (!overrideInputs.isEmpty()) { - script.append("var overrideInputArray = new Array("); - for (UIInput input : overrideInputs) { - for (String htmlDomReference : getHtmlDomReferences(input)) { - script.append(htmlDomReference).append(", "); - } - } - - script.delete(script.length() - 2, script.length()); // chop off the extra ", " - script.append(");\n"); - - // do it this way instead of DISABLED attribute via code, because if DISABLED is used and - // even if javascript later enables them, JSF won't submit them as part of the component - script.append("setInputsOverride(overrideInputArray, false);"); - } - - if (!unsetInputs.isEmpty()) { - script.append("var unsetInputArray = new Array("); - for (UIInput input : unsetInputs) { - for (String htmlDomReference : getHtmlDomReferences(input)) { - script.append(htmlDomReference).append(", "); - } - } - - script.delete(script.length() - 2, script.length()); // chop off the extra ", " - script.append(");\n"); - - // do it this way instead of DISABLED attribute via code, because if DISABLED is used and - // even if javascript later enables them, JSF won't submit them as part of the component - script.append("unsetInputs(unsetInputArray);"); - } - - if (!readOnlyInputs.isEmpty()) { - script.append("var readOnlyInputArray = new Array("); - for (UIInput input : readOnlyInputs) { - for (String htmlDomReference : getHtmlDomReferences(input)) { - script.append(htmlDomReference).append(", "); - } - } - - script.delete(script.length() - 2, script.length()); // chop off the extra ", " - script.append(");\n"); - script.append("writeProtectInputs(readOnlyInputArray);"); - } - - UIOutput uiOutput = FacesComponentUtility.addJavaScript(config, config, null, script); - String id = PropertyIdGeneratorUtility.getIdentifier(config.getConfiguration(), - INIT_INPUTS_JAVA_SCRIPT_COMPONENT_ID_SUFFIX); - uiOutput.setId(id); - } - - static List<String> getHtmlDomReferences(UIComponent component) { - List<String> htmlDomReferences = new ArrayList<String>(); - if (component instanceof HtmlSelectOneRadio) { - String clientId = component.getClientId(FacesContext.getCurrentInstance()); - int selectItemCount = 0; - for (UIComponent child : component.getChildren()) { - if (child instanceof UISelectItem) { - String selectItemClientId = clientId + NamingContainer.SEPARATOR_CHAR + selectItemCount++; - htmlDomReferences.add(getHtmlDomReference(selectItemClientId)); - } else { - throw new IllegalStateException( - "HtmlSelectOneRadio component has a child that is not a UISelectItem."); - } - } - } else { - String clientId = component.getClientId(FacesContext.getCurrentInstance()); - htmlDomReferences.add(getHtmlDomReference(clientId)); - } - - return htmlDomReferences; - } - - static String getHtmlDomReference(String clientId) { - return "document.getElementById('" + clientId + "')"; - } - </span><span class="cx"> private void validateAttributes(ConfigUIComponent config) { if (config.getValueExpression("configurationDefinition") == null) { throw new IllegalStateException("The " + config.getClass().getName() </span><span class="lines">@@ -477,4 +367,9 @@ </span><span class="cx"> FacesComponentUtility.addVerbatimText(component, msg); } } </span><span class="add">+ + private String getInitInputsJavaScriptComponentId(ConfigUIComponent configUIComponent) + { + return configUIComponent.getId() + INIT_INPUTS_JAVA_SCRIPT_COMPONENT_ID_SUFFIX; + } </span><span class="cx"> } \ No newline at end of file </span></pre></div> <a id="rhqtrunkmodulescoreguisrcmainjavaorgrhqcoreguiconfigurationCssStyleClassesjava"></a> <div class="addfile"><h4>Added: rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/CssStyleClasses.java (0 => 2855)</h4> <pre class="diff"> <span class="info">--- rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/CssStyleClasses.java (rev 0) +++ rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/CssStyleClasses.java 2009-01-31 00:38:24 UTC (rev 2855) </span><span class="lines">@@ -0,0 +1,41 @@ </span><span class="add">+/* + * RHQ Management Platform + * Copyright (C) 2005-2008 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +package org.rhq.core.gui.configuration; + +/** + * @author Ian Springer + */ +public class CssStyleClasses +{ + public static final String PROPERTIES_TABLE = "properties-table"; + public static final String MEMBER_PROPERTIES_TABLE = "member-properties-table"; + public static final String PROPERTIES_TABLE_HEADER_CELL = "properties-table-header-cell"; + public static final String PROPERTY_DISPLAY_NAME_TEXT = "property-display-name-text"; + public static final String DESCRIPTION = "description"; + public static final String REQUIRED_MARKER_TEXT = "required-marker-text"; + public static final String PROPERTY_DISPLAY_NAME_CELL = "property-display-name-cell"; + public static final String PROPERTY_VALUE_CELL = "property-value-cell"; + public static final String PROPERTY_DESCRIPTION_CELL = "property-description-cell"; + public static final String PROPERTY_ENABLED_CELL = "property-enabled-cell"; + public static final String PROPERTY_VALUE_INPUT = ""; + + private CssStyleClasses() + { + } +} </span><span class="cx">Property changes on: rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/CssStyleClasses.java ___________________________________________________________________ </span></pre></div> <a id="svnmimetype"></a> <div class="addfile"><h4>Added: svn:mime-type ( => )</h4> <pre class="diff"> <span class="info">Added: svn:keywords + Date Author Id Revision HeadURL </span></pre></div> <a id="svneolstyle"></a> <div class="addfile"><h4>Added: svn:eol-style ( => )</h4> <pre class="diff"> <span class="info"> Copied: rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/helper/PropertyRenderingUtility.java (from rev 2853, rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/helper/PropertySimpleRenderingUtility.java) </span><span class="cx">=================================================================== </span><span class="rem">--- rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/helper/PropertyRenderingUtility.java (rev 0) </span><span class="add">+++ rhq/trunk/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/helper/PropertyRenderingUtility.java 2009-01-31 00:38:24 UTC (rev 2855) </span><span class="lines">@@ -0,0 +1,488 @@ </span><span class="add">+/* + * RHQ Management Platform + * Copyright (C) 2005-2008 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +package org.rhq.core.gui.configuration.helper; + +import java.util.List; +import java.util.ArrayList; + +import javax.el.ValueExpression; +import javax.faces.component.UIInput; +import javax.faces.component.UISelectItem; +import javax.faces.component.UISelectOne; +import javax.faces.component.UIComponent; +import javax.faces.component.UIOutput; +import javax.faces.component.NamingContainer; +import javax.faces.component.html.HtmlInputSecret; +import javax.faces.component.html.HtmlInputText; +import javax.faces.component.html.HtmlInputTextarea; +import javax.faces.component.html.HtmlSelectOneMenu; +import javax.faces.component.html.HtmlSelectOneRadio; +import javax.faces.component.html.HtmlSelectBooleanCheckbox; +import javax.faces.context.FacesContext; +import javax.faces.validator.ValidatorException; +import javax.faces.application.FacesMessage; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionEnumeration; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; +import org.rhq.core.domain.configuration.definition.PropertyDefinition; +import org.rhq.core.gui.converter.PropertySimpleValueConverter; +import org.rhq.core.gui.util.FacesComponentUtility; +import org.rhq.core.gui.util.FacesExpressionUtility; +import org.rhq.core.gui.util.PropertyIdGeneratorUtility; +import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.core.gui.validator.PropertySimpleValueValidator; +import org.rhq.core.gui.configuration.CssStyleClasses; + +/** + * @author Ian Springer + */ +public class PropertyRenderingUtility +{ + private static final int INPUT_TEXT_COMPONENT_WIDTH = 30; + private static final int INPUT_TEXTAREA_COMPONENT_ROWS = 4; + private static final String ERROR_MSG_STYLE_CLASS = "error-msg"; + + /** + * Enums with a size equal to or greater than this threshold will be rendered as list boxes, rather than radios. + */ + private static final int LISTBOX_THRESHOLD_ENUM_SIZE = 6; + + @NotNull + public static UIInput createInputForSimpleProperty(PropertyDefinitionSimple propertyDefinitionSimple, + PropertySimple propertySimple, + ValueExpression propertyValueExpression, + Integer listIndex, + boolean readOnly, boolean prevalidate) { + UIInput input; + switch (propertyDefinitionSimple.getType()) { + case BOOLEAN: { + input = createInputForBooleanProperty(); + break; + } + + case LONG_STRING: { + input = createInputForLongStringProperty(); + break; + } + + case PASSWORD: { + input = createInputForPasswordProperty(); + break; + } + + default: { + if (isEnum(propertyDefinitionSimple)) { + input = createInputForEnumProperty(propertyDefinitionSimple); + } else { + input = createInputForStringProperty(); + } + // TODO (ips, 01/21/09): Figure out some way to do this for the propertySet component, where propertySimple will + // be null. Perhaps perform this logic in PropertySetRenderer.encodeEnd() after the UIInputs have been + // rendered. + if (propertySimple != null) + addTitleAttribute(input, propertySimple.getStringValue()); + } + } + + boolean isUnset = isUnset(propertyDefinitionSimple, propertySimple); + boolean isReadOnly = isReadOnly(propertyDefinitionSimple, propertySimple, readOnly); + + String propertyId = PropertyIdGeneratorUtility.getIdentifier(propertySimple, listIndex); + input.setId(propertyId); + + input.setValueExpression("value", propertyValueExpression); + + // It's important to set the label attribute, since we include it in our validation error messages. + input.getAttributes().put("label", propertyDefinitionSimple.getDisplayName()); + + // The below adds an inert attribute to the input that contains the name of the associated property - useful + // for debugging (i.e. when viewing source of the page or using a JavaScript debugger). + input.getAttributes().put("ondblclick", "//" + propertyDefinitionSimple.getName()); + + FacesComponentUtility.setUnset(input, isUnset); + FacesComponentUtility.setReadonly(input, isReadOnly); + + addValidatorsAndConverter(input, propertyDefinitionSimple, readOnly); + + addErrorMessages(input, propertyDefinitionSimple, propertySimple, prevalidate); + return input; + } + + @NotNull + public static UIInput createInputForSimpleProperty(PropertySimple propertySimple, String valueExpressionFormat, + boolean readOnly) { + UIInput input = createInputForStringProperty(); + setInputValueExpression(input, propertySimple.getName(), valueExpressionFormat); + FacesComponentUtility.setReadonly(input, readOnly); + addTitleAttribute(input, propertySimple.getStringValue()); + return input; + } + + public static void addMessageComponentForInput(UIComponent parent, UIInput input) { + // <h:message for="#{input-component-id}" showDetail="true" errorClass="error-msg" /> + FacesComponentUtility.addMessage(parent, null, input.getId(), ERROR_MSG_STYLE_CLASS); + // TODO: specify a component id + } + + public static HtmlSelectBooleanCheckbox addUnsetControl(UIComponent parent, + PropertyDefinitionSimple propertyDefinitionSimple, + PropertySimple propertySimple, + UIInput valueInput, boolean readOnlyConfig) { + HtmlSelectBooleanCheckbox unsetCheckbox = FacesComponentUtility.createComponent( + HtmlSelectBooleanCheckbox.class, null); + if (!propertyDefinitionSimple.isRequired()) { + parent.getChildren().add(unsetCheckbox); + unsetCheckbox.setValue(Boolean.valueOf(isUnset(propertyDefinitionSimple, propertySimple))); + if (isReadOnly(propertyDefinitionSimple, propertySimple, readOnlyConfig)) { + FacesComponentUtility.setDisabled(unsetCheckbox, true); + } else { + // Add JavaScript that will disable/enable the corresponding input element when the unset checkbox is + // checked/unchecked. + // IMPORTANT: We must use document.formName.inputName, rather than document.getElementById('inputId'), + // to reference the HTML DOM element, because the id of the HTML DOM input element is not the same as the + // id of the corresponding JSF input component in some cases (e.g. radio buttons). However, the + // name property that JSF renders on the HTML DOM input element does always match the JSF + // component id. (ips, 05/31/07) + StringBuilder onchange = new StringBuilder(); + for (String htmlDomReference : getHtmlDomReferences(valueInput)) { + onchange.append("setInputUnset(").append(htmlDomReference).append(", this.checked);"); + } + + unsetCheckbox.setOnchange(onchange.toString()); + } + } + return unsetCheckbox; + } + + public static void addInitInputsJavaScript(UIComponent parent, String componentId, boolean configFullyEditable, boolean postBack) { + List<UIInput> inputs = FacesComponentUtility.getDescendantsOfType(parent, UIInput.class); + List<UIInput> overrideInputs = new ArrayList<UIInput>(); + List<UIInput> unsetInputs = new ArrayList<UIInput>(); + List<UIInput> readOnlyInputs = new ArrayList<UIInput>(); + for (UIInput input : inputs) { + // readOnly components can not be overridden - by this point, the override + // status should have only been set if the component *was not* readOnly + //if (FacesComponentUtility.isOverride(input)) { + // overrideInputs.add(input); + //} + + if (postBack) { + boolean inputIsNull = PropertySimpleValueConverter.NULL_INPUT_VALUE.equals(input.getSubmittedValue()); + FacesComponentUtility.setUnset(input, inputIsNull); + } + if (FacesComponentUtility.isUnset(input)) { + unsetInputs.add(input); + } + + if (!configFullyEditable && FacesComponentUtility.isReadonly(input)) { + readOnlyInputs.add(input); + } + } + + StringBuilder script = new StringBuilder(); + + if (!overrideInputs.isEmpty()) { + script.append("var overrideInputArray = new Array("); + for (UIInput input : overrideInputs) { + for (String htmlDomReference : getHtmlDomReferences(input)) { + script.append(htmlDomReference).append(", "); + } + } + + script.delete(script.length() - 2, script.length()); // chop off the extra ", " + script.append(");\n"); + + // do it this way instead of DISABLED attribute via code, because if DISABLED is used and + // even if javascript later enables them, JSF won't submit them as part of the component + script.append("setInputsOverride(overrideInputArray, false);\n"); + } + + if (!unsetInputs.isEmpty()) { + script.append("var unsetInputArray = new Array("); + for (UIInput input : unsetInputs) { + for (String htmlDomReference : getHtmlDomReferences(input)) { + script.append(htmlDomReference).append(", "); + } + } + + script.delete(script.length() - 2, script.length()); // chop off the extra ", " + script.append(");\n"); + + // do it this way instead of DISABLED attribute via code, because if DISABLED is used and + // even if javascript later enables them, JSF won't submit them as part of the component + script.append("unsetInputs(unsetInputArray);\n"); + } + + if (!readOnlyInputs.isEmpty()) { + script.append("var readOnlyInputArray = new Array("); + for (UIInput input : readOnlyInputs) { + for (String htmlDomReference : getHtmlDomReferences(input)) { + script.append(htmlDomReference).append(", "); + } + } + + script.delete(script.length() - 2, script.length()); // chop off the extra ", " + script.append(");\n"); + script.append("writeProtectInputs(readOnlyInputArray);\n"); + } + + UIOutput uiOutput = FacesComponentUtility.addJavaScript(parent, null, null, script); + + uiOutput.setId(componentId); + } + + public static List<String> getHtmlDomReferences(UIComponent component) { + List<String> htmlDomReferences = new ArrayList<String>(); + if (component instanceof HtmlSelectOneRadio) { + String clientId = component.getClientId(FacesContext.getCurrentInstance()); + int selectItemCount = 0; + for (UIComponent child : component.getChildren()) { + if (child instanceof UISelectItem) { + String selectItemClientId = clientId + NamingContainer.SEPARATOR_CHAR + selectItemCount++; + htmlDomReferences.add(getHtmlDomReference(selectItemClientId)); + } else { + throw new IllegalStateException( + "HtmlSelectOneRadio component has a child that is not a UISelectItem."); + } + } + } else { + String clientId = component.getClientId(FacesContext.getCurrentInstance()); + htmlDomReferences.add(getHtmlDomReference(clientId)); + } + + return htmlDomReferences; + } + + // <h:outputLabel value="DISPLAY_NAME" styleClass="..." /> + public static void addPropertyDisplayName(UIComponent parent, PropertyDefinition propertyDefinition, + boolean configReadOnly) { + FacesComponentUtility.addOutputText(parent, null, propertyDefinition.getDisplayName(), + CssStyleClasses.PROPERTY_DISPLAY_NAME_TEXT); + if (!configReadOnly && propertyDefinition.isRequired() + && (propertyDefinition instanceof PropertyDefinitionSimple)) { + // Print a required marker next to required simples. + ... [truncated message content] |