/******************************************************************************* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*******************************************************************************/ | |
package org.ofbiz.widget.model; | |
import java.io.IOException; | |
import java.math.BigDecimal; | |
import java.sql.Timestamp; | |
import java.text.DateFormat; | |
import java.text.NumberFormat; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.Date; | |
import java.util.HashMap; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Locale; | |
import java.util.Map; | |
import java.util.StringTokenizer; | |
import java.util.TimeZone; | |
import org.ofbiz.base.conversion.ConversionException; | |
import org.ofbiz.base.conversion.DateTimeConverters; | |
import org.ofbiz.base.conversion.DateTimeConverters.StringToTimestamp; | |
import org.ofbiz.base.util.BshUtil; | |
import org.ofbiz.base.util.Debug; | |
import org.ofbiz.base.util.GeneralException; | |
import org.ofbiz.base.util.ObjectType; | |
import org.ofbiz.base.util.StringUtil; | |
import org.ofbiz.base.util.UtilCodec; | |
import org.ofbiz.base.util.UtilDateTime; | |
import org.ofbiz.base.util.UtilFormatOut; | |
import org.ofbiz.base.util.UtilGenerics; | |
import org.ofbiz.base.util.UtilMisc; | |
import org.ofbiz.base.util.UtilProperties; | |
import org.ofbiz.base.util.UtilValidate; | |
import org.ofbiz.base.util.UtilXml; | |
import org.ofbiz.base.util.collections.FlexibleMapAccessor; | |
import org.ofbiz.base.util.collections.MapStack; | |
import org.ofbiz.base.util.string.FlexibleStringExpander; | |
import org.ofbiz.entity.Delegator; | |
import org.ofbiz.entity.GenericEntity; | |
import org.ofbiz.entity.GenericEntityException; | |
import org.ofbiz.entity.GenericValue; | |
import org.ofbiz.entity.condition.EntityCondition; | |
import org.ofbiz.entity.finder.EntityFinderUtil; | |
import org.ofbiz.entity.model.ModelEntity; | |
import org.ofbiz.entity.util.EntityUtil; | |
import org.ofbiz.widget.WidgetWorker; | |
import org.ofbiz.widget.model.CommonWidgetModels.AutoEntityParameters; | |
import org.ofbiz.widget.model.CommonWidgetModels.AutoServiceParameters; | |
import org.ofbiz.widget.model.CommonWidgetModels.Image; | |
import org.ofbiz.widget.model.CommonWidgetModels.Link; | |
import org.ofbiz.widget.model.CommonWidgetModels.Parameter; | |
import org.ofbiz.widget.model.ModelForm.UpdateArea; | |
import org.ofbiz.widget.renderer.FormStringRenderer; | |
import org.w3c.dom.Element; | |
import bsh.EvalError; | |
import bsh.Interpreter; | |
/** | |
* Models the <field> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public class ModelFormField { | |
/* | |
* ----------------------------------------------------------------------- * | |
* DEVELOPERS PLEASE READ | |
* ----------------------------------------------------------------------- * | |
* | |
* This model is intended to be a read-only data structure that represents | |
* an XML element. Outside of object construction, the class should not | |
* have any behaviors. All behavior should be contained in model visitors. | |
* | |
* Instances of this class will be shared by multiple threads - therefore | |
* it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME! | |
* | |
*/ | |
public static final String module = ModelFormField.class.getName(); | |
public static ModelFormField from(ModelFormFieldBuilder builder) { | |
return new ModelFormField(builder); | |
} | |
private final FlexibleStringExpander action; | |
private final String attributeName; | |
private final boolean encodeOutput; | |
private final String entityName; | |
private final FlexibleMapAccessor<Object> entryAcsr; | |
private final String event; | |
private final FieldInfo fieldInfo; | |
private final String fieldName; | |
private final String headerLink; | |
private final String headerLinkStyle; | |
private final String idName; | |
private final FlexibleMapAccessor<Map<String, ? extends Object>> mapAcsr; | |
private final ModelForm modelForm; | |
private final String name; | |
private final List<UpdateArea> onChangeUpdateAreas; | |
private final List<UpdateArea> onClickUpdateAreas; | |
private final String parameterName; | |
private final Integer position; | |
private final String redWhen; | |
private final Boolean requiredField; | |
private final String requiredFieldStyle; | |
private final boolean separateColumn; | |
private final String serviceName; | |
private final Boolean sortField; | |
private final String sortFieldAscStyle; | |
private final String sortFieldDescStyle; | |
private final String sortFieldHelpText; | |
private final String sortFieldStyle; | |
private final FlexibleStringExpander title; | |
private final String titleAreaStyle; | |
private final String titleStyle; | |
private final FlexibleStringExpander tooltip; | |
private final String tooltipStyle; | |
private final FlexibleStringExpander useWhen; | |
private final String widgetAreaStyle; | |
private final String widgetStyle; | |
private ModelFormField(ModelFormFieldBuilder builder) { | |
this.action = builder.getAction(); | |
this.attributeName = builder.getAttributeName(); | |
this.encodeOutput = builder.getEncodeOutput(); | |
this.entityName = builder.getEntityName(); | |
this.entryAcsr = builder.getEntryAcsr(); | |
this.event = builder.getEvent(); | |
if (builder.getFieldInfo() != null) { | |
this.fieldInfo = builder.getFieldInfo().copy(this); | |
} else { | |
this.fieldInfo = null; | |
} | |
this.fieldName = builder.getFieldName(); | |
this.headerLink = builder.getHeaderLink(); | |
this.headerLinkStyle = builder.getHeaderLinkStyle(); | |
this.idName = builder.getIdName(); | |
this.mapAcsr = builder.getMapAcsr(); | |
this.modelForm = builder.getModelForm(); | |
this.name = builder.getName(); | |
if (builder.getOnChangeUpdateAreas().isEmpty()) { | |
this.onChangeUpdateAreas = Collections.emptyList(); | |
} else { | |
this.onChangeUpdateAreas = Collections.unmodifiableList(new ArrayList<UpdateArea>(builder.getOnChangeUpdateAreas())); | |
} | |
if (builder.getOnClickUpdateAreas().isEmpty()) { | |
this.onClickUpdateAreas = Collections.emptyList(); | |
} else { | |
this.onClickUpdateAreas = Collections.unmodifiableList(new ArrayList<UpdateArea>(builder.getOnClickUpdateAreas())); | |
} | |
this.parameterName = builder.getParameterName(); | |
this.position = builder.getPosition(); | |
this.redWhen = builder.getRedWhen(); | |
this.requiredField = builder.getRequiredField(); | |
this.requiredFieldStyle = builder.getRequiredFieldStyle(); | |
this.separateColumn = builder.getSeparateColumn(); | |
this.serviceName = builder.getServiceName(); | |
this.sortField = builder.getSortField(); | |
this.sortFieldAscStyle = builder.getSortFieldAscStyle(); | |
this.sortFieldDescStyle = builder.getSortFieldDescStyle(); | |
this.sortFieldHelpText = builder.getSortFieldHelpText(); | |
this.sortFieldStyle = builder.getSortFieldStyle(); | |
this.title = builder.getTitle(); | |
this.titleAreaStyle = builder.getTitleAreaStyle(); | |
this.titleStyle = builder.getTitleStyle(); | |
this.tooltip = builder.getTooltip(); | |
this.tooltipStyle = builder.getTooltipStyle(); | |
this.useWhen = builder.getUseWhen(); | |
this.widgetAreaStyle = builder.getWidgetAreaStyle(); | |
this.widgetStyle = builder.getWidgetStyle(); | |
} | |
public FlexibleStringExpander getAction() { | |
return action; | |
} | |
public String getAction(Map<String, ? extends Object> context) { | |
if (UtilValidate.isNotEmpty(this.action)) | |
return action.expandString(context); | |
return null; | |
} | |
/** | |
* Gets the name of the Service Attribute (aka Parameter) that corresponds | |
* with this field. This can be used to get additional information about the field. | |
* Use the getServiceName() method to get the Entity name that the field is in. | |
* | |
* @return returns the name of the Service Attribute | |
*/ | |
public String getAttributeName() { | |
if (UtilValidate.isNotEmpty(this.attributeName)) | |
return this.attributeName; | |
return this.name; | |
} | |
public String getCurrentContainerId(Map<String, Object> context) { | |
ModelForm modelForm = this.getModelForm(); | |
String idName = FlexibleStringExpander.expandString(this.getIdName(), context); | |
if (modelForm != null) { | |
Integer itemIndex = (Integer) context.get("itemIndex"); | |
if ("list".equals(modelForm.getType()) || "multi".equals(modelForm.getType())) { | |
if (itemIndex != null) { | |
return idName + modelForm.getItemIndexSeparator() + itemIndex.intValue(); | |
} | |
} | |
} | |
return idName; | |
} | |
public boolean getEncodeOutput() { | |
return this.encodeOutput; | |
} | |
public String getEntityName() { | |
if (UtilValidate.isNotEmpty(this.entityName)) | |
return this.entityName; | |
return this.modelForm.getDefaultEntityName(); | |
} | |
/** | |
* Gets the entry from the context that corresponds to this field; if this | |
* form is being rendered in an error condition (ie isError in the context | |
* is true) then the value will be retrieved from the parameters Map in | |
* the context. | |
* | |
* @param context the context | |
* @return returns the entry from the context that corresponds to this field | |
*/ | |
public String getEntry(Map<String, ? extends Object> context) { | |
return this.getEntry(context, ""); | |
} | |
public String getEntry(Map<String, ? extends Object> context, String defaultValue) { | |
Boolean isError = (Boolean) context.get("isError"); | |
Boolean useRequestParameters = (Boolean) context.get("useRequestParameters"); | |
Locale locale = (Locale) context.get("locale"); | |
if (locale == null) | |
locale = Locale.getDefault(); | |
TimeZone timeZone = (TimeZone) context.get("timeZone"); | |
if (timeZone == null) | |
timeZone = TimeZone.getDefault(); | |
String returnValue; | |
// if useRequestParameters is TRUE then parameters will always be used, if FALSE then parameters will never be used | |
// if isError is TRUE and useRequestParameters is not FALSE (ie is null or TRUE) then parameters will be used | |
if ((Boolean.TRUE.equals(isError) && !Boolean.FALSE.equals(useRequestParameters)) | |
|| (Boolean.TRUE.equals(useRequestParameters))) { | |
//Debug.logInfo("Getting entry, isError true so getting from parameters for field " + this.getName() + " of form " + this.modelForm.getName(), module); | |
Map<String, Object> parameters = UtilGenerics.checkMap(context.get("parameters"), String.class, Object.class); | |
String parameterName = this.getParameterName(context); | |
if (parameters != null && parameters.get(parameterName) != null) { | |
Object parameterValue = parameters.get(parameterName); | |
if (parameterValue instanceof String) { | |
returnValue = (String) parameterValue; | |
} else { | |
// we might want to do something else here in the future, but for now this is probably best | |
Debug.logWarning("Found a non-String parameter value for field [" + this.getModelForm().getName() + "." | |
+ this.getFieldName() + "]", module); | |
returnValue = defaultValue; | |
} | |
} else { | |
returnValue = defaultValue; | |
} | |
} else { | |
//Debug.logInfo("Getting entry, isError false so getting from Map in context for field " + this.getName() + " of form " + this.modelForm.getName(), module); | |
Map<String, ? extends Object> dataMap = this.getMap(context); | |
boolean dataMapIsContext = false; | |
if (dataMap == null) { | |
//Debug.logInfo("Getting entry, no Map found with name " + this.getMapName() + ", using context for field " + this.getName() + " of form " + this.modelForm.getName(), module); | |
dataMap = context; | |
dataMapIsContext = true; | |
} | |
Object retVal = null; | |
if (UtilValidate.isNotEmpty(this.entryAcsr)) { | |
if (dataMap instanceof GenericEntity) { | |
GenericEntity genEnt = (GenericEntity) dataMap; | |
if (genEnt.getModelEntity().isField(this.entryAcsr.getOriginalName())) { | |
retVal = genEnt.get(this.entryAcsr.getOriginalName(), locale); | |
} else { | |
//TODO: this may never come up, but if necessary use the FlexibleStringExander to eval the name first: String evaled = this.entryAcsr | |
} | |
} else { | |
retVal = this.entryAcsr.get(dataMap, locale); | |
} | |
} else { | |
// if no entry name was specified, use the field's name | |
if (dataMap.containsKey(this.name)) { | |
retVal = dataMap.get(this.name); | |
} | |
} | |
// this is a special case to fill in fields during a create by default from parameters passed in | |
if (dataMapIsContext && retVal == null && !Boolean.FALSE.equals(useRequestParameters)) { | |
Map<String, ? extends Object> parameters = UtilGenerics.checkMap(context.get("parameters")); | |
if (parameters != null) { | |
if (UtilValidate.isNotEmpty(this.entryAcsr)) | |
retVal = this.entryAcsr.get(parameters); | |
else | |
retVal = parameters.get(this.name); | |
} | |
} | |
if (retVal != null) { | |
// format string based on the user's locale and time zone | |
if (retVal instanceof Double || retVal instanceof Float || retVal instanceof BigDecimal) { | |
NumberFormat nf = NumberFormat.getInstance(locale); | |
nf.setMaximumFractionDigits(10); | |
return nf.format(retVal); | |
} else if (retVal instanceof java.sql.Date) { | |
DateFormat df = UtilDateTime.toDateFormat(UtilDateTime.DATE_FORMAT, timeZone, null); | |
return df.format((java.util.Date) retVal); | |
} else if (retVal instanceof java.sql.Time) { | |
DateFormat df = UtilDateTime.toTimeFormat(UtilDateTime.TIME_FORMAT, timeZone, null); | |
return df.format((java.util.Date) retVal); | |
} else if (retVal instanceof java.sql.Timestamp) { | |
DateFormat df = UtilDateTime.toDateTimeFormat(UtilDateTime.DATE_TIME_FORMAT, timeZone, null); | |
return df.format((java.util.Date) retVal); | |
} else if (retVal instanceof java.util.Date) { | |
DateFormat df = UtilDateTime.toDateTimeFormat("EEE MMM dd hh:mm:ss z yyyy", timeZone, null); | |
return df.format((java.util.Date) retVal); | |
} else { | |
returnValue = retVal.toString(); | |
} | |
} else { | |
returnValue = defaultValue; | |
} | |
} | |
if (this.getEncodeOutput() && returnValue != null) { | |
UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder"); | |
if (simpleEncoder != null) | |
returnValue = simpleEncoder.encode(returnValue); | |
} | |
return returnValue; | |
} | |
public FlexibleMapAccessor<Object> getEntryAcsr() { | |
return entryAcsr; | |
} | |
public String getEntryName() { | |
if (UtilValidate.isNotEmpty(this.entryAcsr)) | |
return this.entryAcsr.getOriginalName(); | |
return this.name; | |
} | |
public String getEvent() { | |
return event; | |
} | |
public FieldInfo getFieldInfo() { | |
return fieldInfo; | |
} | |
/** | |
* Gets the name of the Entity Field that corresponds | |
* with this field. This can be used to get additional information about the field. | |
* Use the getEntityName() method to get the Entity name that the field is in. | |
* | |
* @return return the name of the Entity Field that corresponds with this field | |
*/ | |
public String getFieldName() { | |
if (UtilValidate.isNotEmpty(this.fieldName)) | |
return this.fieldName; | |
return this.name; | |
} | |
public String getHeaderLink() { | |
return headerLink; | |
} | |
public String getHeaderLinkStyle() { | |
return headerLinkStyle; | |
} | |
public String getIdName() { | |
if (UtilValidate.isNotEmpty(idName)) | |
return idName; | |
return this.modelForm.getName() + "_" + this.getFieldName(); | |
} | |
public Map<String, ? extends Object> getMap(Map<String, ? extends Object> context) { | |
if (UtilValidate.isEmpty(this.mapAcsr)) | |
return this.modelForm.getDefaultMap(context); //Debug.logInfo("Getting Map from default of the form because of no mapAcsr for field " + this.getName(), module); | |
// Debug.logInfo("Getting Map from mapAcsr for field " + this.getName() + ", map-name=" + mapAcsr.getOriginalName() + ", context type=" + context.getClass().toString(), module); | |
Map<String, ? extends Object> result = null; | |
try { | |
result = mapAcsr.get(context); | |
} catch (java.lang.ClassCastException e) { | |
String errMsg = "Got an unexpected object type (not a Map) for map-name [" + mapAcsr.getOriginalName() | |
+ "] in field with name [" + this.getName() + "]: " + e.getMessage(); | |
Debug.logError(errMsg, module); | |
throw new ClassCastException(errMsg); | |
} | |
return result; | |
} | |
public FlexibleMapAccessor<Map<String, ? extends Object>> getMapAcsr() { | |
return mapAcsr; | |
} | |
/** Get the name of the Map in the form context that contains the entry, | |
* available from the getEntryName() method. This entry is used to | |
* pre-populate the field widget when not in an error condition. In an | |
* error condition the parameter name is used to get the value from the | |
* parameters Map. | |
* | |
* @return returns the name of the Map in the form context that contains the entry | |
*/ | |
public String getMapName() { | |
if (UtilValidate.isNotEmpty(this.mapAcsr)) | |
return this.mapAcsr.getOriginalName(); | |
return this.modelForm.getDefaultMapName(); | |
} | |
public ModelForm getModelForm() { | |
return modelForm; | |
} | |
public String getName() { | |
return name; | |
} | |
public List<UpdateArea> getOnChangeUpdateAreas() { | |
return onChangeUpdateAreas; | |
} | |
public List<UpdateArea> getOnClickUpdateAreas() { | |
return onClickUpdateAreas; | |
} | |
public String getParameterName() { | |
return parameterName; | |
} | |
/** | |
* Get the name to use for the parameter for this field in the form interpreter. | |
* For HTML forms this is the request parameter name. | |
* | |
* @return returns the name to use for the parameter for this field in the form interpreter | |
*/ | |
public String getParameterName(Map<String, ? extends Object> context) { | |
String baseName; | |
if (UtilValidate.isNotEmpty(this.parameterName)) | |
baseName = this.parameterName; | |
else | |
baseName = this.name; | |
Integer itemIndex = (Integer) context.get("itemIndex"); | |
if (itemIndex != null && "multi".equals(this.modelForm.getType())) { | |
return baseName + this.modelForm.getItemIndexSeparator() + itemIndex.intValue(); | |
} else { | |
return baseName; | |
} | |
} | |
public int getPosition() { | |
if (this.position == null) | |
return 1; | |
return position.intValue(); | |
} | |
public String getRedWhen() { | |
return redWhen; | |
} | |
public boolean getRequiredField() { | |
return this.requiredField != null ? this.requiredField : false; | |
} | |
public String getRequiredFieldStyle() { | |
if (UtilValidate.isNotEmpty(this.requiredFieldStyle)) | |
return this.requiredFieldStyle; | |
return this.modelForm.getDefaultRequiredFieldStyle(); | |
} | |
public boolean getSeparateColumn() { | |
return this.separateColumn; | |
} | |
public String getServiceName() { | |
if (UtilValidate.isNotEmpty(this.serviceName)) | |
return this.serviceName; | |
return this.modelForm.getDefaultServiceName(); | |
} | |
public Boolean getSortField() { | |
return sortField; | |
} | |
public String getSortFieldAscStyle() { | |
return sortFieldAscStyle; | |
} | |
public String getSortFieldDescStyle() { | |
return sortFieldDescStyle; | |
} | |
public String getSortFieldHelpText() { | |
return sortFieldHelpText; | |
} | |
public String getSortFieldHelpText(Map<String, Object> context) { | |
return FlexibleStringExpander.expandString(this.sortFieldHelpText, context); | |
} | |
public String getSortFieldStyle() { | |
if (UtilValidate.isNotEmpty(this.sortFieldStyle)) | |
return this.sortFieldStyle; | |
return this.modelForm.getDefaultSortFieldStyle(); | |
} | |
public String getSortFieldStyleAsc() { | |
if (UtilValidate.isNotEmpty(this.sortFieldAscStyle)) | |
return this.sortFieldAscStyle; | |
return this.modelForm.getDefaultSortFieldAscStyle(); | |
} | |
public String getSortFieldStyleDesc() { | |
if (UtilValidate.isNotEmpty(this.sortFieldDescStyle)) | |
return this.sortFieldDescStyle; | |
return this.modelForm.getDefaultSortFieldDescStyle(); | |
} | |
public FlexibleStringExpander getTitle() { | |
return title; | |
} | |
public String getTitle(Map<String, Object> context) { | |
if (UtilValidate.isNotEmpty(this.title)) | |
return title.expandString(context); | |
// create a title from the name of this field; expecting a Java method/field style name, ie productName or productCategoryId | |
if (UtilValidate.isEmpty(this.name)) | |
return ""; // this should never happen, ie name is required | |
// search for a localized label for the field's name | |
Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap")); | |
if (uiLabelMap != null) { | |
String titleFieldName = "FormFieldTitle_" + this.name; | |
String localizedName = uiLabelMap.get(titleFieldName); | |
if (!localizedName.equals(titleFieldName)) { | |
return localizedName; | |
} | |
} else { | |
Debug.logWarning("Could not find uiLabelMap in context while rendering form " + this.modelForm.getName(), module); | |
} | |
// create a title from the name of this field; expecting a Java method/field style name, ie productName or productCategoryId | |
StringBuilder autoTitlewriter = new StringBuilder(); | |
// always use upper case first letter... | |
autoTitlewriter.append(Character.toUpperCase(this.name.charAt(0))); | |
// just put spaces before the upper case letters | |
for (int i = 1; i < this.name.length(); i++) { | |
char curChar = this.name.charAt(i); | |
if (Character.isUpperCase(curChar)) { | |
autoTitlewriter.append(' '); | |
} | |
autoTitlewriter.append(curChar); | |
} | |
return autoTitlewriter.toString(); | |
} | |
public String getTitleAreaStyle() { | |
if (UtilValidate.isNotEmpty(this.titleAreaStyle)) | |
return this.titleAreaStyle; | |
return this.modelForm.getDefaultTitleAreaStyle(); | |
} | |
public String getTitleStyle() { | |
if (UtilValidate.isNotEmpty(this.titleStyle)) | |
return this.titleStyle; | |
return this.modelForm.getDefaultTitleStyle(); | |
} | |
public FlexibleStringExpander getTooltip() { | |
return tooltip; | |
} | |
public String getTooltip(Map<String, Object> context) { | |
String tooltipString = ""; | |
if (UtilValidate.isNotEmpty(tooltip)) | |
tooltipString = tooltip.expandString(context); | |
if (this.getEncodeOutput()) { | |
UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder"); | |
if (simpleEncoder != null) | |
tooltipString = simpleEncoder.encode(tooltipString); | |
} | |
return tooltipString; | |
} | |
public String getTooltipStyle() { | |
if (UtilValidate.isNotEmpty(this.tooltipStyle)) | |
return this.tooltipStyle; | |
return this.modelForm.getDefaultTooltipStyle(); | |
} | |
public FlexibleStringExpander getUseWhen() { | |
return useWhen; | |
} | |
public String getUseWhen(Map<String, Object> context) { | |
if (UtilValidate.isNotEmpty(this.useWhen)) | |
return this.useWhen.expandString(context); | |
return ""; | |
} | |
public String getWidgetAreaStyle() { | |
if (UtilValidate.isNotEmpty(this.widgetAreaStyle)) | |
return this.widgetAreaStyle; | |
return this.modelForm.getDefaultWidgetAreaStyle(); | |
} | |
public String getWidgetStyle() { | |
if (UtilValidate.isNotEmpty(this.widgetStyle)) | |
return this.widgetStyle; | |
return this.modelForm.getDefaultWidgetStyle(); | |
} | |
/** | |
* Checks if field is a row submit field. | |
*/ | |
public boolean isRowSubmit() { | |
if (!"multi".equals(getModelForm().getType())) | |
return false; | |
if (getFieldInfo().getFieldType() != FieldInfo.CHECK) | |
return false; | |
if (!CheckField.ROW_SUBMIT_FIELD_NAME.equals(getName())) | |
return false; | |
return true; | |
} | |
public boolean isSortField() { | |
return this.sortField != null && this.sortField.booleanValue(); | |
} | |
public boolean isUseWhenEmpty() { | |
if (this.useWhen == null) { | |
return true; | |
} | |
return this.useWhen.isEmpty(); | |
} | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
this.fieldInfo.renderFieldString(writer, context, formStringRenderer); | |
} | |
/** | |
* the widget/interaction part will be red if the date value is | |
* before-now (for ex. thruDate), after-now (for ex. fromDate), or by-name (if the | |
* field's name or entry-name or fromDate or thruDate the corresponding | |
* action will be done); only applicable when the field is a timestamp | |
* | |
* @param context the context | |
* @return true if the field should be read otherwise false | |
*/ | |
public boolean shouldBeRed(Map<String, Object> context) { | |
// red-when (never | before-now | after-now | by-name) "by-name" | |
String redCondition = this.redWhen; | |
if ("never".equals(redCondition)) | |
return false; | |
// for performance resaons we check this first, most fields will be eliminated here and the valueOfs will not be necessary | |
if (UtilValidate.isEmpty(redCondition) || "by-name".equals(redCondition)) { | |
if ("fromDate".equals(this.name) || (this.entryAcsr != null && "fromDate".equals(this.entryAcsr.getOriginalName()))) { | |
redCondition = "after-now"; | |
} else if ("thruDate".equals(this.name) | |
|| (this.entryAcsr != null && "thruDate".equals(this.entryAcsr.getOriginalName()))) { | |
redCondition = "before-now"; | |
} else { | |
return false; | |
} | |
} | |
boolean isBeforeNow = false; | |
if ("before-now".equals(redCondition)) { | |
isBeforeNow = true; | |
} else if ("after-now".equals(redCondition)) { | |
isBeforeNow = false; | |
} else { | |
return false; | |
} | |
java.sql.Date dateVal = null; | |
java.sql.Time timeVal = null; | |
java.sql.Timestamp timestampVal = null; | |
//now before going on, check to see if the current entry is a valid date and/or time and get the value | |
String value = this.getEntry(context, null); | |
try { | |
timestampVal = java.sql.Timestamp.valueOf(value); | |
} catch (Exception e) { | |
// okay, not a timestamp... | |
} | |
if (timestampVal == null) { | |
try { | |
dateVal = java.sql.Date.valueOf(value); | |
} catch (Exception e) { | |
// okay, not a date... | |
} | |
} | |
if (timestampVal == null && dateVal == null) { | |
try { | |
timeVal = java.sql.Time.valueOf(value); | |
} catch (Exception e) { | |
// okay, not a time... | |
} | |
} | |
if (timestampVal == null && dateVal == null && timeVal == null) { | |
return false; | |
} | |
long nowMillis = System.currentTimeMillis(); | |
if (timestampVal != null) { | |
java.sql.Timestamp nowStamp = new java.sql.Timestamp(nowMillis); | |
if (!timestampVal.equals(nowStamp)) { | |
if (isBeforeNow) { | |
if (timestampVal.before(nowStamp)) { | |
return true; | |
} | |
} else { | |
if (timestampVal.after(nowStamp)) { | |
return true; | |
} | |
} | |
} | |
} else if (dateVal != null) { | |
java.sql.Date nowDate = new java.sql.Date(nowMillis); | |
if (!dateVal.equals(nowDate)) { | |
if (isBeforeNow) { | |
if (dateVal.before(nowDate)) { | |
return true; | |
} | |
} else { | |
if (dateVal.after(nowDate)) { | |
return true; | |
} | |
} | |
} | |
} else if (timeVal != null) { | |
java.sql.Time nowTime = new java.sql.Time(nowMillis); | |
if (!timeVal.equals(nowTime)) { | |
if (isBeforeNow) { | |
if (timeVal.before(nowTime)) { | |
return true; | |
} | |
} else { | |
if (timeVal.after(nowTime)) { | |
return true; | |
} | |
} | |
} | |
} | |
return false; | |
} | |
public boolean shouldUse(Map<String, Object> context) { | |
String useWhenStr = this.getUseWhen(context); | |
if (UtilValidate.isEmpty(useWhenStr)) | |
return true; | |
try { | |
Interpreter bsh = this.modelForm.getBshInterpreter(context); | |
Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhenStr)); | |
boolean condTrue = false; | |
// retVal should be a Boolean, if not something weird is up... | |
if (retVal instanceof Boolean) { | |
Boolean boolVal = (Boolean) retVal; | |
condTrue = boolVal.booleanValue(); | |
} else { | |
throw new IllegalArgumentException("Return value from use-when condition eval was not a Boolean: " | |
+ (retVal != null ? retVal.getClass().getName() : "null") + " [" + retVal + "] on the field " + this.name | |
+ " of form " + this.modelForm.getName()); | |
} | |
return condTrue; | |
} catch (EvalError e) { | |
String errMsg = "Error evaluating BeanShell use-when condition [" + useWhenStr + "] on the field " + this.name | |
+ " of form " + this.modelForm.getName() + ": " + e.toString(); | |
Debug.logError(e, errMsg, module); | |
//Debug.logError("For use-when eval error context is: " + context, module); | |
throw new IllegalArgumentException(errMsg); | |
} | |
} | |
/** | |
* Models the <auto-complete> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class AutoComplete { | |
private final String autoSelect; | |
private final String choices; | |
private final String frequency; | |
private final String fullSearch; | |
private final String ignoreCase; | |
private final String minChars; | |
private final String partialChars; | |
private final String partialSearch; | |
public AutoComplete(Element element) { | |
this.autoSelect = element.getAttribute("auto-select"); | |
this.frequency = element.getAttribute("frequency"); | |
this.minChars = element.getAttribute("min-chars"); | |
this.choices = element.getAttribute("choices"); | |
this.partialSearch = element.getAttribute("partial-search"); | |
this.partialChars = element.getAttribute("partial-chars"); | |
this.ignoreCase = element.getAttribute("ignore-case"); | |
this.fullSearch = element.getAttribute("full-search"); | |
} | |
public String getAutoSelect() { | |
return this.autoSelect; | |
} | |
public String getChoices() { | |
return this.choices; | |
} | |
public String getFrequency() { | |
return this.frequency; | |
} | |
public String getFullSearch() { | |
return this.fullSearch; | |
} | |
public String getIgnoreCase() { | |
return this.ignoreCase; | |
} | |
public String getMinChars() { | |
return this.minChars; | |
} | |
public String getPartialChars() { | |
return this.partialChars; | |
} | |
public String getPartialSearch() { | |
return this.partialSearch; | |
} | |
} | |
/** | |
* Models the <check> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class CheckField extends FieldInfoWithOptions { | |
public final static String ROW_SUBMIT_FIELD_NAME = "_rowSubmit"; | |
private final FlexibleStringExpander allChecked; | |
private CheckField(CheckField original, ModelFormField modelFormField) { | |
super(original, modelFormField); | |
this.allChecked = original.allChecked; | |
} | |
public CheckField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
allChecked = FlexibleStringExpander.getInstance(element.getAttribute("all-checked")); | |
} | |
public CheckField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.CHECK, modelFormField); | |
this.allChecked = FlexibleStringExpander.getInstance(""); | |
} | |
public CheckField(ModelFormField modelFormField) { | |
super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.CHECK, modelFormField); | |
this.allChecked = FlexibleStringExpander.getInstance(""); | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new CheckField(this, modelFormField); | |
} | |
public FlexibleStringExpander getAllChecked() { | |
return allChecked; | |
} | |
public Boolean isAllChecked(Map<String, Object> context) { | |
String allCheckedStr = this.allChecked.expandString(context); | |
if (!allCheckedStr.isEmpty()) | |
return Boolean.valueOf("true".equals(allCheckedStr)); | |
else | |
return null; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderCheckField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <container> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class ContainerField extends FieldInfo { | |
private ContainerField(ContainerField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
} | |
public ContainerField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
} | |
public ContainerField(int fieldSource, int fieldType, ModelFormField modelFormField) { | |
super(fieldSource, fieldType, modelFormField); | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new ContainerField(this, modelFormField); | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderContainerFindField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <date-find> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class DateFindField extends DateTimeField { | |
private final String defaultOptionFrom; | |
private final String defaultOptionThru; | |
private DateFindField(DateFindField original, ModelFormField modelFormField) { | |
super(original, modelFormField); | |
this.defaultOptionFrom = original.defaultOptionFrom; | |
this.defaultOptionThru = original.defaultOptionThru; | |
} | |
public DateFindField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.defaultOptionFrom = element.getAttribute("default-option-from"); | |
this.defaultOptionThru = element.getAttribute("default-option-thru"); | |
} | |
public DateFindField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, modelFormField); | |
this.defaultOptionFrom = "greaterThanEqualTo"; | |
this.defaultOptionThru = "lessThanEqualTo"; | |
} | |
public DateFindField(int fieldSource, String type) { | |
super(fieldSource, type); | |
this.defaultOptionFrom = "greaterThanEqualTo"; | |
this.defaultOptionThru = "lessThanEqualTo"; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new DateFindField(this, modelFormField); | |
} | |
public String getDefaultOptionFrom() { | |
return this.defaultOptionFrom; | |
} | |
public String getDefaultOptionThru() { | |
return this.defaultOptionThru; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderDateFindField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <date-time> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class DateTimeField extends FieldInfo { | |
private final String clock; | |
private final FlexibleStringExpander defaultValue; | |
private final String inputMethod; | |
private final String mask; | |
private final String step; | |
private final String type; | |
protected DateTimeField(DateTimeField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
this.defaultValue = original.defaultValue; | |
this.type = original.type; | |
this.inputMethod = original.inputMethod; | |
this.clock = original.clock; | |
this.mask = original.mask; | |
this.step = original.step; | |
} | |
public DateTimeField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value")); | |
this.type = element.getAttribute("type"); | |
this.inputMethod = element.getAttribute("input-method"); | |
this.clock = element.getAttribute("clock"); | |
this.mask = element.getAttribute("mask"); | |
String step = element.getAttribute("step"); | |
if (step.isEmpty()) { | |
step = "1"; | |
} | |
this.step = step; | |
} | |
public DateTimeField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.DATE_TIME, modelFormField); | |
this.defaultValue = FlexibleStringExpander.getInstance(""); | |
this.type = ""; | |
this.inputMethod = ""; | |
this.clock = ""; | |
this.mask = ""; | |
this.step = "1"; | |
} | |
public DateTimeField(int fieldSource, String type) { | |
super(fieldSource, FieldInfo.DATE_TIME, null); | |
this.defaultValue = FlexibleStringExpander.getInstance(""); | |
this.type = type; | |
this.inputMethod = ""; | |
this.clock = ""; | |
this.mask = ""; | |
this.step = "1"; | |
} | |
public DateTimeField(ModelFormField modelFormField) { | |
super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DATE_TIME, modelFormField); | |
this.defaultValue = FlexibleStringExpander.getInstance(""); | |
this.type = ""; | |
this.inputMethod = ""; | |
this.clock = ""; | |
this.mask = ""; | |
this.step = "1"; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new DateTimeField(this, modelFormField); | |
} | |
public String getClock() { | |
return this.clock; | |
} | |
/** | |
* Returns the default-value if specified, otherwise the current date, time or timestamp | |
* | |
* @param context Context Map | |
* @return Default value string for date-time | |
*/ | |
public String getDefaultDateTimeString(Map<String, Object> context) { | |
if (UtilValidate.isNotEmpty(this.defaultValue)) | |
return this.getDefaultValue(context); | |
if ("date".equals(this.type)) | |
return (new java.sql.Date(System.currentTimeMillis())).toString(); | |
else if ("time".equals(this.type)) | |
return (new java.sql.Time(System.currentTimeMillis())).toString(); | |
else | |
return UtilDateTime.nowTimestamp().toString(); | |
} | |
public FlexibleStringExpander getDefaultValue() { | |
return defaultValue; | |
} | |
public String getDefaultValue(Map<String, Object> context) { | |
if (this.defaultValue != null) { | |
return this.defaultValue.expandString(context); | |
} else { | |
return ""; | |
} | |
} | |
public String getInputMethod() { | |
return this.inputMethod; | |
} | |
public String getMask() { | |
return this.mask; | |
} | |
public String getStep() { | |
return this.step; | |
} | |
public String getType() { | |
return type; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderDateTimeField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <display-entity> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class DisplayEntityField extends DisplayField { | |
private final boolean cache; | |
private final String entityName; | |
private final String keyFieldName; | |
private final SubHyperlink subHyperlink; | |
private DisplayEntityField(DisplayEntityField original, ModelFormField modelFormField) { | |
super(original, modelFormField); | |
this.cache = original.cache; | |
this.entityName = original.entityName; | |
this.keyFieldName = original.keyFieldName; | |
if (original.subHyperlink != null) { | |
this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField); | |
} else { | |
this.subHyperlink = null; | |
} | |
} | |
public DisplayEntityField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.cache = !"false".equals(element.getAttribute("cache")); | |
this.entityName = element.getAttribute("entity-name"); | |
this.keyFieldName = element.getAttribute("key-field-name"); | |
Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink"); | |
if (subHyperlinkElement != null) { | |
this.subHyperlink = new SubHyperlink(subHyperlinkElement, modelFormField); | |
} else { | |
this.subHyperlink = null; | |
} | |
} | |
public DisplayEntityField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.DISPLAY_ENTITY, modelFormField); | |
this.cache = true; | |
this.entityName = ""; | |
this.keyFieldName = ""; | |
this.subHyperlink = null; | |
} | |
public DisplayEntityField(ModelFormField modelFormField) { | |
super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DISPLAY_ENTITY, modelFormField); | |
this.cache = true; | |
this.entityName = ""; | |
this.keyFieldName = ""; | |
this.subHyperlink = null; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new DisplayEntityField(this, modelFormField); | |
} | |
public boolean getCache() { | |
return cache; | |
} | |
@Override | |
public String getDescription(Map<String, Object> context) { | |
Locale locale = UtilMisc.ensureLocale(context.get("locale")); | |
// rather than using the context to expand the string, lookup the given entity and use it to expand the string | |
GenericValue value = null; | |
String fieldKey = this.keyFieldName; | |
if (UtilValidate.isEmpty(fieldKey)) | |
fieldKey = getModelFormField().fieldName; | |
Delegator delegator = WidgetWorker.getDelegator(context); | |
String fieldValue = getModelFormField().getEntry(context); | |
try { | |
value = delegator.findOne(this.entityName, this.cache, fieldKey, fieldValue); | |
} catch (GenericEntityException e) { | |
String errMsg = "Error getting value from the database for display of field [" + getModelFormField().getName() | |
+ "] on form [" + getModelFormField().modelForm.getName() + "]: " + e.toString(); | |
Debug.logError(e, errMsg, module); | |
throw new IllegalArgumentException(errMsg); | |
} | |
String retVal = null; | |
if (value != null) { | |
// expanding ${} stuff, passing locale explicitly to expand value string because it won't be found in the Entity | |
MapStack<String> localContext = MapStack.create(context); | |
// Rendering code might try to modify the GenericEntity instance, | |
// so we make a copy of it. | |
Map<String, Object> genericEntityClone = UtilGenerics.cast(value.clone()); | |
localContext.push(genericEntityClone); | |
// expand with the new localContext, which is locale aware | |
retVal = this.getDescription().expandString(localContext, locale); | |
} | |
// try to get the entry for the field if description doesn't expand to anything | |
if (UtilValidate.isEmpty(retVal)) | |
retVal = fieldValue; | |
if (UtilValidate.isEmpty(retVal)) | |
retVal = ""; | |
return retVal; | |
} | |
public String getEntityName() { | |
return entityName; | |
} | |
public String getKeyFieldName() { | |
return keyFieldName; | |
} | |
public SubHyperlink getSubHyperlink() { | |
return this.subHyperlink; | |
} | |
} | |
/** | |
* Models the <display> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class DisplayField extends FieldInfo { | |
private final boolean alsoHidden; | |
private final FlexibleStringExpander currency; | |
private final FlexibleStringExpander date; | |
private final FlexibleStringExpander defaultValue; | |
private final FlexibleStringExpander description; | |
private final FlexibleStringExpander imageLocation; | |
private final InPlaceEditor inPlaceEditor; | |
private final String size; // maximum number of characters to display | |
private final String type; // matches type of field, currently text or currency | |
protected DisplayField(DisplayField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
this.alsoHidden = original.alsoHidden; | |
this.currency = original.currency; | |
this.date = original.date; | |
this.defaultValue = original.defaultValue; | |
this.description = original.description; | |
this.imageLocation = original.imageLocation; | |
this.inPlaceEditor = original.inPlaceEditor; | |
this.size = original.size; | |
this.type = original.type; | |
} | |
public DisplayField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.alsoHidden = !"false".equals(element.getAttribute("also-hidden")); | |
this.currency = FlexibleStringExpander.getInstance(element.getAttribute("currency")); | |
this.date = FlexibleStringExpander.getInstance(element.getAttribute("date")); | |
this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value")); | |
this.description = FlexibleStringExpander.getInstance(element.getAttribute("description")); | |
this.imageLocation = FlexibleStringExpander.getInstance(element.getAttribute("image-location")); | |
Element inPlaceEditorElement = UtilXml.firstChildElement(element, "in-place-editor"); | |
if (inPlaceEditorElement != null) { | |
this.inPlaceEditor = new InPlaceEditor(inPlaceEditorElement); | |
} else { | |
this.inPlaceEditor = null; | |
} | |
this.size = element.getAttribute("size"); | |
this.type = element.getAttribute("type"); | |
} | |
public DisplayField(int fieldSource, int fieldType, ModelFormField modelFormField) { | |
super(fieldSource, fieldType, modelFormField); | |
this.alsoHidden = true; | |
this.currency = FlexibleStringExpander.getInstance(""); | |
this.date = FlexibleStringExpander.getInstance(""); | |
this.defaultValue = FlexibleStringExpander.getInstance(""); | |
this.description = FlexibleStringExpander.getInstance(""); | |
this.imageLocation = FlexibleStringExpander.getInstance(""); | |
this.inPlaceEditor = null; | |
this.size = ""; | |
this.type = ""; | |
} | |
public DisplayField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.DISPLAY, modelFormField); | |
this.alsoHidden = true; | |
this.currency = FlexibleStringExpander.getInstance(""); | |
this.date = FlexibleStringExpander.getInstance(""); | |
this.defaultValue = FlexibleStringExpander.getInstance(""); | |
this.description = FlexibleStringExpander.getInstance(""); | |
this.imageLocation = FlexibleStringExpander.getInstance(""); | |
this.inPlaceEditor = null; | |
this.size = ""; | |
this.type = ""; | |
} | |
public DisplayField(ModelFormField modelFormField) { | |
super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DISPLAY, modelFormField); | |
this.alsoHidden = true; | |
this.currency = FlexibleStringExpander.getInstance(""); | |
this.date = FlexibleStringExpander.getInstance(""); | |
this.defaultValue = FlexibleStringExpander.getInstance(""); | |
this.description = FlexibleStringExpander.getInstance(""); | |
this.imageLocation = FlexibleStringExpander.getInstance(""); | |
this.inPlaceEditor = null; | |
this.size = ""; | |
this.type = ""; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new DisplayField(this, modelFormField); | |
} | |
public boolean getAlsoHidden() { | |
return alsoHidden; | |
} | |
public FlexibleStringExpander getCurrency() { | |
return currency; | |
} | |
public FlexibleStringExpander getDate() { | |
return date; | |
} | |
public FlexibleStringExpander getDefaultValue() { | |
return defaultValue; | |
} | |
public String getDefaultValue(Map<String, Object> context) { | |
if (this.defaultValue != null) { | |
return this.defaultValue.expandString(context); | |
} else { | |
return ""; | |
} | |
} | |
public FlexibleStringExpander getDescription() { | |
return description; | |
} | |
public String getDescription(Map<String, Object> context) { | |
String retVal = null; | |
if (UtilValidate.isNotEmpty(this.description)) | |
retVal = this.description.expandString(context); | |
else | |
retVal = getModelFormField().getEntry(context); | |
if (UtilValidate.isEmpty(retVal)) { | |
retVal = this.getDefaultValue(context); | |
} else if ("currency".equals(type)) { | |
retVal = retVal.replaceAll(" ", " "); // FIXME : encoding currency is a problem for some locale, we should not have any in retVal other case may arise in future... | |
Locale locale = (Locale) context.get("locale"); | |
if (locale == null) | |
locale = Locale.getDefault(); | |
String isoCode = null; | |
if (UtilValidate.isNotEmpty(this.currency)) | |
isoCode = this.currency.expandString(context); | |
try { | |
BigDecimal parsedRetVal = (BigDecimal) ObjectType.simpleTypeConvert(retVal, "BigDecimal", null, null, locale, | |
true); | |
retVal = UtilFormatOut.formatCurrency(parsedRetVal, isoCode, locale, 10); // we set the max to 10 digits as an hack to not round numbers in the ui | |
} catch (GeneralException e) { | |
String errMsg = "Error formatting currency value [" + retVal + "]: " + e.toString(); | |
Debug.logError(e, errMsg, module); | |
throw new IllegalArgumentException(errMsg); | |
} | |
} else if ("date".equals(this.type) && retVal.length() > 10) { | |
Locale locale = (Locale) context.get("locale"); | |
if (locale == null) { | |
locale = Locale.getDefault(); | |
} | |
StringToTimestamp stringToTimestamp = new DateTimeConverters.StringToTimestamp(); | |
Timestamp timestamp = null; | |
try { | |
timestamp = stringToTimestamp.convert(retVal); | |
Date date = new Date(timestamp.getTime()); | |
DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.SHORT, locale); | |
retVal = dateFormatter.format(date); | |
} catch (ConversionException e) { | |
String errMsg = "Error formatting date using default instead [" + retVal + "]: " + e.toString(); | |
Debug.logError(e, errMsg, module); | |
// create default date value from timestamp string | |
retVal = retVal.substring(0, 10); | |
} | |
} else if ("date-time".equals(this.type) && retVal.length() > 16) { | |
Locale locale = (Locale) context.get("locale"); | |
TimeZone timeZone = (TimeZone) context.get("timeZone"); | |
if (locale == null) { | |
locale = Locale.getDefault(); | |
} | |
if (timeZone == null) { | |
timeZone = TimeZone.getDefault(); | |
} | |
StringToTimestamp stringToTimestamp = new DateTimeConverters.StringToTimestamp(); | |
Timestamp timestamp = null; | |
try { | |
timestamp = stringToTimestamp.convert(retVal); | |
Date date = new Date(timestamp.getTime()); | |
DateFormat dateFormatter = UtilDateTime.toDateTimeFormat(null, timeZone, locale); | |
retVal = dateFormatter.format(date); | |
} catch (ConversionException e) { | |
String errMsg = "Error formatting date/time using default instead [" + retVal + "]: " + e.toString(); | |
Debug.logError(e, errMsg, module); | |
// create default date/time value from timestamp string | |
retVal = retVal.substring(0, 16); | |
} | |
} else if ("accounting-number".equals(this.type)) { | |
Locale locale = (Locale) context.get("locale"); | |
if (locale == null) { | |
locale = Locale.getDefault(); | |
} | |
try { | |
Double parsedRetVal = (Double) ObjectType.simpleTypeConvert(retVal, "Double", null, locale, false); | |
String template = UtilProperties.getPropertyValue("arithmetic", "accounting-number.format", | |
"#,##0.00;(#,##0.00)"); | |
retVal = UtilFormatOut.formatDecimalNumber(parsedRetVal.doubleValue(), template, locale); | |
} catch (GeneralException e) { | |
String errMsg = "Error formatting number [" + retVal + "]: " + e.toString(); | |
Debug.logError(e, errMsg, module); | |
throw new IllegalArgumentException(errMsg); | |
} | |
} | |
if (UtilValidate.isNotEmpty(this.description) && retVal != null && this.getModelFormField().getEncodeOutput()) { | |
UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder"); | |
if (simpleEncoder != null) { | |
retVal = simpleEncoder.encode(retVal); | |
} | |
} | |
return retVal; | |
} | |
public FlexibleStringExpander getImageLocation() { | |
return imageLocation; | |
} | |
public String getImageLocation(Map<String, Object> context) { | |
if (this.imageLocation != null) | |
return this.imageLocation.expandString(context); | |
return ""; | |
} | |
public InPlaceEditor getInPlaceEditor() { | |
return this.inPlaceEditor; | |
} | |
public String getSize() { | |
return this.size; | |
} | |
public String getType() { | |
return this.type; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderDisplayField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <drop-down> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class DropDownField extends FieldInfoWithOptions { | |
private final boolean allowEmpty; | |
private final boolean allowMulti; | |
private final AutoComplete autoComplete; | |
private final String current; | |
private final FlexibleStringExpander currentDescription; | |
private final int otherFieldSize; | |
private final String size; | |
private final SubHyperlink subHyperlink; | |
private final String textSize; | |
private DropDownField(DropDownField original, ModelFormField modelFormField) { | |
super(original, modelFormField); | |
this.allowEmpty = original.allowEmpty; | |
this.allowMulti = original.allowMulti; | |
this.autoComplete = original.autoComplete; | |
this.current = original.current; | |
this.currentDescription = original.currentDescription; | |
this.otherFieldSize = original.otherFieldSize; | |
this.size = original.size; | |
if (original.subHyperlink != null) { | |
this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField); | |
} else { | |
this.subHyperlink = null; | |
} | |
this.textSize = original.textSize; | |
} | |
public DropDownField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.allowEmpty = "true".equals(element.getAttribute("allow-empty")); | |
this.allowMulti = "true".equals(element.getAttribute("allow-multiple")); | |
Element autoCompleteElement = UtilXml.firstChildElement(element, "auto-complete"); | |
if (autoCompleteElement != null) { | |
this.autoComplete = new AutoComplete(autoCompleteElement); | |
} else { | |
this.autoComplete = null; | |
} | |
this.current = element.getAttribute("current"); | |
this.currentDescription = FlexibleStringExpander.getInstance(element.getAttribute("current-description")); | |
int otherFieldSize = 0; | |
String sizeStr = element.getAttribute("other-field-size"); | |
if (!sizeStr.isEmpty()) { | |
try { | |
otherFieldSize = Integer.parseInt(sizeStr); | |
} catch (Exception e) { | |
Debug.logError("Could not parse the size value of the text element: [" + sizeStr | |
+ "], setting to the default of 0", module); | |
} | |
} | |
this.otherFieldSize = otherFieldSize; | |
String size = element.getAttribute("size"); | |
if (size.isEmpty()) { | |
size = "1"; | |
} | |
this.size = size; | |
Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink"); | |
if (subHyperlinkElement != null) { | |
this.subHyperlink = new SubHyperlink(subHyperlinkElement, this.getModelFormField()); | |
} else { | |
this.subHyperlink = null; | |
} | |
String textSize = element.getAttribute("text-size"); | |
if (textSize.isEmpty()) { | |
textSize = "0"; | |
} | |
this.textSize = textSize; | |
} | |
public DropDownField(int fieldSource, List<OptionSource> optionSources) { | |
super(fieldSource, FieldInfo.DROP_DOWN, optionSources); | |
this.allowEmpty = false; | |
this.allowMulti = false; | |
this.autoComplete = null; | |
this.current = ""; | |
this.currentDescription = FlexibleStringExpander.getInstance(""); | |
this.otherFieldSize = 0; | |
this.size = "1"; | |
this.subHyperlink = null; | |
this.textSize = "0"; | |
} | |
public DropDownField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.DROP_DOWN, modelFormField); | |
this.allowEmpty = false; | |
this.allowMulti = false; | |
this.autoComplete = null; | |
this.current = ""; | |
this.currentDescription = FlexibleStringExpander.getInstance(""); | |
this.otherFieldSize = 0; | |
this.size = "1"; | |
this.subHyperlink = null; | |
this.textSize = "0"; | |
} | |
public DropDownField(ModelFormField modelFormField) { | |
super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DROP_DOWN, modelFormField); | |
this.allowEmpty = false; | |
this.allowMulti = false; | |
this.autoComplete = null; | |
this.current = ""; | |
this.currentDescription = FlexibleStringExpander.getInstance(""); | |
this.otherFieldSize = 0; | |
this.size = "1"; | |
this.subHyperlink = null; | |
this.textSize = "0"; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new DropDownField(this, modelFormField); | |
} | |
public boolean getAllowMulti() { | |
return allowMulti; | |
} | |
public AutoComplete getAutoComplete() { | |
return this.autoComplete; | |
} | |
public String getCurrent() { | |
if (UtilValidate.isEmpty(this.current)) | |
return "first-in-list"; | |
return this.current; | |
} | |
public FlexibleStringExpander getCurrentDescription() { | |
return currentDescription; | |
} | |
public String getCurrentDescription(Map<String, Object> context) { | |
if (this.currentDescription == null) | |
return null; | |
return this.currentDescription.expandString(context); | |
} | |
public int getOtherFieldSize() { | |
return this.otherFieldSize; | |
} | |
/** | |
* Get the name to use for the parameter for this field in the form interpreter. | |
* For HTML forms this is the request parameter name. | |
* @param context the context | |
* @return returns the name to use for the parameter for this field in the form interpreter. | |
*/ | |
public String getParameterNameOther(Map<String, Object> context) { | |
String baseName; | |
if (UtilValidate.isNotEmpty(getModelFormField().parameterName)) | |
baseName = getModelFormField().parameterName; | |
else | |
baseName = getModelFormField().name; | |
baseName += "_OTHER"; | |
Integer itemIndex = (Integer) context.get("itemIndex"); | |
if (itemIndex != null && "multi".equals(getModelFormField().modelForm.getType())) { | |
return baseName + getModelFormField().modelForm.getItemIndexSeparator() + itemIndex.intValue(); | |
} else { | |
return baseName; | |
} | |
} | |
public String getSize() { | |
return this.size; | |
} | |
public SubHyperlink getSubHyperlink() { | |
return this.subHyperlink; | |
} | |
public String getTextSize() { | |
return this.textSize; | |
} | |
public boolean getAllowEmpty() { | |
return this.allowEmpty; | |
} | |
public boolean getAllowMultiple() { | |
return this.allowMulti; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderDropDownField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <entity-options> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class EntityOptions extends OptionSource { | |
private final boolean cache; | |
private final List<EntityFinderUtil.ConditionExpr> constraintList; | |
private final FlexibleStringExpander description; | |
private final String entityName; | |
private final String filterByDate; | |
private final String keyFieldName; | |
private final List<String> orderByList; | |
public EntityOptions(Element entityOptionsElement, ModelFormField modelFormField) { | |
super(modelFormField); | |
this.cache = !"false".equals(entityOptionsElement.getAttribute("cache")); | |
List<? extends Element> constraintElements = UtilXml.childElementList(entityOptionsElement, "entity-constraint"); | |
if (!constraintElements.isEmpty()) { | |
List<EntityFinderUtil.ConditionExpr> constraintList = new ArrayList<EntityFinderUtil.ConditionExpr>( | |
constraintElements.size()); | |
for (Element constraintElement : constraintElements) { | |
constraintList.add(new EntityFinderUtil.ConditionExpr(constraintElement)); | |
} | |
this.constraintList = Collections.unmodifiableList(constraintList); | |
} else { | |
this.constraintList = Collections.emptyList(); | |
} | |
this.description = FlexibleStringExpander.getInstance(entityOptionsElement.getAttribute("description")); | |
this.entityName = entityOptionsElement.getAttribute("entity-name"); | |
this.filterByDate = entityOptionsElement.getAttribute("filter-by-date"); | |
this.keyFieldName = entityOptionsElement.getAttribute("key-field-name"); | |
List<? extends Element> orderByElements = UtilXml.childElementList(entityOptionsElement, "entity-order-by"); | |
if (!orderByElements.isEmpty()) { | |
List<String> orderByList = new ArrayList<String>(orderByElements.size()); | |
for (Element orderByElement : orderByElements) { | |
orderByList.add(orderByElement.getAttribute("field-name")); | |
} | |
this.orderByList = Collections.unmodifiableList(orderByList); | |
} else { | |
this.orderByList = Collections.emptyList(); | |
} | |
} | |
private EntityOptions(EntityOptions original, ModelFormField modelFormField) { | |
super(modelFormField); | |
this.cache = original.cache; | |
this.constraintList = original.constraintList; | |
this.description = original.description; | |
this.entityName = original.entityName; | |
this.filterByDate = original.filterByDate; | |
this.keyFieldName = original.keyFieldName; | |
this.orderByList = original.orderByList; | |
} | |
public EntityOptions(ModelFormField modelFormField) { | |
super(modelFormField); | |
this.cache = true; | |
this.constraintList = Collections.emptyList(); | |
this.description = FlexibleStringExpander.getInstance(""); | |
this.entityName = ""; | |
this.filterByDate = ""; | |
this.keyFieldName = ""; | |
this.orderByList = Collections.emptyList(); | |
} | |
@Override | |
public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) { | |
// first expand any conditions that need expanding based on the current context | |
EntityCondition findCondition = null; | |
if (UtilValidate.isNotEmpty(this.constraintList)) { | |
List<EntityCondition> expandedConditionList = new LinkedList<EntityCondition>(); | |
for (EntityFinderUtil.Condition condition : constraintList) { | |
ModelEntity modelEntity = delegator.getModelEntity(this.entityName); | |
if (modelEntity == null) { | |
throw new IllegalArgumentException("Error in entity-options: could not find entity [" + this.entityName | |
+ "]"); | |
} | |
EntityCondition createdCondition = condition.createCondition(context, modelEntity, | |
delegator.getModelFieldTypeReader(modelEntity)); | |
if (createdCondition != null) { | |
expandedConditionList.add(createdCondition); | |
} | |
} | |
findCondition = EntityCondition.makeCondition(expandedConditionList); | |
} | |
try { | |
Locale locale = UtilMisc.ensureLocale(context.get("locale")); | |
List<GenericValue> values = null; | |
values = delegator.findList(this.entityName, findCondition, null, this.orderByList, null, this.cache); | |
// filter-by-date if requested | |
if ("true".equals(this.filterByDate)) { | |
values = EntityUtil.filterByDate(values, true); | |
} else if (!"false".equals(this.filterByDate)) { | |
// not explicitly true or false, check to see if has fromDate and thruDate, if so do the filter | |
ModelEntity modelEntity = delegator.getModelEntity(this.entityName); | |
if (modelEntity != null && modelEntity.isField("fromDate") && modelEntity.isField("thruDate")) { | |
values = EntityUtil.filterByDate(values, true); | |
} | |
} | |
for (GenericValue value : values) { | |
// add key and description with string expansion, ie expanding ${} stuff, passing locale explicitly to expand value string because it won't be found in the Entity | |
MapStack<String> localContext = MapStack.create(context); | |
// Rendering code might try to modify the GenericEntity instance, | |
// so we make a copy of it. | |
Map<String, Object> genericEntityClone = UtilGenerics.cast(value.clone()); | |
localContext.push(genericEntityClone); | |
// expand with the new localContext, which is locale aware | |
String optionDesc = this.description.expandString(localContext, locale); | |
Object keyFieldObject = value.get(this.getKeyFieldName()); | |
if (keyFieldObject == null) { | |
throw new IllegalArgumentException( | |
"The entity-options identifier (from key-name attribute, or default to the field name) [" | |
+ this.getKeyFieldName() + "], may not be a valid key field name for the entity [" | |
+ this.entityName + "]."); | |
} | |
String keyFieldValue = keyFieldObject.toString(); | |
optionValues.add(new OptionValue(keyFieldValue, optionDesc)); | |
} | |
} catch (GenericEntityException e) { | |
Debug.logError(e, "Error getting entity options in form", module); | |
} | |
} | |
@Override | |
public OptionSource copy(ModelFormField modelFormField) { | |
return new EntityOptions(this, modelFormField); | |
} | |
public boolean getCache() { | |
return cache; | |
} | |
public List<EntityFinderUtil.ConditionExpr> getConstraintList() { | |
return constraintList; | |
} | |
public FlexibleStringExpander getDescription() { | |
return description; | |
} | |
public String getEntityName() { | |
return entityName; | |
} | |
public String getFilterByDate() { | |
return filterByDate; | |
} | |
public String getKeyFieldName() { | |
if (UtilValidate.isNotEmpty(this.keyFieldName)) | |
return this.keyFieldName; | |
return getModelFormField().getFieldName(); // get the modelFormField fieldName | |
} | |
public List<String> getOrderByList() { | |
return orderByList; | |
} | |
} | |
public static abstract class FieldInfoWithOptions extends FieldInfo { | |
public static String getDescriptionForOptionKey(String key, List<OptionValue> allOptionValues) { | |
if (UtilValidate.isEmpty(key)) | |
return ""; | |
if (UtilValidate.isEmpty(allOptionValues)) | |
return key; | |
for (OptionValue optionValue : allOptionValues) { | |
if (key.equals(optionValue.getKey())) { | |
return optionValue.getDescription(); | |
} | |
} | |
// if we get here we didn't find a match, just return the key | |
return key; | |
} | |
private final FlexibleStringExpander noCurrentSelectedKey; | |
private final List<OptionSource> optionSources; | |
public FieldInfoWithOptions(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.noCurrentSelectedKey = FlexibleStringExpander.getInstance(element.getAttribute("no-current-selected-key")); | |
// read all option and entity-options sub-elements, maintaining order | |
ArrayList<OptionSource> optionSources = new ArrayList<OptionSource>(); | |
List<? extends Element> childElements = UtilXml.childElementList(element); | |
if (childElements.size() > 0) { | |
for (Element childElement : childElements) { | |
if ("option".equals(childElement.getTagName())) { | |
optionSources.add(new SingleOption(childElement, modelFormField)); | |
} else if ("list-options".equals(childElement.getTagName())) { | |
optionSources.add(new ListOptions(childElement, modelFormField)); | |
} else if ("entity-options".equals(childElement.getTagName())) { | |
optionSources.add(new EntityOptions(childElement, modelFormField)); | |
} | |
} | |
} else { | |
// this must be added or the multi-form select box options would not show up | |
optionSources.add(new SingleOption("Y", " ", modelFormField)); | |
} | |
optionSources.trimToSize(); | |
this.optionSources = Collections.unmodifiableList(optionSources); | |
} | |
// Copy constructor. | |
protected FieldInfoWithOptions(FieldInfoWithOptions original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
this.noCurrentSelectedKey = original.noCurrentSelectedKey; | |
if (original.optionSources.isEmpty()) { | |
this.optionSources = original.optionSources; | |
} else { | |
List<OptionSource> optionSources = new ArrayList<OptionSource>(original.optionSources.size()); | |
for (OptionSource source : original.optionSources) { | |
optionSources.add(source.copy(modelFormField)); | |
} | |
this.optionSources = Collections.unmodifiableList(optionSources); | |
} | |
} | |
protected FieldInfoWithOptions(int fieldSource, int fieldType, List<OptionSource> optionSources) { | |
super(fieldSource, fieldType, null); | |
this.noCurrentSelectedKey = FlexibleStringExpander.getInstance(""); | |
this.optionSources = Collections.unmodifiableList(new ArrayList<OptionSource>(optionSources)); | |
} | |
public FieldInfoWithOptions(int fieldSource, int fieldType, ModelFormField modelFormField) { | |
super(fieldSource, fieldType, modelFormField); | |
this.noCurrentSelectedKey = FlexibleStringExpander.getInstance(""); | |
this.optionSources = Collections.emptyList(); | |
} | |
public List<OptionValue> getAllOptionValues(Map<String, Object> context, Delegator delegator) { | |
List<OptionValue> optionValues = new LinkedList<OptionValue>(); | |
for (OptionSource optionSource : this.optionSources) { | |
optionSource.addOptionValues(optionValues, context, delegator); | |
} | |
return optionValues; | |
} | |
public FlexibleStringExpander getNoCurrentSelectedKey() { | |
return noCurrentSelectedKey; | |
} | |
public String getNoCurrentSelectedKey(Map<String, Object> context) { | |
return this.noCurrentSelectedKey.expandString(context); | |
} | |
public List<OptionSource> getOptionSources() { | |
return optionSources; | |
} | |
} | |
/** | |
* Models the <file> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class FileField extends TextField { | |
public FileField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
} | |
private FileField(FileField original, ModelFormField modelFormField) { | |
super(original, modelFormField); | |
} | |
public FileField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, modelFormField); | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new FileField(this, modelFormField); | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderFileField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <hidden> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class HiddenField extends FieldInfo { | |
private final FlexibleStringExpander value; | |
public HiddenField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.value = FlexibleStringExpander.getInstance(element.getAttribute("value")); | |
} | |
private HiddenField(HiddenField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
this.value = original.value; | |
} | |
public HiddenField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.HIDDEN, modelFormField); | |
this.value = FlexibleStringExpander.getInstance(""); | |
} | |
public HiddenField(ModelFormField modelFormField) { | |
super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.HIDDEN, modelFormField); | |
this.value = FlexibleStringExpander.getInstance(""); | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new HiddenField(this, modelFormField); | |
} | |
public FlexibleStringExpander getValue() { | |
return value; | |
} | |
public String getValue(Map<String, Object> context) { | |
if (UtilValidate.isNotEmpty(this.value)) { | |
String valueEnc = this.value.expandString(context); | |
UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder"); | |
if (simpleEncoder != null) { | |
valueEnc = simpleEncoder.encode(valueEnc); | |
} | |
return valueEnc; | |
} else { | |
return getModelFormField().getEntry(context); | |
} | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderHiddenField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <hyperlink> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class HyperlinkField extends FieldInfo { | |
private final boolean alsoHidden; | |
private final FlexibleStringExpander confirmationMsgExdr; | |
private final FlexibleStringExpander description; | |
private final boolean requestConfirmation; | |
private final Link link; | |
public HyperlinkField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.alsoHidden = !"false".equals(element.getAttribute("also-hidden")); | |
this.confirmationMsgExdr = FlexibleStringExpander.getInstance(element.getAttribute("confirmation-message")); | |
this.description = FlexibleStringExpander.getInstance(element.getAttribute("description")); | |
this.requestConfirmation = "true".equals(element.getAttribute("request-confirmation")); | |
// Backwards-compatible fix | |
element.setAttribute("url-mode", element.getAttribute("target-type")); | |
this.link = new Link(element); | |
} | |
private HyperlinkField(HyperlinkField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
this.alsoHidden = original.alsoHidden; | |
this.confirmationMsgExdr = original.confirmationMsgExdr; | |
this.description = original.description; | |
this.requestConfirmation = original.requestConfirmation; | |
this.link = original.link; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new HyperlinkField(this, modelFormField); | |
} | |
public boolean getAlsoHidden() { | |
return this.alsoHidden; | |
} | |
public String getConfirmation(Map<String, Object> context) { | |
String message = getConfirmationMsg(context); | |
if (UtilValidate.isNotEmpty(message)) | |
return message; | |
if (getRequestConfirmation()) { | |
String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message", | |
"${uiLabelMap.CommonConfirm}"); | |
return FlexibleStringExpander.expandString(defaultMessage, context); | |
} | |
return ""; | |
} | |
public String getAlternate(Map<String, Object> context) { | |
if (link.getImage() != null) { | |
return link.getImage().getAlt(context); | |
} | |
return ""; | |
} | |
public String getImageTitle(Map<String, Object> context) { | |
if (link.getImage() != null) { | |
return link.getImage().getTitleExdr().expandString(context); | |
} | |
return ""; | |
} | |
public String getImageLocation(Map<String, Object> context) { | |
if (link.getImage() != null) { | |
return link.getImage().getSrc(context); | |
} | |
return ""; | |
} | |
public String getConfirmationMsg(Map<String, Object> context) { | |
return this.confirmationMsgExdr.expandString(context); | |
} | |
public FlexibleStringExpander getConfirmationMsgExdr() { | |
return confirmationMsgExdr; | |
} | |
public FlexibleStringExpander getDescription() { | |
return description; | |
} | |
public String getDescription(Map<String, Object> context) { | |
return this.description.expandString(context); | |
} | |
public boolean getRequestConfirmation() { | |
return this.requestConfirmation; | |
} | |
public Link getLink() { | |
return link; | |
} | |
public AutoEntityParameters getAutoEntityParameters() { | |
return link.getAutoEntityParameters(); | |
} | |
public AutoServiceParameters getAutoServiceParameters() { | |
return link.getAutoServiceParameters(); | |
} | |
public boolean getEncode() { | |
return link.getEncode(); | |
} | |
public boolean getFullPath() { | |
return link.getFullPath(); | |
} | |
public String getHeight() { | |
return link.getHeight(); | |
} | |
public String getId(Map<String, Object> context) { | |
return link.getId(context); | |
} | |
public FlexibleStringExpander getIdExdr() { | |
return link.getIdExdr(); | |
} | |
public Image getImage() { | |
return link.getImage(); | |
} | |
public String getLinkType() { | |
return link.getLinkType(); | |
} | |
public String getName() { | |
return link.getName(); | |
} | |
public String getName(Map<String, Object> context) { | |
return link.getName(context); | |
} | |
public FlexibleStringExpander getNameExdr() { | |
return link.getNameExdr(); | |
} | |
public List<Parameter> getParameterList() { | |
return link.getParameterList(); | |
} | |
public Map<String, String> getParameterMap(Map<String, Object> context) { | |
return link.getParameterMap(context); | |
} | |
public String getPrefix(Map<String, Object> context) { | |
return link.getPrefix(context); | |
} | |
public FlexibleStringExpander getPrefixExdr() { | |
return link.getPrefixExdr(); | |
} | |
public boolean getSecure() { | |
return link.getSecure(); | |
} | |
public Integer getSize() { | |
return link.getSize(); | |
} | |
public String getStyle(Map<String, Object> context) { | |
return link.getStyle(context); | |
} | |
public FlexibleStringExpander getStyleExdr() { | |
return link.getStyleExdr(); | |
} | |
public String getTarget(Map<String, Object> context) { | |
return link.getTarget(context); | |
} | |
public FlexibleStringExpander getTargetExdr() { | |
return link.getTargetExdr(); | |
} | |
public String getTargetWindow(Map<String, Object> context) { | |
return link.getTargetWindow(context); | |
} | |
public FlexibleStringExpander getTargetWindowExdr() { | |
return link.getTargetWindowExdr(); | |
} | |
public String getText(Map<String, Object> context) { | |
return link.getText(context); | |
} | |
public FlexibleStringExpander getTextExdr() { | |
return link.getTextExdr(); | |
} | |
public String getUrlMode() { | |
return link.getUrlMode(); | |
} | |
public String getWidth() { | |
return link.getWidth(); | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderHyperlinkField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <ignored> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class IgnoredField extends FieldInfo { | |
public IgnoredField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
} | |
private IgnoredField(IgnoredField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
} | |
public IgnoredField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.IGNORED, modelFormField); | |
} | |
public IgnoredField(ModelFormField modelFormField) { | |
super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.IGNORED, modelFormField); | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new IgnoredField(this, modelFormField); | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderIgnoredField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <image> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class ImageField extends FieldInfo { | |
private final FlexibleStringExpander alternate; | |
private final FlexibleStringExpander defaultValue; | |
private final FlexibleStringExpander description; | |
private final FlexibleStringExpander style; | |
private final SubHyperlink subHyperlink; | |
private final FlexibleStringExpander value; | |
public ImageField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.alternate = FlexibleStringExpander.getInstance(element.getAttribute("alternate")); | |
this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value")); | |
this.description = FlexibleStringExpander.getInstance(element.getAttribute("description")); | |
this.style = FlexibleStringExpander.getInstance(element.getAttribute("style")); | |
Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink"); | |
if (subHyperlinkElement != null) { | |
this.subHyperlink = new SubHyperlink(subHyperlinkElement, modelFormField); | |
} else { | |
this.subHyperlink = null; | |
} | |
this.value = FlexibleStringExpander.getInstance(element.getAttribute("value")); | |
} | |
public ImageField(ImageField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
this.alternate = original.alternate; | |
this.defaultValue = original.defaultValue; | |
this.description = original.description; | |
this.style = original.style; | |
if (original.subHyperlink != null) { | |
this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField); | |
} else { | |
this.subHyperlink = null; | |
} | |
this.value = original.value; | |
} | |
public ImageField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.IMAGE, modelFormField); | |
this.alternate = FlexibleStringExpander.getInstance(""); | |
this.defaultValue = FlexibleStringExpander.getInstance(""); | |
this.description = FlexibleStringExpander.getInstance(""); | |
this.style = FlexibleStringExpander.getInstance(""); | |
this.subHyperlink = null; | |
this.value = FlexibleStringExpander.getInstance(""); | |
} | |
public ImageField(ModelFormField modelFormField) { | |
this(FieldInfo.SOURCE_EXPLICIT, modelFormField); | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new ImageField(this, modelFormField); | |
} | |
public FlexibleStringExpander getAlternate() { | |
return alternate; | |
} | |
public String getAlternate(Map<String, Object> context) { | |
if (UtilValidate.isNotEmpty(this.alternate)) | |
return this.alternate.expandString(context); | |
return ""; | |
} | |
public FlexibleStringExpander getDefaultValue() { | |
return defaultValue; | |
} | |
public String getDefaultValue(Map<String, Object> context) { | |
if (this.defaultValue != null) { | |
return this.defaultValue.expandString(context); | |
} else { | |
return ""; | |
} | |
} | |
public FlexibleStringExpander getDescription() { | |
return description; | |
} | |
public String getDescription(Map<String, Object> context) { | |
if (UtilValidate.isNotEmpty(this.description)) | |
return this.description.expandString(context); | |
return ""; | |
} | |
public FlexibleStringExpander getStyle() { | |
return style; | |
} | |
public String getStyle(Map<String, Object> context) { | |
if (UtilValidate.isNotEmpty(this.style)) | |
return this.style.expandString(context); | |
return ""; | |
} | |
public SubHyperlink getSubHyperlink() { | |
return this.subHyperlink; | |
} | |
public FlexibleStringExpander getValue() { | |
return value; | |
} | |
public String getValue(Map<String, Object> context) { | |
if (UtilValidate.isNotEmpty(this.value)) | |
return this.value.expandString(context); | |
return getModelFormField().getEntry(context); | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderImageField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <in-place-editor> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class InPlaceEditor { | |
private final String cancelControl; | |
private final String cancelText; | |
private final String clickToEditText; | |
private final String cols; | |
private final Map<FlexibleMapAccessor<Object>, Object> fieldMap; | |
private final String fieldPostCreation; | |
private final String formClassName; | |
private final String highlightColor; | |
private final String highlightEndColor; | |
private final String hoverClassName; | |
private final String htmlResponse; | |
private final String loadingClassName; | |
private final String loadingText; | |
private final String okControl; | |
private final String okText; | |
private final String paramName; | |
private final String rows; | |
private final String savingClassName; | |
private final String savingText; | |
private final String submitOnBlur; | |
private final String textAfterControls; | |
private final String textBeforeControls; | |
private final String textBetweenControls; | |
private final String updateAfterRequestCall; | |
private final FlexibleStringExpander url; | |
public InPlaceEditor(Element element) { | |
this.cancelControl = element.getAttribute("cancel-control"); | |
this.cancelText = element.getAttribute("cancel-text"); | |
this.clickToEditText = element.getAttribute("click-to-edit-text"); | |
this.fieldPostCreation = element.getAttribute("field-post-creation"); | |
this.formClassName = element.getAttribute("form-class-name"); | |
this.highlightColor = element.getAttribute("highlight-color"); | |
this.highlightEndColor = element.getAttribute("highlight-end-color"); | |
this.hoverClassName = element.getAttribute("hover-class-name"); | |
this.htmlResponse = element.getAttribute("html-response"); | |
this.loadingClassName = element.getAttribute("loading-class-name"); | |
this.loadingText = element.getAttribute("loading-text"); | |
this.okControl = element.getAttribute("ok-control"); | |
this.okText = element.getAttribute("ok-text"); | |
this.paramName = element.getAttribute("param-name"); | |
this.savingClassName = element.getAttribute("saving-class-name"); | |
this.savingText = element.getAttribute("saving-text"); | |
this.submitOnBlur = element.getAttribute("submit-on-blur"); | |
this.textBeforeControls = element.getAttribute("text-before-controls"); | |
this.textAfterControls = element.getAttribute("text-after-controls"); | |
this.textBetweenControls = element.getAttribute("text-between-controls"); | |
this.updateAfterRequestCall = element.getAttribute("update-after-request-call"); | |
Element simpleElement = UtilXml.firstChildElement(element, "simple-editor"); | |
if (simpleElement != null) { | |
this.rows = simpleElement.getAttribute("rows"); | |
this.cols = simpleElement.getAttribute("cols"); | |
} else { | |
this.rows = ""; | |
this.cols = ""; | |
} | |
this.fieldMap = EntityFinderUtil.makeFieldMap(element); | |
this.url = FlexibleStringExpander.getInstance(element.getAttribute("url")); | |
} | |
public String getCancelControl() { | |
return this.cancelControl; | |
} | |
public String getCancelText() { | |
return this.cancelText; | |
} | |
public String getClickToEditText() { | |
return this.clickToEditText; | |
} | |
public String getCols() { | |
return this.cols; | |
} | |
public Map<FlexibleMapAccessor<Object>, Object> getFieldMap() { | |
return fieldMap; | |
} | |
public Map<String, Object> getFieldMap(Map<String, Object> context) { | |
Map<String, Object> inPlaceEditorContext = new HashMap<String, Object>(); | |
EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, inPlaceEditorContext); | |
return inPlaceEditorContext; | |
} | |
public String getFieldPostCreation() { | |
return this.fieldPostCreation; | |
} | |
public String getFormClassName() { | |
return this.formClassName; | |
} | |
public String getHighlightColor() { | |
return this.highlightColor; | |
} | |
public String getHighlightEndColor() { | |
return this.highlightEndColor; | |
} | |
public String getHoverClassName() { | |
return this.hoverClassName; | |
} | |
public String getHtmlResponse() { | |
return this.htmlResponse; | |
} | |
public String getLoadingClassName() { | |
return this.loadingClassName; | |
} | |
public String getLoadingText() { | |
return this.loadingText; | |
} | |
public String getOkControl() { | |
return this.okControl; | |
} | |
public String getOkText() { | |
return this.okText; | |
} | |
public String getParamName() { | |
return this.paramName; | |
} | |
public String getRows() { | |
return this.rows; | |
} | |
public String getSavingClassName() { | |
return this.savingClassName; | |
} | |
public String getSavingText() { | |
return this.savingText; | |
} | |
public String getSubmitOnBlur() { | |
return this.submitOnBlur; | |
} | |
public String getTextAfterControls() { | |
return this.textAfterControls; | |
} | |
public String getTextBeforeControls() { | |
return this.textBeforeControls; | |
} | |
public String getTextBetweenControls() { | |
return this.textBetweenControls; | |
} | |
public String getUpdateAfterRequestCall() { | |
return this.updateAfterRequestCall; | |
} | |
public FlexibleStringExpander getUrl() { | |
return url; | |
} | |
public String getUrl(Map<String, Object> context) { | |
if (this.url != null) { | |
return this.url.expandString(context); | |
} else { | |
return ""; | |
} | |
} | |
} | |
/** | |
* Models the <list-options> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class ListOptions extends OptionSource { | |
private final FlexibleStringExpander description; | |
private final FlexibleMapAccessor<Object> keyAcsr; | |
private final FlexibleMapAccessor<List<? extends Object>> listAcsr; | |
private final String listEntryName; | |
public ListOptions(Element optionElement, ModelFormField modelFormField) { | |
super(modelFormField); | |
this.listEntryName = optionElement.getAttribute("list-entry-name"); | |
this.keyAcsr = FlexibleMapAccessor.getInstance(optionElement.getAttribute("key-name")); | |
this.listAcsr = FlexibleMapAccessor.getInstance(optionElement.getAttribute("list-name")); | |
this.description = FlexibleStringExpander.getInstance(optionElement.getAttribute("description")); | |
} | |
private ListOptions(ListOptions original, ModelFormField modelFormField) { | |
super(modelFormField); | |
this.listAcsr = original.listAcsr; | |
this.listEntryName = original.listEntryName; | |
this.keyAcsr = original.keyAcsr; | |
this.description = original.description; | |
} | |
public ListOptions(String listName, String listEntryName, String keyName, String description, | |
ModelFormField modelFormField) { | |
super(modelFormField); | |
this.listAcsr = FlexibleMapAccessor.getInstance(listName); | |
this.listEntryName = listEntryName; | |
this.keyAcsr = FlexibleMapAccessor.getInstance(keyName); | |
this.description = FlexibleStringExpander.getInstance(description); | |
} | |
@Override | |
public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) { | |
List<? extends Object> dataList = UtilGenerics.checkList(this.listAcsr.get(context)); | |
if (dataList != null && dataList.size() != 0) { | |
for (Object data : dataList) { | |
Map<String, Object> localContext = new HashMap<String, Object>(); | |
localContext.putAll(context); | |
if (UtilValidate.isNotEmpty(this.listEntryName)) { | |
localContext.put(this.listEntryName, data); | |
} else { | |
Map<String, Object> dataMap = UtilGenerics.checkMap(data); | |
localContext.putAll(dataMap); | |
} | |
Object keyObj = keyAcsr.get(localContext); | |
String key = null; | |
if (keyObj instanceof String) { | |
key = (String) keyObj; | |
} else { | |
try { | |
key = (String) ObjectType.simpleTypeConvert(keyObj, "String", null, null); | |
} catch (GeneralException e) { | |
String errMsg = "Could not convert field value for the field: [" + this.keyAcsr.toString() | |
+ "] to String for the value [" + keyObj + "]: " + e.toString(); | |
Debug.logError(e, errMsg, module); | |
} | |
} | |
optionValues.add(new OptionValue(key, description.expandString(localContext))); | |
} | |
} | |
} | |
@Override | |
public OptionSource copy(ModelFormField modelFormField) { | |
return new ListOptions(this, modelFormField); | |
} | |
public FlexibleStringExpander getDescription() { | |
return description; | |
} | |
public FlexibleMapAccessor<Object> getKeyAcsr() { | |
return keyAcsr; | |
} | |
public FlexibleMapAccessor<List<? extends Object>> getListAcsr() { | |
return listAcsr; | |
} | |
public String getListEntryName() { | |
return listEntryName; | |
} | |
} | |
/** | |
* Models the <lookup> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class LookupField extends TextField { | |
private final String descriptionFieldName; | |
private final String fadeBackground; | |
private final FlexibleStringExpander formName; | |
private final String initiallyCollapsed; | |
private final String lookupHeight; | |
private final String lookupPosition; | |
private final String lookupPresentation; | |
private final String lookupWidth; | |
private final String showDescription; | |
private final String targetParameter; | |
public LookupField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.descriptionFieldName = element.getAttribute("description-field-name"); | |
this.fadeBackground = element.getAttribute("fade-background"); | |
this.formName = FlexibleStringExpander.getInstance(element.getAttribute("target-form-name")); | |
this.initiallyCollapsed = element.getAttribute("initially-collapsed"); | |
this.lookupHeight = element.getAttribute("height"); | |
this.lookupPosition = element.getAttribute("position"); | |
this.lookupPresentation = element.getAttribute("presentation"); | |
this.lookupWidth = element.getAttribute("width"); | |
this.showDescription = element.getAttribute("show-description"); | |
this.targetParameter = element.getAttribute("target-parameter"); | |
} | |
public LookupField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, modelFormField); | |
this.descriptionFieldName = ""; | |
this.fadeBackground = ""; | |
this.formName = FlexibleStringExpander.getInstance(""); | |
this.initiallyCollapsed = ""; | |
this.lookupHeight = ""; | |
this.lookupPosition = ""; | |
this.lookupPresentation = ""; | |
this.lookupWidth = ""; | |
this.showDescription = ""; | |
this.targetParameter = ""; | |
} | |
public LookupField(LookupField original, ModelFormField modelFormField) { | |
super(original, modelFormField); | |
this.descriptionFieldName = original.descriptionFieldName; | |
this.fadeBackground = original.fadeBackground; | |
this.formName = original.formName; | |
this.initiallyCollapsed = original.initiallyCollapsed; | |
this.lookupHeight = original.lookupHeight; | |
this.lookupPosition = original.lookupPosition; | |
this.lookupPresentation = original.lookupPresentation; | |
this.lookupWidth = original.lookupWidth; | |
this.showDescription = original.showDescription; | |
this.targetParameter = original.targetParameter; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new LookupField(this, modelFormField); | |
} | |
public String getDescriptionFieldName() { | |
return this.descriptionFieldName; | |
} | |
public String getFadeBackground() { | |
return this.fadeBackground; | |
} | |
public FlexibleStringExpander getFormName() { | |
return formName; | |
} | |
public String getFormName(Map<String, Object> context) { | |
return this.formName.expandString(context); | |
} | |
//initially-collapsed status | |
public boolean getInitiallyCollapsed() { | |
return "true".equals(this.initiallyCollapsed); | |
} | |
public String getLookupHeight() { | |
return this.lookupHeight; | |
} | |
public String getLookupPosition() { | |
return this.lookupPosition; | |
} | |
public String getLookupPresentation() { | |
return this.lookupPresentation; | |
} | |
public String getLookupWidth() { | |
return this.lookupWidth; | |
} | |
public Boolean getShowDescription() { | |
return UtilValidate.isEmpty(this.showDescription) ? null : "true".equals(this.showDescription); | |
} | |
public String getTargetParameter() { | |
return targetParameter; | |
} | |
public List<String> getTargetParameterList() { | |
List<String> paramList = new LinkedList<String>(); | |
if (UtilValidate.isNotEmpty(this.targetParameter)) { | |
StringTokenizer stk = new StringTokenizer(this.targetParameter, ", "); | |
while (stk.hasMoreTokens()) { | |
paramList.add(stk.nextToken()); | |
} | |
} | |
return paramList; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderLookupField(writer, context, this); | |
} | |
} | |
public static abstract class OptionSource { | |
private final ModelFormField modelFormField; | |
protected OptionSource(ModelFormField modelFormField) { | |
this.modelFormField = modelFormField; | |
} | |
public abstract void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator); | |
public abstract OptionSource copy(ModelFormField modelFormField); | |
public ModelFormField getModelFormField() { | |
return modelFormField; | |
} | |
} | |
public static class OptionValue { | |
private final String description; | |
private final String key; | |
public OptionValue(String key, String description) { | |
this.key = key; | |
this.description = description; | |
} | |
public String getDescription() { | |
return description; | |
} | |
public String getKey() { | |
return key; | |
} | |
} | |
/** | |
* Models the <password> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class PasswordField extends TextField { | |
public PasswordField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
} | |
public PasswordField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, modelFormField); | |
} | |
private PasswordField(PasswordField original, ModelFormField modelFormField) { | |
super(original, modelFormField); | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new PasswordField(this, modelFormField); | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderPasswordField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <radio> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class RadioField extends FieldInfoWithOptions { | |
public RadioField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
} | |
public RadioField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.RADIO, modelFormField); | |
} | |
public RadioField(ModelFormField modelFormField) { | |
super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.RADIO, modelFormField); | |
} | |
private RadioField(RadioField original, ModelFormField modelFormField) { | |
super(original, modelFormField); | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new RadioField(this, modelFormField); | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderRadioField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <range-find> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class RangeFindField extends TextField { | |
private final String defaultOptionFrom; | |
private final String defaultOptionThru; | |
public RangeFindField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.defaultOptionFrom = element.getAttribute("default-option-from"); | |
this.defaultOptionThru = element.getAttribute("default-option-thru"); | |
} | |
public RangeFindField(int fieldSource, int size, ModelFormField modelFormField) { | |
super(fieldSource, size, null, modelFormField); | |
this.defaultOptionFrom = "greaterThanEqualTo"; | |
this.defaultOptionThru = "lessThanEqualTo"; | |
} | |
private RangeFindField(RangeFindField original, ModelFormField modelFormField) { | |
super(original, modelFormField); | |
this.defaultOptionFrom = original.defaultOptionFrom; | |
this.defaultOptionThru = original.defaultOptionThru; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new RangeFindField(this, modelFormField); | |
} | |
public String getDefaultOptionFrom() { | |
return this.defaultOptionFrom; | |
} | |
public String getDefaultOptionThru() { | |
return this.defaultOptionThru; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderRangeFindField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <reset> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class ResetField extends FieldInfo { | |
public ResetField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
} | |
public ResetField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.RESET, modelFormField); | |
} | |
public ResetField(ModelFormField modelFormField) { | |
super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.RESET, modelFormField); | |
} | |
private ResetField(ResetField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new ResetField(this, modelFormField); | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderResetField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <option> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class SingleOption extends OptionSource { | |
private final FlexibleStringExpander description; | |
private final FlexibleStringExpander key; | |
public SingleOption(Element optionElement, ModelFormField modelFormField) { | |
super(modelFormField); | |
this.key = FlexibleStringExpander.getInstance(optionElement.getAttribute("key")); | |
this.description = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(optionElement.getAttribute("description"), | |
optionElement.getAttribute("key"))); | |
} | |
private SingleOption(SingleOption original, ModelFormField modelFormField) { | |
super(modelFormField); | |
this.key = original.key; | |
this.description = original.description; | |
} | |
public SingleOption(String key, String description, ModelFormField modelFormField) { | |
super(modelFormField); | |
this.key = FlexibleStringExpander.getInstance(key); | |
this.description = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(description, key)); | |
} | |
@Override | |
public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) { | |
optionValues.add(new OptionValue(key.expandString(context), description.expandString(context))); | |
} | |
@Override | |
public OptionSource copy(ModelFormField modelFormField) { | |
return new SingleOption(this, modelFormField); | |
} | |
public FlexibleStringExpander getDescription() { | |
return description; | |
} | |
public FlexibleStringExpander getKey() { | |
return key; | |
} | |
} | |
/** | |
* Models the <sub-hyperlink> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class SubHyperlink { | |
private final FlexibleStringExpander description; | |
private final FlexibleStringExpander useWhen; | |
private final Link link; | |
private final ModelFormField modelFormField; | |
public SubHyperlink(Element element, ModelFormField modelFormField) { | |
this.description = FlexibleStringExpander.getInstance(element.getAttribute("description")); | |
this.useWhen = FlexibleStringExpander.getInstance(element.getAttribute("use-when")); | |
// Backwards compatible support | |
element.setAttribute("style", element.getAttribute("link-style")); | |
element.setAttribute("url-mode", element.getAttribute("target-type")); | |
this.link = new Link(element); | |
this.modelFormField = modelFormField; | |
} | |
public SubHyperlink(SubHyperlink original, ModelFormField modelFormField) { | |
this.description = original.description; | |
this.useWhen = original.useWhen; | |
this.link = original.link; | |
this.modelFormField = modelFormField; | |
} | |
public AutoEntityParameters getAutoEntityParameters() { | |
return link.getAutoEntityParameters(); | |
} | |
public AutoServiceParameters getAutoServiceParameters() { | |
return link.getAutoServiceParameters(); | |
} | |
public boolean getEncode() { | |
return link.getEncode(); | |
} | |
public boolean getFullPath() { | |
return link.getFullPath(); | |
} | |
public String getHeight() { | |
return link.getHeight(); | |
} | |
public String getId(Map<String, Object> context) { | |
return link.getId(context); | |
} | |
public FlexibleStringExpander getIdExdr() { | |
return link.getIdExdr(); | |
} | |
public Image getImage() { | |
return link.getImage(); | |
} | |
public String getLinkType() { | |
return link.getLinkType(); | |
} | |
public String getName() { | |
return link.getName(); | |
} | |
public String getName(Map<String, Object> context) { | |
return link.getName(context); | |
} | |
public FlexibleStringExpander getNameExdr() { | |
return link.getNameExdr(); | |
} | |
public List<Parameter> getParameterList() { | |
return link.getParameterList(); | |
} | |
public Map<String, String> getParameterMap(Map<String, Object> context) { | |
return link.getParameterMap(context); | |
} | |
public String getPrefix(Map<String, Object> context) { | |
return link.getPrefix(context); | |
} | |
public FlexibleStringExpander getPrefixExdr() { | |
return link.getPrefixExdr(); | |
} | |
public boolean getSecure() { | |
return link.getSecure(); | |
} | |
public Integer getSize() { | |
return link.getSize(); | |
} | |
public String getStyle(Map<String, Object> context) { | |
return link.getStyle(context); | |
} | |
public FlexibleStringExpander getStyleExdr() { | |
return link.getStyleExdr(); | |
} | |
public String getTarget(Map<String, Object> context) { | |
return link.getTarget(context); | |
} | |
public FlexibleStringExpander getTargetExdr() { | |
return link.getTargetExdr(); | |
} | |
public String getTargetWindow(Map<String, Object> context) { | |
return link.getTargetWindow(context); | |
} | |
public FlexibleStringExpander getTargetWindowExdr() { | |
return link.getTargetWindowExdr(); | |
} | |
public String getText(Map<String, Object> context) { | |
return link.getText(context); | |
} | |
public FlexibleStringExpander getTextExdr() { | |
return link.getTextExdr(); | |
} | |
public String getUrlMode() { | |
return link.getUrlMode(); | |
} | |
public String getWidth() { | |
return link.getWidth(); | |
} | |
public FlexibleStringExpander getDescription() { | |
return description; | |
} | |
public String getDescription(Map<String, Object> context) { | |
return description.expandString(context); | |
} | |
public FlexibleStringExpander getUseWhen() { | |
return useWhen; | |
} | |
public Link getLink() { | |
return link; | |
} | |
public String getUseWhen(Map<String, Object> context) { | |
return this.useWhen.expandString(context); | |
} | |
public ModelFormField getModelFormField() { | |
return modelFormField; | |
} | |
public boolean shouldUse(Map<String, Object> context) { | |
boolean shouldUse = true; | |
String useWhen = this.getUseWhen(context); | |
if (UtilValidate.isNotEmpty(useWhen)) { | |
try { | |
Interpreter bsh = (Interpreter) context.get("bshInterpreter"); | |
if (bsh == null) { | |
bsh = BshUtil.makeInterpreter(context); | |
context.put("bshInterpreter", bsh); | |
} | |
Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhen)); | |
// retVal should be a Boolean, if not something weird is up... | |
if (retVal instanceof Boolean) { | |
Boolean boolVal = (Boolean) retVal; | |
shouldUse = boolVal.booleanValue(); | |
} else { | |
throw new IllegalArgumentException("Return value from target condition eval was not a Boolean: " | |
+ retVal.getClass().getName() + " [" + retVal + "]"); | |
} | |
} catch (EvalError e) { | |
String errmsg = "Error evaluating BeanShell target conditions"; | |
Debug.logError(e, errmsg, module); | |
throw new IllegalArgumentException(errmsg); | |
} | |
} | |
return shouldUse; | |
} | |
} | |
/** | |
* Models the <submit> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class SubmitField extends FieldInfo { | |
private final FlexibleStringExpander backgroundSubmitRefreshTargetExdr; | |
private final String buttonType; | |
private final FlexibleStringExpander confirmationMsgExdr; | |
private final FlexibleStringExpander imageLocation; | |
private final boolean requestConfirmation; | |
public SubmitField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.backgroundSubmitRefreshTargetExdr = FlexibleStringExpander.getInstance(element | |
.getAttribute("background-submit-refresh-target")); | |
this.buttonType = element.getAttribute("button-type"); | |
this.confirmationMsgExdr = FlexibleStringExpander.getInstance(element.getAttribute("confirmation-message")); | |
this.imageLocation = FlexibleStringExpander.getInstance(element.getAttribute("image-location")); | |
this.requestConfirmation = "true".equals(element.getAttribute("request-confirmation")); | |
} | |
public SubmitField(int fieldInfo, ModelFormField modelFormField) { | |
super(fieldInfo, FieldInfo.SUBMIT, modelFormField); | |
this.backgroundSubmitRefreshTargetExdr = FlexibleStringExpander.getInstance(""); | |
this.buttonType = ""; | |
this.confirmationMsgExdr = FlexibleStringExpander.getInstance(""); | |
this.imageLocation = FlexibleStringExpander.getInstance(""); | |
this.requestConfirmation = false; | |
} | |
public SubmitField(ModelFormField modelFormField) { | |
this(FieldInfo.SOURCE_EXPLICIT, modelFormField); | |
} | |
private SubmitField(SubmitField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
this.buttonType = original.buttonType; | |
this.imageLocation = original.imageLocation; | |
this.backgroundSubmitRefreshTargetExdr = original.backgroundSubmitRefreshTargetExdr; | |
this.requestConfirmation = original.requestConfirmation; | |
this.confirmationMsgExdr = original.confirmationMsgExdr; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new SubmitField(this, modelFormField); | |
} | |
public String getBackgroundSubmitRefreshTarget(Map<String, Object> context) { | |
return this.backgroundSubmitRefreshTargetExdr.expandString(context); | |
} | |
public FlexibleStringExpander getBackgroundSubmitRefreshTargetExdr() { | |
return backgroundSubmitRefreshTargetExdr; | |
} | |
public String getButtonType() { | |
return buttonType; | |
} | |
public String getConfirmation(Map<String, Object> context) { | |
String message = getConfirmationMsg(context); | |
if (UtilValidate.isNotEmpty(message)) | |
return message; | |
else if (getRequestConfirmation()) { | |
String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message", | |
"${uiLabelMap.CommonConfirm}"); | |
return FlexibleStringExpander.expandString(defaultMessage, context); | |
} | |
return ""; | |
} | |
public String getConfirmationMsg(Map<String, Object> context) { | |
return this.confirmationMsgExdr.expandString(context); | |
} | |
public FlexibleStringExpander getConfirmationMsgExdr() { | |
return confirmationMsgExdr; | |
} | |
public FlexibleStringExpander getImageLocation() { | |
return imageLocation; | |
} | |
public String getImageLocation(Map<String, Object> context) { | |
return this.imageLocation.expandString(context); | |
} | |
public boolean getRequestConfirmation() { | |
return this.requestConfirmation; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderSubmitField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <textarea> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class TextareaField extends FieldInfo { | |
private final int cols; | |
private final FlexibleStringExpander defaultValue; | |
private final boolean readOnly; | |
private final int rows; | |
private final FlexibleStringExpander visualEditorButtons; | |
private final boolean visualEditorEnable; | |
public TextareaField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
int cols = 60; | |
String colsStr = element.getAttribute("cols"); | |
if (!colsStr.isEmpty()) { | |
try { | |
cols = Integer.parseInt(colsStr); | |
} catch (Exception e) { | |
if (UtilValidate.isNotEmpty(colsStr)) { | |
Debug.logError("Could not parse the size value of the text element: [" + colsStr | |
+ "], setting to default of " + cols, module); | |
} | |
} | |
} | |
this.cols = cols; | |
this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value")); | |
this.readOnly = "true".equals(element.getAttribute("read-only")); | |
int rows = 2; | |
String rowsStr = element.getAttribute("rows"); | |
if (!rowsStr.isEmpty()) { | |
try { | |
rows = Integer.parseInt(rowsStr); | |
} catch (Exception e) { | |
if (UtilValidate.isNotEmpty(rowsStr)) { | |
Debug.logError("Could not parse the size value of the text element: [" + rowsStr | |
+ "], setting to default of " + rows, module); | |
} | |
} | |
} | |
this.rows = rows; | |
this.visualEditorButtons = FlexibleStringExpander.getInstance(element.getAttribute("visual-editor-buttons")); | |
this.visualEditorEnable = "true".equals(element.getAttribute("visual-editor-enable")); | |
} | |
public TextareaField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.TEXTAREA, modelFormField); | |
this.cols = 60; | |
this.defaultValue = FlexibleStringExpander.getInstance(""); | |
this.readOnly = false; | |
this.rows = 2; | |
this.visualEditorButtons = FlexibleStringExpander.getInstance(""); | |
this.visualEditorEnable = false; | |
} | |
public TextareaField(ModelFormField modelFormField) { | |
this(FieldInfo.SOURCE_EXPLICIT, modelFormField); | |
} | |
private TextareaField(TextareaField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
this.defaultValue = original.defaultValue; | |
this.visualEditorEnable = original.visualEditorEnable; | |
this.visualEditorButtons = original.visualEditorButtons; | |
this.readOnly = original.readOnly; | |
this.cols = original.cols; | |
this.rows = original.rows; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new TextareaField(this, modelFormField); | |
} | |
public int getCols() { | |
return cols; | |
} | |
public FlexibleStringExpander getDefaultValue() { | |
return defaultValue; | |
} | |
public String getDefaultValue(Map<String, Object> context) { | |
if (this.defaultValue != null) { | |
return this.defaultValue.expandString(context); | |
} else { | |
return ""; | |
} | |
} | |
public int getRows() { | |
return rows; | |
} | |
public FlexibleStringExpander getVisualEditorButtons() { | |
return visualEditorButtons; | |
} | |
public String getVisualEditorButtons(Map<String, Object> context) { | |
return this.visualEditorButtons.expandString(context); | |
} | |
public boolean getVisualEditorEnable() { | |
return this.visualEditorEnable; | |
} | |
public boolean isReadOnly() { | |
return readOnly; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderTextareaField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <text> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class TextField extends FieldInfo { | |
private final boolean clientAutocompleteField; | |
private final FlexibleStringExpander defaultValue; | |
private final boolean disabled; | |
private final String mask; | |
private final Integer maxlength; | |
private final FlexibleStringExpander placeholder; | |
private final boolean readonly; | |
private final int size; | |
private final SubHyperlink subHyperlink; | |
public TextField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
this.clientAutocompleteField = !"false".equals(element.getAttribute("client-autocomplete-field")); | |
this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value")); | |
this.disabled = "true".equals(element.getAttribute("disabled")); | |
this.mask = element.getAttribute("mask"); | |
Integer maxlength = null; | |
String maxlengthStr = element.getAttribute("maxlength"); | |
if (!maxlengthStr.isEmpty()) { | |
try { | |
maxlength = Integer.valueOf(maxlengthStr); | |
} catch (Exception e) { | |
Debug.logError("Could not parse the max-length value of the text element: [" + maxlengthStr | |
+ "], setting to null; default of no maxlength will be used", module); | |
} | |
} | |
this.maxlength = maxlength; | |
this.placeholder = FlexibleStringExpander.getInstance(element.getAttribute("placeholder")); | |
this.readonly = "true".equals(element.getAttribute("read-only")); | |
int size = 25; | |
String sizeStr = element.getAttribute("size"); | |
if (!sizeStr.isEmpty()) { | |
try { | |
size = Integer.parseInt(sizeStr); | |
} catch (Exception e) { | |
Debug.logError("Could not parse the size value of the text element: [" + sizeStr | |
+ "], setting to the default of " + size, module); | |
} | |
} | |
this.size = size; | |
Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink"); | |
if (subHyperlinkElement != null) { | |
this.subHyperlink = new SubHyperlink(subHyperlinkElement, this.getModelFormField()); | |
} else { | |
this.subHyperlink = null; | |
} | |
} | |
protected TextField(int fieldSource, int size, Integer maxlength, ModelFormField modelFormField) { | |
super(fieldSource, FieldInfo.TEXT, modelFormField); | |
this.clientAutocompleteField = true; | |
this.defaultValue = FlexibleStringExpander.getInstance(""); | |
this.disabled = false; | |
this.mask = ""; | |
this.maxlength = maxlength; | |
this.placeholder = FlexibleStringExpander.getInstance(""); | |
this.readonly = false; | |
this.size = size; | |
this.subHyperlink = null; | |
} | |
private TextField(int fieldSource, int fieldType, ModelFormField modelFormField) { | |
super(fieldSource, fieldType, modelFormField); | |
this.clientAutocompleteField = true; | |
this.defaultValue = FlexibleStringExpander.getInstance(""); | |
this.disabled = false; | |
this.mask = ""; | |
this.maxlength = null; | |
this.placeholder = FlexibleStringExpander.getInstance(""); | |
this.readonly = false; | |
this.size = 25; | |
this.subHyperlink = null; | |
} | |
public TextField(int fieldSource, ModelFormField modelFormField) { | |
this(fieldSource, FieldInfo.TEXT, modelFormField); | |
} | |
public TextField(ModelFormField modelFormField) { | |
this(FieldInfo.SOURCE_EXPLICIT, FieldInfo.TEXT, modelFormField); | |
} | |
protected TextField(TextField original, ModelFormField modelFormField) { | |
super(original.getFieldSource(), original.getFieldType(), modelFormField); | |
this.clientAutocompleteField = original.clientAutocompleteField; | |
this.defaultValue = original.defaultValue; | |
this.mask = original.mask; | |
this.placeholder = original.placeholder; | |
this.size = original.size; | |
this.maxlength = original.maxlength; | |
this.disabled = original.disabled; | |
this.readonly = original.readonly; | |
if (original.subHyperlink != null) { | |
this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField); | |
} else { | |
this.subHyperlink = null; | |
} | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new TextField(this, modelFormField); | |
} | |
public boolean getClientAutocompleteField() { | |
return this.clientAutocompleteField; | |
} | |
public FlexibleStringExpander getDefaultValue() { | |
return defaultValue; | |
} | |
public String getDefaultValue(Map<String, Object> context) { | |
if (this.defaultValue != null) { | |
return this.defaultValue.expandString(context); | |
} else { | |
return ""; | |
} | |
} | |
public boolean getDisabled() { | |
return this.disabled; | |
} | |
public String getMask() { | |
return this.mask; | |
} | |
public Integer getMaxlength() { | |
return maxlength; | |
} | |
public FlexibleStringExpander getPlaceholder() { | |
return placeholder; | |
} | |
public String getPlaceholder(Map<String, Object> context) { | |
return this.placeholder.expandString(context); | |
} | |
public boolean getReadonly() { | |
return this.readonly; | |
} | |
public int getSize() { | |
return size; | |
} | |
public SubHyperlink getSubHyperlink() { | |
return this.subHyperlink; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderTextField(writer, context, this); | |
} | |
} | |
/** | |
* Models the <text-find> element. | |
* | |
* @see <code>widget-form.xsd</code> | |
*/ | |
public static class TextFindField extends TextField { | |
private final String defaultOption; | |
private final boolean hideIgnoreCase; | |
private final boolean hideOptions; | |
private final boolean ignoreCase; | |
public TextFindField(Element element, ModelFormField modelFormField) { | |
super(element, modelFormField); | |
if (element.hasAttribute("default-option")) { | |
this.defaultOption = element.getAttribute("default-option"); | |
} else { | |
this.defaultOption = UtilProperties.getPropertyValue("widget", "widget.form.defaultTextFindOption", "contains"); | |
} | |
this.hideIgnoreCase = "true".equals(element.getAttribute("hide-options")) | |
|| "ignore-case".equals(element.getAttribute("hide-options")) ? true : false; | |
this.hideOptions = "true".equals(element.getAttribute("hide-options")) | |
|| "options".equals(element.getAttribute("hide-options")) ? true : false; | |
this.ignoreCase = "true".equals(element.getAttribute("ignore-case")); | |
} | |
public TextFindField(int fieldSource, int size, Integer maxlength, ModelFormField modelFormField) { | |
super(fieldSource, size, maxlength, modelFormField); | |
this.defaultOption = UtilProperties.getPropertyValue("widget", "widget.form.defaultTextFindOption", "contains"); | |
this.hideIgnoreCase = false; | |
this.hideOptions = false; | |
this.ignoreCase = true; | |
} | |
public TextFindField(int fieldSource, ModelFormField modelFormField) { | |
super(fieldSource, modelFormField); | |
this.defaultOption = UtilProperties.getPropertyValue("widget", "widget.form.defaultTextFindOption", "contains"); | |
this.hideIgnoreCase = false; | |
this.hideOptions = false; | |
this.ignoreCase = true; | |
} | |
private TextFindField(TextFindField original, ModelFormField modelFormField) { | |
super(original, modelFormField); | |
this.ignoreCase = original.ignoreCase; | |
this.hideIgnoreCase = original.hideIgnoreCase; | |
this.defaultOption = original.defaultOption; | |
this.hideOptions = original.hideOptions; | |
} | |
@Override | |
public void accept(ModelFieldVisitor visitor) throws Exception { | |
visitor.visit(this); | |
} | |
@Override | |
public FieldInfo copy(ModelFormField modelFormField) { | |
return new TextFindField(this, modelFormField); | |
} | |
public String getDefaultOption() { | |
return this.defaultOption; | |
} | |
public boolean getHideIgnoreCase() { | |
return this.hideIgnoreCase; | |
} | |
public boolean getHideOptions() { | |
return this.hideOptions; | |
} | |
public boolean getIgnoreCase() { | |
return this.ignoreCase; | |
} | |
@Override | |
public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) | |
throws IOException { | |
formStringRenderer.renderTextFindField(writer, context, this); | |
} | |
} | |
} |