blob: ab8daa78d5ecb0fe926518b6cec985fd410fb135 [file] [log] [blame]
/*******************************************************************************
* 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.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.ofbiz.base.util.BshUtil;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.UtilCodec;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilXml;
import org.ofbiz.base.util.string.FlexibleStringExpander;
import org.ofbiz.entity.model.ModelReader;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.widget.WidgetWorker;
import org.w3c.dom.Element;
import bsh.EvalError;
import bsh.Interpreter;
/**
* Models the <grid> element.
*
* @see <code>widget-form.xsd</code>
*/
@SuppressWarnings("serial")
public class ModelGrid extends ModelForm {
/*
* ----------------------------------------------------------------------- *
* 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!
*
* BE VERY CAREFUL when implementing "extends" - parent form collections
* must be added to child collections, not replace them. In other words,
* do not assign parent collection fields to child collection fields.
*
*/
public static final String module = ModelGrid.class.getName();
/** XML Constructor */
public ModelGrid(Element formElement, String formLocation, ModelReader entityModelReader, DispatchContext dispatchContext) {
super(formElement, formLocation, entityModelReader, dispatchContext);
}
@Override
public void accept(ModelWidgetVisitor visitor) throws Exception {
visitor.visit(this);
}
public List<ModelAction> getActions() {
return actions;
}
public List<AltRowStyle> getAltRowStyles() {
return altRowStyles;
}
public List<AltTarget> getAltTargets() {
return altTargets;
}
public List<AutoFieldsEntity> getAutoFieldsEntities() {
return autoFieldsEntities;
}
public List<AutoFieldsService> getAutoFieldsServices() {
return autoFieldsServices;
}
public Interpreter getBshInterpreter(Map<String, Object> context) throws EvalError {
Interpreter bsh = (Interpreter) context.get("bshInterpreter");
if (bsh == null) {
bsh = BshUtil.makeInterpreter(context);
context.put("bshInterpreter", bsh);
}
return bsh;
}
@Override
public String getBoundaryCommentName() {
return formLocation + "#" + getName();
}
public boolean getClientAutocompleteFields() {
return this.clientAutocompleteFields;
}
public String getContainerId() {
// use the name if there is no id
if (UtilValidate.isNotEmpty(this.containerId)) {
return this.containerId;
} else {
return this.getName();
}
}
public String getContainerStyle() {
return this.containerStyle;
}
public String getDefaultEntityName() {
return this.defaultEntityName;
}
public FieldGroup getDefaultFieldGroup() {
return defaultFieldGroup;
}
public Map<String, ? extends Object> getDefaultMap(Map<String, ? extends Object> context) {
return this.defaultMapName.get(context);
}
public String getDefaultMapName() {
return this.defaultMapName.getOriginalName();
}
public String getDefaultRequiredFieldStyle() {
return this.defaultRequiredFieldStyle;
}
public String getDefaultServiceName() {
return this.defaultServiceName;
}
public String getDefaultSortFieldAscStyle() {
return this.defaultSortFieldAscStyle;
}
public String getDefaultSortFieldDescStyle() {
return this.defaultSortFieldDescStyle;
}
public String getDefaultSortFieldStyle() {
return this.defaultSortFieldStyle;
}
public String getDefaultTableStyle() {
return this.defaultTableStyle;
}
public String getDefaultTitleAreaStyle() {
return this.defaultTitleAreaStyle;
}
public String getDefaultTitleStyle() {
return this.defaultTitleStyle;
}
public String getDefaultTooltipStyle() {
return this.defaultTooltipStyle;
}
public int getDefaultViewSize() {
return defaultViewSize;
}
public String getDefaultWidgetAreaStyle() {
return this.defaultWidgetAreaStyle;
}
public String getDefaultWidgetStyle() {
return this.defaultWidgetStyle;
}
public String getEvenRowStyle() {
return this.evenRowStyle;
}
public List<FieldGroupBase> getFieldGroupList() {
return fieldGroupList;
}
public Map<String, FieldGroupBase> getFieldGroupMap() {
return fieldGroupMap;
}
public List<ModelFormField> getFieldList() {
return fieldList;
}
public String getFocusFieldName() {
return focusFieldName;
}
public String getFormLocation() {
return this.formLocation;
}
public String getFormTitleAreaStyle() {
return this.formTitleAreaStyle;
}
public String getFormWidgetAreaStyle() {
return this.formWidgetAreaStyle;
}
public String getHeaderRowStyle() {
return this.headerRowStyle;
}
public boolean getHideHeader() {
return this.hideHeader;
}
public String getItemIndexSeparator() {
if (UtilValidate.isNotEmpty(this.itemIndexSeparator)) {
return this.itemIndexSeparator;
} else {
return "_o_";
}
}
public List<String> getLastOrderFields() {
return lastOrderFields;
}
public String getListEntryName() {
return this.listEntryName;
}
public String getListName() {
return this.listName;
}
public String getMultiPaginateIndexField(Map<String, Object> context) {
String field = this.paginateIndexField.expandString(context);
if (UtilValidate.isEmpty(field)) {
field = DEFAULT_PAG_INDEX_FIELD;
}
// append the paginator number
field = field + "_" + WidgetWorker.getPaginatorNumber(context);
return field;
}
public String getMultiPaginateSizeField(Map<String, Object> context) {
String field = this.paginateSizeField.expandString(context);
if (UtilValidate.isEmpty(field)) {
field = DEFAULT_PAG_SIZE_FIELD;
}
// append the paginator number
field = field + "_" + WidgetWorker.getPaginatorNumber(context);
return field;
}
public List<ModelFormField> getMultiSubmitFields() {
return this.multiSubmitFields;
}
public String getOddRowStyle() {
return this.oddRowStyle;
}
public List<UpdateArea> getOnPaginateUpdateAreas() {
return this.onPaginateUpdateAreas;
}
public List<UpdateArea> getOnSortColumnUpdateAreas() {
return this.onSortColumnUpdateAreas;
}
/* Returns the list of ModelForm.UpdateArea objects.
*/
public List<UpdateArea> getOnSubmitUpdateAreas() {
return this.onSubmitUpdateAreas;
}
public String getOverrideListSize() {
return overrideListSize.getOriginal();
}
public int getOverrideListSize(Map<String, Object> context) {
int listSize = 0;
if (!this.overrideListSize.isEmpty()) {
String size = this.overrideListSize.expandString(context);
try {
size = size.replaceAll("[^0-9.]", "");
listSize = Integer.parseInt(size);
} catch (NumberFormatException e) {
Debug.logError(e, "Error getting override list size from value " + size, module);
}
}
return listSize;
}
public String getPaginate() {
return paginate.getOriginal();
}
public boolean getPaginate(Map<String, Object> context) {
String paginate = this.paginate.expandString(context);
if (!paginate.isEmpty()) {
return Boolean.valueOf(paginate).booleanValue();
} else {
return true;
}
}
public String getPaginateFirstLabel() {
return paginateFirstLabel.getOriginal();
}
public String getPaginateFirstLabel(Map<String, Object> context) {
Locale locale = (Locale) context.get("locale");
String field = this.paginateFirstLabel.expandString(context);
if (UtilValidate.isEmpty(field)) {
field = UtilProperties.getMessage("CommonUiLabels", "CommonFirst", locale);
}
return field;
}
public String getPaginateFirstStyle() {
return DEFAULT_PAG_FIRST_STYLE;
}
public String getPaginateIndexField() {
return paginateIndexField.getOriginal();
}
public String getPaginateIndexField(Map<String, Object> context) {
String field = this.paginateIndexField.expandString(context);
if (field.isEmpty()) {
return DEFAULT_PAG_INDEX_FIELD;
}
return field;
}
public String getPaginateLastLabel() {
return paginateLastLabel.getOriginal();
}
public String getPaginateLastLabel(Map<String, Object> context) {
Locale locale = (Locale) context.get("locale");
String field = this.paginateLastLabel.expandString(context);
if (UtilValidate.isEmpty(field)) {
field = UtilProperties.getMessage("CommonUiLabels", "CommonLast", locale);
}
return field;
}
public String getPaginateLastStyle() {
return DEFAULT_PAG_LAST_STYLE;
}
public String getPaginateNextLabel() {
return paginateNextLabel.getOriginal();
}
public String getPaginateNextLabel(Map<String, Object> context) {
String field = this.paginateNextLabel.expandString(context);
if (field.isEmpty()) {
Locale locale = (Locale) context.get("locale");
return UtilProperties.getMessage("CommonUiLabels", "CommonNext", locale);
}
return field;
}
public String getPaginateNextStyle() {
return DEFAULT_PAG_NEXT_STYLE;
}
public String getPaginatePreviousLabel() {
return paginatePreviousLabel.getOriginal();
}
public String getPaginatePreviousLabel(Map<String, Object> context) {
String field = this.paginatePreviousLabel.expandString(context);
if (field.isEmpty()) {
Locale locale = (Locale) context.get("locale");
field = UtilProperties.getMessage("CommonUiLabels", "CommonPrevious", locale);
}
return field;
}
public String getPaginatePreviousStyle() {
return DEFAULT_PAG_PREV_STYLE;
}
public String getPaginateSizeField() {
return paginateSizeField.getOriginal();
}
public String getPaginateSizeField(Map<String, Object> context) {
String field = this.paginateSizeField.expandString(context);
if (field.isEmpty()) {
return DEFAULT_PAG_SIZE_FIELD;
}
return field;
}
public String getPaginateStyle() {
return this.paginateStyle;
}
public String getPaginateTarget() {
return paginateTarget.getOriginal();
}
public String getPaginateTarget(Map<String, Object> context) {
String targ = this.paginateTarget.expandString(context);
if (targ.isEmpty()) {
Map<String, ?> parameters = UtilGenerics.cast(context.get("parameters"));
if (parameters != null && parameters.containsKey("targetRequestUri")) {
targ = (String) parameters.get("targetRequestUri");
}
}
return targ;
}
public String getPaginateTargetAnchor() {
return this.paginateTargetAnchor;
}
public String getPaginateViewSizeLabel() {
return paginateViewSizeLabel.getOriginal();
}
public String getPaginateViewSizeLabel(Map<String, Object> context) {
String field = this.paginateViewSizeLabel.expandString(context);
if (field.isEmpty()) {
Locale locale = (Locale) context.get("locale");
return UtilProperties.getMessage("CommonUiLabels", "CommonItemsPerPage", locale);
}
return field;
}
protected ModelForm getParentModel(Element gridElement, ModelReader entityModelReader, DispatchContext dispatchContext) {
ModelForm parentModel = null;
String parentResource = gridElement.getAttribute("extends-resource");
String parentGrid = gridElement.getAttribute("extends");
String gridType = gridElement.getAttribute("type");
if (!parentGrid.isEmpty()) {
// check if we have a resource name
if (!parentResource.isEmpty()) {
try {
parentModel = GridFactory.getGridFromLocation(parentResource, parentGrid, entityModelReader, dispatchContext);
} catch (Exception e) {
Debug.logError(e, "Failed to load parent grid definition '" + parentGrid + "' at resource '" + parentResource
+ "'", module);
}
} else if (!parentGrid.equals(gridElement.getAttribute("name"))) {
// try to find a grid definition in the same file
Element rootElement = gridElement.getOwnerDocument().getDocumentElement();
List<? extends Element> gridElements = UtilXml.childElementList(rootElement, "grid");
if (gridElements.isEmpty()) {
// Backwards compatibility - look for form definitions
gridElements = UtilXml.childElementList(rootElement, "form");
}
for (Element parentElement : gridElements) {
if (parentElement.getAttribute("name").equals(parentGrid) && gridType.equals(parentElement.getAttribute("type"))) {
parentModel = GridFactory.createModelGrid(parentElement, entityModelReader, dispatchContext, parentResource, parentGrid);
break;
}
}
if (parentModel == null) {
Debug.logError("Failed to find parent grid definition '" + parentGrid + "' in same document.", module);
}
} else {
Debug.logError("Recursive grid definition found for '" + gridElement.getAttribute("name") + ".'", module);
}
}
return parentModel;
}
public String getPassedRowCount(Map<String, Object> context) {
return rowCountExdr.expandString(context);
}
public List<ModelAction> getRowActions() {
return rowActions;
}
public String getRowCount() {
return rowCountExdr.getOriginal();
}
public boolean getSeparateColumns() {
return this.separateColumns;
}
public boolean getSkipEnd() {
return this.skipEnd;
}
public boolean getSkipStart() {
return this.skipStart;
}
public String getSortField(Map<String, Object> context) {
String value = null;
try {
value = (String) context.get(this.sortFieldParameterName);
if (value == null) {
Map<String, String> parameters = UtilGenerics.cast(context.get("parameters"));
if (parameters != null) {
value = parameters.get(this.sortFieldParameterName);
}
}
} catch (Exception e) {
Debug.logWarning(e, "Error getting sortField: " + e.toString(), module);
}
return value;
}
public String getSortFieldParameterName() {
return this.sortFieldParameterName;
}
public List<SortField> getSortOrderFields() {
return sortOrderFields;
}
/**
* iterate through alt-row-styles list to see if should be used, then add style
* @return The style for item row
*/
public String getStyleAltRowStyle(Map<String, Object> context) {
String styles = "";
try {
// use the same Interpreter (ie with the same context setup) for all evals
Interpreter bsh = this.getBshInterpreter(context);
for (AltRowStyle altRowStyle : this.altRowStyles) {
Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(altRowStyle.useWhen));
// retVal should be a Boolean, if not something weird is up...
if (retVal instanceof Boolean) {
Boolean boolVal = (Boolean) retVal;
if (boolVal.booleanValue()) {
styles += altRowStyle.style;
}
} else {
throw new IllegalArgumentException("Return value from style condition eval was not a Boolean: "
+ retVal.getClass().getName() + " [" + retVal + "] of form " + getName());
}
}
} catch (EvalError e) {
String errmsg = "Error evaluating BeanShell style conditions on form " + getName();
Debug.logError(e, errmsg, module);
throw new IllegalArgumentException(errmsg);
}
return styles;
}
public String getTarget() {
return target.getOriginal();
}
/** iterate through altTargets list to see if any should be used, if not return original target
* @return The target for this Form
*/
public String getTarget(Map<String, Object> context, String targetType) {
Map<String, Object> expanderContext = context;
UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
if (simpleEncoder != null) {
expanderContext = UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
}
try {
// use the same Interpreter (ie with the same context setup) for all evals
Interpreter bsh = this.getBshInterpreter(context);
for (AltTarget altTarget : this.altTargets) {
String useWhen = FlexibleStringExpander.expandString(altTarget.useWhen, context);
Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhen));
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 target condition eval was not a Boolean: "
+ retVal.getClass().getName() + " [" + retVal + "] of form " + getName());
}
if (condTrue && !targetType.equals("inter-app")) {
return altTarget.targetExdr.expandString(expanderContext);
}
}
} catch (EvalError e) {
String errmsg = "Error evaluating BeanShell target conditions on form " + getName();
Debug.logError(e, errmsg, module);
throw new IllegalArgumentException(errmsg);
}
return target.expandString(expanderContext);
}
public String getTargetType() {
return this.targetType;
}
public String getTargetWindow() {
return targetWindowExdr.getOriginal();
}
public String getTargetWindow(Map<String, Object> context) {
return this.targetWindowExdr.expandString(context);
}
public String getTitle() {
return this.title;
}
public String getTooltip() {
return this.tooltip;
}
public String getType() {
return this.type;
}
public boolean getUseRowSubmit() {
return this.useRowSubmit;
}
public Set<String> getUseWhenFields() {
return useWhenFields;
}
public boolean getGroupColumns() {
return groupColumns;
}
public boolean isOverridenListSize() {
return !this.overrideListSize.isEmpty();
}
public void runFormActions(Map<String, Object> context) {
AbstractModelAction.runSubActions(this.actions, context);
}
}