| /******************************************************************************* |
| * 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.form; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.NoSuchElementException; |
| import java.util.Set; |
| import java.util.TreeMap; |
| import java.util.TreeSet; |
| |
| import javolution.util.FastList; |
| import javolution.util.FastMap; |
| import javolution.util.FastSet; |
| |
| import org.ofbiz.base.util.BshUtil; |
| import org.ofbiz.base.util.Debug; |
| import org.ofbiz.base.util.GeneralException; |
| import org.ofbiz.base.util.StringUtil; |
| 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.GenericEntity; |
| import org.ofbiz.entity.GenericEntityException; |
| import org.ofbiz.entity.model.ModelEntity; |
| import org.ofbiz.entity.model.ModelField; |
| import org.ofbiz.entity.model.ModelReader; |
| import org.ofbiz.entity.util.EntityListIterator; |
| import org.ofbiz.service.DispatchContext; |
| import org.ofbiz.service.GenericServiceException; |
| import org.ofbiz.service.ModelParam; |
| import org.ofbiz.service.ModelService; |
| import org.ofbiz.webapp.control.ConfigXMLReader; |
| import org.ofbiz.widget.ModelWidget; |
| import org.ofbiz.widget.WidgetWorker; |
| import org.w3c.dom.Element; |
| |
| import bsh.EvalError; |
| import bsh.Interpreter; |
| |
| /** |
| * Widget Library - Form model class |
| */ |
| @SuppressWarnings("serial") |
| public class ModelForm extends ModelWidget { |
| |
| public static final String module = ModelForm.class.getName(); |
| public static final String DEFAULT_FORM_RESULT_LIST_NAME = "defaultFormResultList"; |
| |
| protected ModelReader entityModelReader; |
| protected DispatchContext dispatchContext; |
| |
| protected String formLocation; |
| protected String parentFormName; |
| protected String parentFormLocation; |
| protected ModelForm parentModelForm; |
| protected String type; |
| protected FlexibleStringExpander target; |
| protected String targetType; |
| protected String containerId; |
| protected String containerStyle; |
| protected String focusFieldName; |
| protected String title; |
| protected String tooltip; |
| protected String listName; |
| protected String listEntryName; |
| protected FlexibleMapAccessor<Map<String, ? extends Object>> defaultMapName; |
| protected String defaultEntityName; |
| protected String defaultServiceName; |
| protected String formTitleAreaStyle; |
| protected String formWidgetAreaStyle; |
| protected String defaultTitleAreaStyle; |
| protected String defaultWidgetAreaStyle; |
| protected String defaultTitleStyle; |
| protected String defaultWidgetStyle; |
| protected String defaultTooltipStyle; |
| protected String itemIndexSeparator; |
| protected FlexibleStringExpander paginate; |
| protected FlexibleStringExpander paginateTarget; |
| protected FlexibleStringExpander paginateIndexField; |
| protected FlexibleStringExpander paginateSizeField; |
| protected FlexibleStringExpander overrideListSize; |
| protected FlexibleStringExpander paginateFirstLabel; |
| protected FlexibleStringExpander paginatePreviousLabel; |
| protected FlexibleStringExpander paginateNextLabel; |
| protected FlexibleStringExpander paginateLastLabel; |
| protected FlexibleStringExpander paginateViewSizeLabel; |
| protected String paginateTargetAnchor; |
| protected String paginateStyle; |
| protected boolean separateColumns = false; |
| protected boolean groupColumns = true; |
| protected boolean useRowSubmit = false; |
| protected FlexibleStringExpander targetWindowExdr; |
| protected String defaultRequiredFieldStyle; |
| protected String defaultSortFieldStyle; |
| protected String defaultSortFieldAscStyle; |
| protected String defaultSortFieldDescStyle; |
| protected String oddRowStyle; |
| protected String evenRowStyle; |
| protected String defaultTableStyle; |
| protected String headerRowStyle; |
| protected boolean skipStart = false; |
| protected boolean skipEnd = false; |
| protected boolean hideHeader = false; |
| protected boolean overridenListSize = false; |
| protected boolean clientAutocompleteFields = true; |
| |
| protected List<AltTarget> altTargets = FastList.newInstance(); |
| protected List<AutoFieldsService> autoFieldsServices = FastList.newInstance(); |
| protected List<AutoFieldsEntity> autoFieldsEntities = FastList.newInstance(); |
| protected List<String> lastOrderFields = FastList.newInstance(); |
| protected List<SortField> sortOrderFields = FastList.newInstance(); |
| protected List<AltRowStyle> altRowStyles = FastList.newInstance(); |
| |
| /** This List will contain one copy of each field for each field name in the order |
| * they were encountered in the service, entity, or form definition; field definitions |
| * with constraints will also be in this list but may appear multiple times for the same |
| * field name. |
| * |
| * When rendering the form the order in this list should be following and it should not be |
| * necessary to use the Map. The Map is used when loading the form definition to keep the |
| * list clean and implement the override features for field definitions. |
| */ |
| protected List<ModelFormField> fieldList = FastList.newInstance(); |
| |
| /** This Map is keyed with the field name and has a ModelFormField for the value. |
| */ |
| protected Map<String, ModelFormField> fieldMap = FastMap.newInstance(); |
| |
| /** Keeps track of conditional fields to help ensure that only one is rendered |
| */ |
| protected Set<String> useWhenFields = FastSet.newInstance(); |
| |
| /** This is a list of FieldGroups in the order they were created. |
| * Can also include Banner objects. |
| */ |
| protected List<FieldGroupBase> fieldGroupList = FastList.newInstance(); |
| |
| /** This Map is keyed with the field name and has a FieldGroup for the value. |
| * Can also include Banner objects. |
| */ |
| protected Map<String, FieldGroupBase> fieldGroupMap = FastMap.newInstance(); |
| |
| /** This field group will be the "catch-all" group for fields that are not |
| * included in an explicit field-group. |
| */ |
| protected FieldGroup defaultFieldGroup; |
| |
| /** Pagination settings and defaults. */ |
| public static int DEFAULT_PAGE_SIZE = 10; |
| public static int MAX_PAGE_SIZE = 10000; |
| protected int defaultViewSize = DEFAULT_PAGE_SIZE; |
| public static String DEFAULT_PAG_INDEX_FIELD = "viewIndex"; |
| public static String DEFAULT_PAG_SIZE_FIELD = "viewSize"; |
| public static String DEFAULT_PAG_STYLE = "nav-pager"; |
| public static String DEFAULT_PAG_FIRST_STYLE = "nav-first"; |
| public static String DEFAULT_PAG_PREV_STYLE = "nav-previous"; |
| public static String DEFAULT_PAG_NEXT_STYLE = "nav-next"; |
| public static String DEFAULT_PAG_LAST_STYLE = "nav-last"; |
| |
| /** Sort field default styles. */ |
| public static String DEFAULT_SORT_FIELD_STYLE = "sort-order"; |
| public static String DEFAULT_SORT_FIELD_ASC_STYLE = "sort-order-asc"; |
| public static String DEFAULT_SORT_FIELD_DESC_STYLE = "sort-order-desc"; |
| |
| protected List<ModelFormAction> actions; |
| protected List<ModelFormAction> rowActions; |
| protected FlexibleStringExpander rowCountExdr; |
| protected List<ModelFormField> multiSubmitFields = FastList.newInstance(); |
| protected int rowCount = 0; |
| private String sortFieldParameterName = "sortField"; |
| |
| /** On Submit areas to be updated. */ |
| protected List<UpdateArea> onSubmitUpdateAreas; |
| /** On Paginate areas to be updated. */ |
| protected List<UpdateArea> onPaginateUpdateAreas; |
| /** On Sort Column areas to be updated. */ |
| protected List<UpdateArea> onSortColumnUpdateAreas; |
| |
| // ===== CONSTRUCTORS ===== |
| /** Default Constructor */ |
| public ModelForm() {} |
| |
| /** XML Constructor */ |
| public ModelForm(Element formElement, ModelReader entityModelReader, DispatchContext dispatchContext) { |
| super(formElement); |
| this.entityModelReader = entityModelReader; |
| this.dispatchContext = dispatchContext; |
| try { |
| initForm(formElement); |
| } catch (RuntimeException e) { |
| Debug.logError(e, "Error parsing form [" + formElement.getAttribute("name") + "]: " + e.toString(), module); |
| throw e; |
| } |
| } |
| |
| public ModelForm(Element formElement) { |
| super(formElement); |
| initForm(formElement); |
| } |
| |
| public void initForm(Element formElement) { |
| |
| setDefaultViewSize(UtilProperties.getPropertyValue("widget.properties", "widget.form.defaultViewSize")); |
| // check if there is a parent form to inherit from |
| String parentResource = formElement.getAttribute("extends-resource"); |
| String parentForm = formElement.getAttribute("extends"); |
| if (parentForm.length() > 0) { |
| ModelForm parent = null; |
| // check if we have a resource name (part of the string before the ?) |
| if (parentResource.length() > 0) { |
| try { |
| parent = FormFactory.getFormFromLocation(parentResource, parentForm, entityModelReader, dispatchContext); |
| this.parentFormName = parentForm; |
| this.parentFormLocation = parentResource; |
| } catch (Exception e) { |
| Debug.logError(e, "Failed to load parent form definition '" + parentForm + "' at resource '" + parentResource + "'", module); |
| } |
| } else if (!parentForm.equals(formElement.getAttribute("name"))) { |
| // try to find a form definition in the same file |
| Element rootElement = formElement.getOwnerDocument().getDocumentElement(); |
| List<? extends Element> formElements = UtilXml.childElementList(rootElement, "form"); |
| //Uncomment below to add support for abstract forms |
| //formElements.addAll(UtilXml.childElementList(rootElement, "abstract-form")); |
| for (Element formElementEntry: formElements) { |
| if (formElementEntry.getAttribute("name").equals(parentForm)) { |
| parent = new ModelForm(formElementEntry, entityModelReader, dispatchContext); |
| break; |
| } |
| } |
| if (parent == null) { |
| Debug.logError("Failed to find parent form definition '" + parentForm + "' in same document.", module); |
| } else { |
| this.parentFormName = parentForm; |
| } |
| } else { |
| Debug.logError("Recursive form definition found for '" + formElement.getAttribute("name") + ".'", module); |
| } |
| |
| if (parent != null) { |
| this.parentModelForm = parent; |
| this.type = parent.type; |
| this.target = parent.target; |
| this.containerId = parent.containerId; |
| this.containerStyle = parent.containerStyle; |
| this.focusFieldName = parent.focusFieldName; |
| this.title = parent.title; |
| this.tooltip = parent.tooltip; |
| this.listName = parent.listName; |
| this.listEntryName = parent.listEntryName; |
| this.tooltip = parent.tooltip; |
| this.defaultEntityName = parent.defaultEntityName; |
| this.defaultServiceName = parent.defaultServiceName; |
| this.formTitleAreaStyle = parent.formTitleAreaStyle; |
| this.formWidgetAreaStyle = parent.formWidgetAreaStyle; |
| this.defaultTitleAreaStyle = parent.defaultTitleAreaStyle; |
| this.defaultWidgetAreaStyle = parent.defaultWidgetAreaStyle; |
| this.oddRowStyle = parent.oddRowStyle; |
| this.evenRowStyle = parent.evenRowStyle; |
| this.defaultTableStyle = parent.defaultTableStyle; |
| this.headerRowStyle = parent.headerRowStyle; |
| this.defaultTitleStyle = parent.defaultTitleStyle; |
| this.defaultWidgetStyle = parent.defaultWidgetStyle; |
| this.defaultTooltipStyle = parent.defaultTooltipStyle; |
| this.itemIndexSeparator = parent.itemIndexSeparator; |
| this.separateColumns = parent.separateColumns; |
| this.groupColumns = parent.groupColumns; |
| this.targetType = parent.targetType; |
| this.defaultMapName = parent.defaultMapName; |
| this.targetWindowExdr = parent.targetWindowExdr; |
| this.hideHeader = parent.hideHeader; |
| this.clientAutocompleteFields = parent.clientAutocompleteFields; |
| this.paginateTarget = parent.paginateTarget; |
| |
| this.altTargets.addAll(parent.altTargets); |
| this.actions = parent.actions; |
| this.rowActions = parent.rowActions; |
| this.defaultViewSize = parent.defaultViewSize; |
| this.onSubmitUpdateAreas = parent.onSubmitUpdateAreas; |
| this.onPaginateUpdateAreas = parent.onPaginateUpdateAreas; |
| this.onSortColumnUpdateAreas = parent.onSortColumnUpdateAreas; |
| this.altRowStyles = parent.altRowStyles; |
| |
| this.useWhenFields = parent.useWhenFields; |
| |
| // Create this fieldList/Map from clones of parent's |
| for (ModelFormField parentChildField: parent.fieldList) { |
| ModelFormField childField = new ModelFormField(this); |
| childField.mergeOverrideModelFormField(parentChildField); |
| this.fieldList.add(childField); |
| this.fieldMap.put(childField.getName(), childField); |
| } |
| |
| this.fieldGroupMap = parent.fieldGroupMap; |
| this.fieldGroupList = parent.fieldGroupList; |
| this.lastOrderFields = parent.lastOrderFields; |
| this.sortFieldParameterName = parent.sortFieldParameterName; |
| |
| } |
| } |
| |
| if (this.type == null || formElement.hasAttribute("type")) { |
| this.type = formElement.getAttribute("type"); |
| } |
| if (this.target == null || formElement.hasAttribute("target")) { |
| setTarget(formElement.getAttribute("target")); |
| } |
| if (this.targetWindowExdr == null || formElement.hasAttribute("target-window")) { |
| setTargetWindow(formElement.getAttribute("target-window")); |
| } |
| if (this.containerId == null || formElement.hasAttribute("id")) { |
| this.containerId = formElement.getAttribute("id"); |
| } |
| if (this.containerStyle == null || formElement.hasAttribute("style")) { |
| this.containerStyle = formElement.getAttribute("style"); |
| } |
| if (this.focusFieldName == null || formElement.hasAttribute("focus-field-name")) { |
| this.focusFieldName = formElement.getAttribute("focus-field-name"); |
| } |
| if (this.title == null || formElement.hasAttribute("title")) { |
| this.title = formElement.getAttribute("title"); |
| } |
| if (this.tooltip == null || formElement.hasAttribute("tooltip")) { |
| this.tooltip = formElement.getAttribute("tooltip"); |
| } |
| if (this.listName == null || formElement.hasAttribute("list-name")) { |
| this.listName = formElement.getAttribute("list-name"); |
| } |
| // if no list-name then look in the list-iterator-name; this is deprecated but we'll look at it anyway |
| if (UtilValidate.isEmpty(this.listName) && formElement.hasAttribute("list-iterator-name")) { |
| this.listName = formElement.getAttribute("list-iterator-name"); |
| } |
| if (this.listEntryName == null || formElement.hasAttribute("list-entry-name")) { |
| this.listEntryName = formElement.getAttribute("list-entry-name"); |
| } |
| if (this.defaultMapName == null || formElement.hasAttribute("default-map-name")) { |
| this.setDefaultMapName(formElement.getAttribute("default-map-name")); |
| } |
| if (this.defaultServiceName == null || formElement.hasAttribute("default-service-name")) { |
| this.defaultServiceName = formElement.getAttribute("default-service-name"); |
| } |
| if (this.defaultEntityName == null || formElement.hasAttribute("default-entity-name")) { |
| this.defaultEntityName = formElement.getAttribute("default-entity-name"); |
| } |
| |
| if (this.formTitleAreaStyle == null || formElement.hasAttribute("form-title-area-style")) { |
| this.formTitleAreaStyle = formElement.getAttribute("form-title-area-style"); |
| } |
| if (this.formWidgetAreaStyle == null || formElement.hasAttribute("form-widget-area-style")) { |
| this.formWidgetAreaStyle = formElement.getAttribute("form-widget-area-style"); |
| } |
| |
| if (this.defaultTitleAreaStyle == null || formElement.hasAttribute("default-title-area-style")) { |
| this.defaultTitleAreaStyle = formElement.getAttribute("default-title-area-style"); |
| } |
| if (this.defaultWidgetAreaStyle == null || formElement.hasAttribute("default-widget-area-style")) { |
| this.defaultWidgetAreaStyle = formElement.getAttribute("default-widget-area-style"); |
| } |
| if (this.oddRowStyle == null || formElement.hasAttribute("odd-row-style")) { |
| this.oddRowStyle = formElement.getAttribute("odd-row-style"); |
| } |
| if (this.evenRowStyle == null || formElement.hasAttribute("even-row-style")) { |
| this.evenRowStyle = formElement.getAttribute("even-row-style"); |
| } |
| if (this.defaultTableStyle == null || formElement.hasAttribute("default-table-style")) { |
| this.defaultTableStyle = formElement.getAttribute("default-table-style"); |
| } |
| if (this.headerRowStyle == null || formElement.hasAttribute("header-row-style")) { |
| this.headerRowStyle = formElement.getAttribute("header-row-style"); |
| } |
| if (this.defaultTitleStyle == null || formElement.hasAttribute("header-row-style")) { |
| this.defaultTitleStyle = formElement.getAttribute("default-title-style"); |
| } |
| if (this.defaultWidgetStyle == null || formElement.hasAttribute("default-widget-style")) { |
| this.defaultWidgetStyle = formElement.getAttribute("default-widget-style"); |
| } |
| if (this.defaultTooltipStyle == null || formElement.hasAttribute("default-tooltip-style")) { |
| this.defaultTooltipStyle = formElement.getAttribute("default-tooltip-style"); |
| } |
| if (this.itemIndexSeparator == null || formElement.hasAttribute("item-index-separator")) { |
| this.itemIndexSeparator = formElement.getAttribute("item-index-separator"); |
| } |
| if (this.targetType == null || formElement.hasAttribute("target-type")) { |
| this.targetType = formElement.getAttribute("target-type"); |
| } |
| if (this.defaultRequiredFieldStyle == null || formElement.hasAttribute("default-required-field-style")) { |
| this.defaultRequiredFieldStyle = formElement.getAttribute("default-required-field-style"); |
| } |
| if (this.defaultSortFieldStyle == null || formElement.hasAttribute("default-sort-field-style")) { |
| this.defaultSortFieldStyle = formElement.getAttribute("default-sort-field-style"); |
| } |
| if (this.defaultSortFieldAscStyle == null || formElement.hasAttribute("default-sort-field-asc-style")) { |
| this.defaultSortFieldAscStyle = formElement.getAttribute("default-sort-field-asc-style"); |
| } |
| if (this.defaultSortFieldDescStyle == null || formElement.hasAttribute("default-sort-field-desc-style")) { |
| this.defaultSortFieldDescStyle = formElement.getAttribute("default-sort-field-desc-style"); |
| } |
| |
| // pagination settings |
| if (this.paginateTarget == null || formElement.hasAttribute("paginate-target")) { |
| setPaginateTarget(formElement.getAttribute("paginate-target")); |
| } |
| if (this.paginateTargetAnchor == null || formElement.hasAttribute("paginate-target-anchor")) { |
| this.paginateTargetAnchor = formElement.getAttribute("paginate-target-anchor"); |
| } |
| if (this.paginateIndexField == null || formElement.hasAttribute("paginate-index-field")) { |
| setPaginateIndexField(formElement.getAttribute("paginate-index-field")); |
| } |
| if (this.paginateSizeField == null || formElement.hasAttribute("paginate-size-field")) { |
| setPaginateSizeField(formElement.getAttribute("paginate-size-field")); |
| } |
| if (this.overrideListSize == null || formElement.hasAttribute("override-list-size")) { |
| this.overrideListSize = FlexibleStringExpander.getInstance(formElement.getAttribute("override-list-size")); |
| } |
| if (this.paginateFirstLabel == null || formElement.hasAttribute("paginate-first-label")) { |
| this.paginateFirstLabel = FlexibleStringExpander.getInstance(formElement.getAttribute("paginate-first-label")); |
| } |
| if (this.paginatePreviousLabel == null || formElement.hasAttribute("paginate-previous-label")) { |
| this.paginatePreviousLabel = FlexibleStringExpander.getInstance(formElement.getAttribute("paginate-previous-label")); |
| } |
| if (this.paginateNextLabel == null || formElement.hasAttribute("paginate-next-label")) { |
| this.paginateNextLabel = FlexibleStringExpander.getInstance(formElement.getAttribute("paginate-next-label")); |
| } |
| if (this.paginateLastLabel == null || formElement.hasAttribute("paginate-last-label")) { |
| this.paginateLastLabel = FlexibleStringExpander.getInstance(formElement.getAttribute("paginate-last-label")); |
| } |
| if (this.paginateViewSizeLabel == null || formElement.hasAttribute("paginate-viewsize-label")) { |
| this.paginateViewSizeLabel = FlexibleStringExpander.getInstance(formElement.getAttribute("paginate-viewsize-label")); |
| } |
| if (this.paginateStyle == null || formElement.hasAttribute("paginate-style")) { |
| setPaginateStyle(formElement.getAttribute("paginate-style")); |
| } |
| if (this.paginate == null || formElement.hasAttribute("paginate")) { |
| this.paginate = FlexibleStringExpander.getInstance(formElement.getAttribute("paginate")); |
| } |
| String sortFieldParameterName = formElement.getAttribute("sort-field-parameter-name"); |
| if (!sortFieldParameterName.isEmpty()) { |
| this.sortFieldParameterName = sortFieldParameterName; |
| } |
| this.skipStart = "true".equals(formElement.getAttribute("skip-start")); |
| this.skipEnd = "true".equals(formElement.getAttribute("skip-end")); |
| this.hideHeader = "true".equals(formElement.getAttribute("hide-header")); |
| this.clientAutocompleteFields = !"false".equals(formElement.getAttribute("client-autocomplete-fields")); |
| if (formElement.hasAttribute("separate-columns")) { |
| String sepColumns = formElement.getAttribute("separate-columns"); |
| if (sepColumns != null && sepColumns.equalsIgnoreCase("true")) |
| separateColumns = true; |
| } |
| if (formElement.hasAttribute("group-columns")) { |
| String groupColumnsStr = formElement.getAttribute("group-columns"); |
| if (groupColumnsStr != null && groupColumnsStr.equalsIgnoreCase("false")) |
| groupColumns = false; |
| } |
| if (formElement.hasAttribute("use-row-submit")) { |
| String rowSubmit = formElement.getAttribute("use-row-submit"); |
| if (rowSubmit != null && rowSubmit.equalsIgnoreCase("true")) |
| useRowSubmit = true; |
| } |
| if (formElement.hasAttribute("view-size")) { |
| setDefaultViewSize(formElement.getAttribute("view-size")); |
| } |
| if (this.rowCountExdr == null || formElement.hasAttribute("row-count")) { |
| this.rowCountExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("row-count")); |
| } |
| |
| //alt-row-styles |
| for (Element altRowStyleElement : UtilXml.childElementList(formElement, "alt-row-style")) { |
| AltRowStyle altRowStyle = new AltRowStyle(altRowStyleElement); |
| this.altRowStyles.add(altRowStyle); |
| } |
| |
| // alt-target |
| for (Element altTargetElement: UtilXml.childElementList(formElement, "alt-target")) { |
| AltTarget altTarget = new AltTarget(altTargetElement); |
| this.addAltTarget(altTarget); |
| } |
| |
| // on-event-update-area |
| for (Element updateAreaElement : UtilXml.childElementList(formElement, "on-event-update-area")) { |
| UpdateArea updateArea = new UpdateArea(updateAreaElement); |
| this.addOnEventUpdateArea(updateArea); |
| } |
| //propagate defaultEntityName on updateAreas |
| if (UtilValidate.isNotEmpty(this.defaultEntityName)) this.setDefaultEntityNameOnUpdateAreas(); |
| if (UtilValidate.isNotEmpty(this.defaultServiceName)) this.setDefaultServiceNameOnUpdateAreas(); |
| |
| // auto-fields-service |
| for (Element autoFieldsServiceElement: UtilXml.childElementList(formElement, "auto-fields-service")) { |
| AutoFieldsService autoFieldsService = new AutoFieldsService(autoFieldsServiceElement); |
| this.addAutoFieldsFromService(autoFieldsService); |
| } |
| |
| // auto-fields-entity |
| for (Element autoFieldsEntityElement: UtilXml.childElementList(formElement, "auto-fields-entity")) { |
| AutoFieldsEntity autoFieldsEntity = new AutoFieldsEntity(autoFieldsEntityElement); |
| this.addAutoFieldsFromEntity(autoFieldsEntity); |
| } |
| |
| // read in add field defs, add/override one by one using the fieldList and fieldMap |
| String thisType = this.getType(); |
| for (Element fieldElement: UtilXml.childElementList(formElement, "field")) { |
| ModelFormField modelFormField = new ModelFormField(fieldElement, this); |
| ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo(); |
| if (thisType.equals("multi") && fieldInfo instanceof ModelFormField.SubmitField) { |
| multiSubmitFields.add(modelFormField); |
| } else { |
| modelFormField = this.addUpdateField(modelFormField); |
| } |
| } |
| |
| // Create the default field group |
| defaultFieldGroup = new FieldGroup(null, this); |
| // get the sort-order |
| Element sortOrderElement = UtilXml.firstChildElement(formElement, "sort-order"); |
| if (sortOrderElement != null) { |
| FieldGroup lastFieldGroup = new FieldGroup(null, this); |
| this.fieldGroupList.add(lastFieldGroup); |
| // read in sort-field |
| for (Element sortFieldElement: UtilXml.childElementList(sortOrderElement)) { |
| String tagName = sortFieldElement.getTagName(); |
| if (tagName.equals("sort-field")) { |
| String fieldName = sortFieldElement.getAttribute("name"); |
| String position = sortFieldElement.getAttribute("position"); |
| this.sortOrderFields.add(new SortField(fieldName, position)); |
| this.fieldGroupMap.put(fieldName, lastFieldGroup); |
| } else if (tagName.equals("last-field")) { |
| String fieldName = sortFieldElement.getAttribute("name"); |
| this.fieldGroupMap.put(fieldName, lastFieldGroup); |
| this.lastOrderFields.add(fieldName); |
| } else if (tagName.equals("banner")) { |
| Banner thisBanner = new Banner(sortFieldElement, this); |
| this.fieldGroupList.add(thisBanner); |
| |
| lastFieldGroup = new FieldGroup(null, this); |
| this.fieldGroupList.add(lastFieldGroup); |
| } else if (tagName.equals("field-group")) { |
| FieldGroup thisFieldGroup = new FieldGroup(sortFieldElement, this); |
| this.fieldGroupList.add(thisFieldGroup); |
| |
| lastFieldGroup = new FieldGroup(null, this); |
| this.fieldGroupList.add(lastFieldGroup); |
| } |
| } |
| } |
| |
| // reorder fields according to sort order |
| if (sortOrderFields.size() > 0) { |
| List<ModelFormField> sortedFields = FastList.newInstance(); |
| for (SortField sortField: this.sortOrderFields) { |
| String fieldName = sortField.getFieldName(); |
| if (UtilValidate.isEmpty(fieldName)) { |
| continue; |
| } |
| |
| // get all fields with the given name from the existing list and put them in the sorted list |
| Iterator<ModelFormField> fieldIter = this.fieldList.iterator(); |
| while (fieldIter.hasNext()) { |
| ModelFormField modelFormField = fieldIter.next(); |
| if (fieldName.equals(modelFormField.getName())) { |
| // matched the name; remove from the original last and add to the sorted list |
| if (UtilValidate.isNotEmpty(sortField.getPosition())) { |
| modelFormField.setPosition(sortField.getPosition()); |
| } |
| fieldIter.remove(); |
| sortedFields.add(modelFormField); |
| } |
| } |
| } |
| // now add all of the rest of the fields from fieldList, ie those that were not explicitly listed in the sort order |
| sortedFields.addAll(this.fieldList); |
| // sortedFields all done, set fieldList |
| this.fieldList = sortedFields; |
| } |
| |
| if (UtilValidate.isNotEmpty(this.lastOrderFields)) { |
| List<ModelFormField> lastedFields = FastList.newInstance(); |
| for (String fieldName: this.lastOrderFields) { |
| if (UtilValidate.isEmpty(fieldName)) { |
| continue; |
| } |
| // get all fields with the given name from the existing list and put them in the lasted list |
| Iterator<ModelFormField> fieldIter = this.fieldList.iterator(); |
| while (fieldIter.hasNext()) { |
| ModelFormField modelFormField = fieldIter.next(); |
| if (fieldName.equals(modelFormField.getName())) { |
| // matched the name; remove from the original last and add to the lasted list |
| fieldIter.remove(); |
| lastedFields.add(modelFormField); |
| } |
| } |
| } |
| //now put all lastedFields at the field list end |
| this.fieldList.addAll(lastedFields); |
| } |
| |
| // read all actions under the "actions" element |
| Element actionsElement = UtilXml.firstChildElement(formElement, "actions"); |
| if (actionsElement != null) { |
| this.actions = ModelFormAction.readSubActions(this, actionsElement); |
| } |
| |
| // read all actions under the "row-actions" element |
| Element rowActionsElement = UtilXml.firstChildElement(formElement, "row-actions"); |
| if (rowActionsElement != null) { |
| this.rowActions = ModelFormAction.readSubActions(this, rowActionsElement); |
| } |
| } |
| |
| /** |
| * add/override modelFormField using the fieldList and fieldMap |
| * |
| * @return The same ModelFormField, or if merged with an existing field, the existing field. |
| */ |
| public ModelFormField addUpdateField(ModelFormField modelFormField) { |
| if (!modelFormField.isUseWhenEmpty() || useWhenFields.contains(modelFormField.getName())) { |
| useWhenFields.add(modelFormField.getName()); |
| // is a conditional field, add to the List but don't worry about the Map |
| //for adding to list, see if there is another field with that name in the list and if so, put it before that one |
| boolean inserted = false; |
| for (int i = 0; i < this.fieldList.size(); i++) { |
| ModelFormField curField = this.fieldList.get(i); |
| if (curField.getName() != null && curField.getName().equals(modelFormField.getName())) { |
| this.fieldList.add(i, modelFormField); |
| inserted = true; |
| break; |
| } |
| } |
| if (!inserted) { |
| this.fieldList.add(modelFormField); |
| } |
| return modelFormField; |
| } else { |
| |
| // not a conditional field, see if a named field exists in Map |
| ModelFormField existingField = this.fieldMap.get(modelFormField.getName()); |
| if (existingField != null) { |
| // does exist, update the field by doing a merge/override |
| existingField.mergeOverrideModelFormField(modelFormField); |
| return existingField; |
| } else { |
| // does not exist, add to List and Map |
| this.fieldList.add(modelFormField); |
| this.fieldMap.put(modelFormField.getName(), modelFormField); |
| return modelFormField; |
| } |
| } |
| } |
| |
| public void addAltTarget(AltTarget altTarget) { |
| int index = altTargets.indexOf(altTarget); |
| if (index != -1) { |
| altTargets.set(index, altTarget); |
| } else { |
| altTargets.add(altTarget); |
| } |
| } |
| |
| public void addOnEventUpdateArea(UpdateArea updateArea) { |
| // Event types are sorted as a convenience |
| // for the rendering classes |
| if ("paginate".equals(updateArea.getEventType())) { |
| addOnPaginateUpdateArea(updateArea); |
| } else if ("submit".equals(updateArea.getEventType())) { |
| addOnSubmitUpdateArea(updateArea); |
| } else if ("sort-column".equals(updateArea.getEventType())) { |
| addOnSortColumnUpdateArea(updateArea); |
| } |
| } |
| |
| protected void addOnSubmitUpdateArea(UpdateArea updateArea) { |
| if (onSubmitUpdateAreas == null) { |
| onSubmitUpdateAreas = FastList.newInstance(); |
| } |
| int index = onSubmitUpdateAreas.indexOf(updateArea); |
| if (index != -1) { |
| onSubmitUpdateAreas.set(index, updateArea); |
| } else { |
| onSubmitUpdateAreas.add(updateArea); |
| } |
| } |
| |
| protected void addOnPaginateUpdateArea(UpdateArea updateArea) { |
| if (onPaginateUpdateAreas == null) { |
| onPaginateUpdateAreas = FastList.newInstance(); |
| } |
| int index = onPaginateUpdateAreas.indexOf(updateArea); |
| if (index != -1) { |
| if (UtilValidate.isNotEmpty(updateArea.areaTarget)) { |
| onPaginateUpdateAreas.set(index, updateArea); |
| } else { |
| // blank target indicates a removing override |
| onPaginateUpdateAreas.remove(index); |
| } |
| } else { |
| onPaginateUpdateAreas.add(updateArea); |
| } |
| } |
| |
| protected void addOnSortColumnUpdateArea(UpdateArea updateArea) { |
| if (onSortColumnUpdateAreas == null) { |
| onSortColumnUpdateAreas = FastList.newInstance(); |
| } |
| int index = onSortColumnUpdateAreas.indexOf(updateArea); |
| if (index != -1) { |
| if (UtilValidate.isNotEmpty(updateArea.areaTarget)) { |
| onSortColumnUpdateAreas.set(index, updateArea); |
| } else { |
| // blank target indicates a removing override |
| onSortColumnUpdateAreas.remove(index); |
| } |
| } else { |
| onSortColumnUpdateAreas.add(updateArea); |
| } |
| } |
| |
| public void addAutoFieldsFromService(AutoFieldsService autoFieldsService) { |
| autoFieldsServices.add(autoFieldsService); |
| |
| // read service def and auto-create fields |
| ModelService modelService = null; |
| try { |
| modelService = this.dispatchContext.getModelService(autoFieldsService.serviceName); |
| } catch (GenericServiceException e) { |
| String errmsg = "Error finding Service with name " + autoFieldsService.serviceName + " for auto-fields-service in a form widget"; |
| Debug.logError(e, errmsg, module); |
| throw new IllegalArgumentException(errmsg); |
| } |
| |
| for (ModelParam modelParam: modelService.getInModelParamList()) { |
| // skip auto params that the service engine populates... |
| if ("userLogin".equals(modelParam.name) || "locale".equals(modelParam.name) || "timeZone".equals(modelParam.name) || "login.username".equals(modelParam.name) || "login.password".equals(modelParam.name)) { |
| continue; |
| } |
| if (modelParam.formDisplay) { |
| if (UtilValidate.isNotEmpty(modelParam.entityName) && UtilValidate.isNotEmpty(modelParam.fieldName)) { |
| ModelEntity modelEntity; |
| try { |
| modelEntity = this.entityModelReader.getModelEntity(modelParam.entityName); |
| if (modelEntity != null) { |
| ModelField modelField = modelEntity.getField(modelParam.fieldName); |
| if (modelField != null) { |
| // okay, populate using the entity field info... |
| ModelFormField modelFormField = this.addFieldFromEntityField(modelEntity, modelField, autoFieldsService.defaultFieldType, autoFieldsService.defaultPosition); |
| if (UtilValidate.isNotEmpty(autoFieldsService.mapName)) { |
| modelFormField.setMapName(autoFieldsService.mapName); |
| } |
| modelFormField.setRequiredField(!modelParam.optional); |
| // continue to skip creating based on service param |
| continue; |
| } |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| } |
| |
| ModelFormField modelFormField = this.addFieldFromServiceParam(modelService, modelParam, autoFieldsService.defaultFieldType, autoFieldsService.defaultPosition); |
| if (UtilValidate.isNotEmpty(autoFieldsService.mapName)) { |
| modelFormField.setMapName(autoFieldsService.mapName); |
| } |
| } |
| } |
| } |
| |
| public ModelFormField addFieldFromServiceParam(ModelService modelService, ModelParam modelParam, String defaultFieldType, int defaultPosition) { |
| // create field def from service param def |
| ModelFormField newFormField = new ModelFormField(this); |
| newFormField.setName(modelParam.name); |
| newFormField.setServiceName(modelService.name); |
| newFormField.setAttributeName(modelParam.name); |
| newFormField.setTitle(modelParam.formLabel); |
| newFormField.setRequiredField(!modelParam.optional); |
| newFormField.induceFieldInfoFromServiceParam(modelService, modelParam, defaultFieldType); |
| newFormField.setPosition(defaultPosition); |
| return this.addUpdateField(newFormField); |
| } |
| |
| public void addAutoFieldsFromEntity(AutoFieldsEntity autoFieldsEntity) { |
| autoFieldsEntities.add(autoFieldsEntity); |
| // read entity def and auto-create fields |
| ModelEntity modelEntity = null; |
| try { |
| modelEntity = this.entityModelReader.getModelEntity(autoFieldsEntity.entityName); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| if (modelEntity == null) { |
| throw new IllegalArgumentException("Error finding Entity with name " + autoFieldsEntity.entityName + " for auto-fields-entity in a form widget"); |
| } |
| |
| Iterator<ModelField> modelFieldIter = modelEntity.getFieldsIterator(); |
| while (modelFieldIter.hasNext()) { |
| ModelField modelField = modelFieldIter.next(); |
| if (modelField.getIsAutoCreatedInternal()) { |
| // don't ever auto-add these, should only be added if explicitly referenced |
| continue; |
| } |
| ModelFormField modelFormField = this.addFieldFromEntityField(modelEntity, modelField, autoFieldsEntity.defaultFieldType, autoFieldsEntity.defaultPosition); |
| if (UtilValidate.isNotEmpty(autoFieldsEntity.mapName)) { |
| modelFormField.setMapName(autoFieldsEntity.mapName); |
| } |
| } |
| } |
| |
| public ModelFormField addFieldFromEntityField(ModelEntity modelEntity, ModelField modelField, String defaultFieldType, int defaultPosition) { |
| // create field def from entity field def |
| ModelFormField newFormField = new ModelFormField(this); |
| newFormField.setName(modelField.getName()); |
| newFormField.setEntityName(modelEntity.getEntityName()); |
| newFormField.setFieldName(modelField.getName()); |
| newFormField.induceFieldInfoFromEntityField(modelEntity, modelField, defaultFieldType); |
| newFormField.setPosition(defaultPosition); |
| return this.addUpdateField(newFormField); |
| } |
| |
| public void runFormActions(Map<String, Object> context) { |
| ModelFormAction.runSubActions(this.actions, context); |
| } |
| |
| /** |
| * Renders this form to a String, i.e. in a text format, as defined with the |
| * FormStringRenderer implementation. |
| * |
| * @param writer The Writer that the form text will be written to |
| * @param context Map containing the form context; the following are |
| * reserved words in this context: parameters (Map), isError (Boolean), |
| * itemIndex (Integer, for lists only, otherwise null), bshInterpreter, |
| * formName (String, optional alternate name for form, defaults to the |
| * value of the name attribute) |
| * @param formStringRenderer An implementation of the FormStringRenderer |
| * interface that is responsible for the actual text generation for |
| * different form elements; implementing your own makes it possible to |
| * use the same form definitions for many types of form UIs |
| */ |
| public void renderFormString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) throws IOException { |
| // increment the paginator, only for list and multi forms |
| if ("list".equals(this.type) || "multi".equals(this.type)) { |
| WidgetWorker.incrementPaginatorNumber(context); |
| } |
| |
| //if pagination is disabled, update the defualt view size |
| if (!getPaginate(context)) { |
| setDefaultViewSize(ModelForm.MAX_PAGE_SIZE); |
| } |
| |
| // Populate the viewSize and viewIndex so they are available for use during form actions |
| context.put("viewIndex", this.getViewIndex(context)); |
| context.put("viewSize", this.getViewSize(context)); |
| |
| runFormActions(context); |
| |
| // if this is a list form, don't useRequestParameters |
| if ("list".equals(this.type) || "multi".equals(this.type)) { |
| context.put("useRequestParameters", Boolean.FALSE); |
| } |
| |
| // find the highest position number to get the max positions used |
| int positions = 1; |
| for (ModelFormField modelFormField: this.fieldList) { |
| int curPos = modelFormField.getPosition(); |
| if (curPos > positions) { |
| positions = curPos; |
| } |
| ModelFormField.FieldInfo currentFieldInfo = modelFormField.getFieldInfo(); |
| if (currentFieldInfo != null) { |
| ModelFormField fieldInfoFormField = currentFieldInfo.getModelFormField(); |
| if (fieldInfoFormField != null) { |
| fieldInfoFormField.setModelForm(this); |
| } |
| } else { |
| throw new IllegalArgumentException("Error rendering form, a field has no FieldInfo, ie no sub-element for the type of field for field named: " + modelFormField.getName()); |
| } |
| } |
| |
| if ("single".equals(this.type)) { |
| this.renderSingleFormString(writer, context, formStringRenderer, positions); |
| } else if ("list".equals(this.type)) { |
| this.renderListFormString(writer, context, formStringRenderer, positions); |
| } else if ("multi".equals(this.type)) { |
| this.renderMultiFormString(writer, context, formStringRenderer, positions); |
| } else if ("upload".equals(this.type)) { |
| this.renderSingleFormString(writer, context, formStringRenderer, positions); |
| } else { |
| if (UtilValidate.isEmpty(this.getType())) { |
| throw new IllegalArgumentException("The form 'type' tag is missing or empty on the form with the name " + this.getName()); |
| } else { |
| throw new IllegalArgumentException("The form type " + this.getType() + " is not supported for form with name " + this.getName()); |
| } |
| } |
| } |
| |
| public void renderSingleFormString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer, int positions) throws IOException { |
| List<ModelFormField> tempFieldList = FastList.newInstance(); |
| tempFieldList.addAll(this.fieldList); |
| |
| // Check to see if there is a field, same name and same use-when (could come from extended form) |
| for (int j = 0; j < tempFieldList.size(); j++) { |
| ModelFormField modelFormField = tempFieldList.get(j); |
| if (this.useWhenFields.contains(modelFormField.getName())) { |
| boolean shouldUse1 = modelFormField.shouldUse(context); |
| for (int i = j+1; i < tempFieldList.size(); i++) { |
| ModelFormField curField = tempFieldList.get(i); |
| if (curField.getName() != null && curField.getName().equals(modelFormField.getName())) { |
| boolean shouldUse2 = curField.shouldUse(context); |
| if (shouldUse1 == shouldUse2) { |
| tempFieldList.remove(i--); |
| } |
| } else { |
| continue; |
| } |
| } |
| } |
| } |
| |
| Set<String> alreadyRendered = new TreeSet<String>(); |
| FieldGroup lastFieldGroup = null; |
| // render form open |
| if (!skipStart) formStringRenderer.renderFormOpen(writer, context, this); |
| |
| // render all hidden & ignored fields |
| List<ModelFormField> hiddenIgnoredFieldList = this.getHiddenIgnoredFields(context, alreadyRendered, tempFieldList, -1); |
| this.renderHiddenIgnoredFields(writer, context, formStringRenderer, hiddenIgnoredFieldList); |
| |
| // render formatting wrapper open |
| // This should be covered by fieldGroup.renderStartString |
| //formStringRenderer.renderFormatSingleWrapperOpen(writer, context, this); |
| |
| // render each field row, except hidden & ignored rows |
| Iterator<ModelFormField> fieldIter = tempFieldList.iterator(); |
| ModelFormField lastFormField = null; |
| ModelFormField currentFormField = null; |
| ModelFormField nextFormField = null; |
| if (fieldIter.hasNext()) { |
| currentFormField = fieldIter.next(); |
| } |
| if (fieldIter.hasNext()) { |
| nextFormField = fieldIter.next(); |
| } |
| |
| FieldGroup currentFieldGroup = null; |
| String currentFieldGroupName = null; |
| String lastFieldGroupName = null; |
| if (currentFormField != null) { |
| currentFieldGroup = (FieldGroup)fieldGroupMap.get(currentFormField.getFieldName()); |
| if (currentFieldGroup == null) { |
| currentFieldGroup = defaultFieldGroup; |
| } |
| if (currentFieldGroup != null) { |
| currentFieldGroupName = currentFieldGroup.getId(); |
| } |
| } |
| |
| |
| boolean isFirstPass = true; |
| boolean haveRenderedOpenFieldRow = false; |
| while (currentFormField != null) { |
| // do the check/get next stuff at the beginning so we can still use the continue stuff easily |
| // don't do it on the first pass though... |
| if (isFirstPass) { |
| isFirstPass = false; |
| List<FieldGroupBase> inbetweenList = getInbetweenList(lastFieldGroup, currentFieldGroup); |
| for (FieldGroupBase obj: inbetweenList) { |
| if (obj instanceof ModelForm.Banner) { |
| ((ModelForm.Banner) obj).renderString(writer, context, formStringRenderer); |
| } |
| } |
| if (currentFieldGroup != null && (lastFieldGroup == null || !lastFieldGroupName.equals(currentFieldGroupName))) { |
| currentFieldGroup.renderStartString(writer, context, formStringRenderer); |
| lastFieldGroup = currentFieldGroup; |
| } |
| } else { |
| if (fieldIter.hasNext()) { |
| // at least two loops left |
| lastFormField = currentFormField; |
| currentFormField = nextFormField; |
| nextFormField = fieldIter.next(); |
| } else if (nextFormField != null) { |
| // okay, just one loop left |
| lastFormField = currentFormField; |
| currentFormField = nextFormField; |
| nextFormField = null; |
| } else { |
| // at the end... |
| lastFormField = currentFormField; |
| currentFormField = null; |
| // nextFormField is already null |
| break; |
| } |
| currentFieldGroup = null; |
| if (currentFormField != null) { |
| currentFieldGroup = (FieldGroup) fieldGroupMap.get(currentFormField.getName()); |
| } |
| if (currentFieldGroup == null) { |
| currentFieldGroup = defaultFieldGroup; |
| } |
| currentFieldGroupName = currentFieldGroup.getId(); |
| |
| if (lastFieldGroup != null) { |
| lastFieldGroupName = lastFieldGroup.getId(); |
| if (!lastFieldGroupName.equals(currentFieldGroupName)) { |
| if (haveRenderedOpenFieldRow) { |
| formStringRenderer.renderFormatFieldRowClose(writer, context, this); |
| haveRenderedOpenFieldRow = false; |
| } |
| lastFieldGroup.renderEndString(writer, context, formStringRenderer); |
| |
| List<FieldGroupBase> inbetweenList = getInbetweenList(lastFieldGroup, currentFieldGroup); |
| for (FieldGroupBase obj: inbetweenList) { |
| if (obj instanceof ModelForm.Banner) { |
| ((ModelForm.Banner) obj).renderString(writer, context, formStringRenderer); |
| } |
| } |
| } |
| } |
| |
| if (lastFieldGroup == null || !lastFieldGroupName.equals(currentFieldGroupName)) { |
| currentFieldGroup.renderStartString(writer, context, formStringRenderer); |
| lastFieldGroup = currentFieldGroup; |
| } |
| } |
| |
| ModelFormField.FieldInfo fieldInfo = currentFormField.getFieldInfo(); |
| if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) { |
| continue; |
| } |
| if (alreadyRendered.contains(currentFormField.getName())) { |
| continue; |
| } |
| //Debug.logInfo("In single form evaluating use-when for field " + currentFormField.getName() + ": " + currentFormField.getUseWhen(), module); |
| if (!currentFormField.shouldUse(context)) { |
| if (UtilValidate.isNotEmpty(lastFormField)) { |
| currentFormField = lastFormField; |
| } |
| continue; |
| } |
| alreadyRendered.add(currentFormField.getName()); |
| |
| boolean stayingOnRow = false; |
| if (lastFormField != null) { |
| if (lastFormField.getPosition() >= currentFormField.getPosition()) { |
| // moving to next row |
| stayingOnRow = false; |
| } else { |
| // staying on same row |
| stayingOnRow = true; |
| } |
| } |
| |
| int positionSpan = 1; |
| Integer nextPositionInRow = null; |
| if (nextFormField != null) { |
| if (nextFormField.getPosition() > currentFormField.getPosition()) { |
| positionSpan = nextFormField.getPosition() - currentFormField.getPosition() - 1; |
| nextPositionInRow = Integer.valueOf(nextFormField.getPosition()); |
| } else { |
| positionSpan = positions - currentFormField.getPosition(); |
| if (!stayingOnRow && nextFormField.getPosition() > 1) { |
| // TODO: here is a weird case where it is setup such |
| //that the first position(s) in the row are skipped |
| // not sure what to do about this right now... |
| } |
| } |
| } |
| |
| if (stayingOnRow) { |
| // no spacer cell, might add later though... |
| //formStringRenderer.renderFormatFieldRowSpacerCell(writer, context, currentFormField); |
| } else { |
| if (haveRenderedOpenFieldRow) { |
| // render row formatting close |
| formStringRenderer.renderFormatFieldRowClose(writer, context, this); |
| haveRenderedOpenFieldRow = false; |
| } |
| |
| // render row formatting open |
| formStringRenderer.renderFormatFieldRowOpen(writer, context, this); |
| haveRenderedOpenFieldRow = true; |
| } |
| |
| // |
| // It must be a row open before rendering a field. If not, open it |
| // |
| if (!haveRenderedOpenFieldRow) { |
| formStringRenderer.renderFormatFieldRowOpen(writer, context, this); |
| haveRenderedOpenFieldRow = true; |
| } |
| |
| // render title formatting open |
| formStringRenderer.renderFormatFieldRowTitleCellOpen(writer, context, currentFormField); |
| |
| // render title (unless this is a submit or a reset field) |
| if (fieldInfo.getFieldType() != ModelFormField.FieldInfo.SUBMIT && fieldInfo.getFieldType() != ModelFormField.FieldInfo.RESET) { |
| formStringRenderer.renderFieldTitle(writer, context, currentFormField); |
| } else { |
| formStringRenderer.renderFormatEmptySpace(writer, context, this); |
| } |
| |
| // render title formatting close |
| formStringRenderer.renderFormatFieldRowTitleCellClose(writer, context, currentFormField); |
| |
| // render separator |
| formStringRenderer.renderFormatFieldRowSpacerCell(writer, context, currentFormField); |
| |
| // render widget formatting open |
| formStringRenderer.renderFormatFieldRowWidgetCellOpen(writer, context, currentFormField, positions, positionSpan, nextPositionInRow); |
| |
| // render widget |
| currentFormField.renderFieldString(writer, context, formStringRenderer); |
| |
| // render widget formatting close |
| formStringRenderer.renderFormatFieldRowWidgetCellClose(writer, context, currentFormField, positions, positionSpan, nextPositionInRow); |
| |
| } |
| // render row formatting close after the end if needed |
| if (haveRenderedOpenFieldRow) { |
| formStringRenderer.renderFormatFieldRowClose(writer, context, this); |
| } |
| |
| if (lastFieldGroup != null) { |
| lastFieldGroup.renderEndString(writer, context, formStringRenderer); |
| } |
| // render formatting wrapper close |
| // should be handled by renderEndString |
| //formStringRenderer.renderFormatSingleWrapperClose(writer, context, this); |
| |
| // render form close |
| if (!skipEnd) formStringRenderer.renderFormClose(writer, context, this); |
| |
| } |
| |
| public void renderListFormString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer, int positions) throws IOException { |
| // render list/tabular type forms |
| |
| // prepare the items iterator and compute the pagination parameters |
| this.preparePager(context); |
| |
| // render formatting wrapper open |
| formStringRenderer.renderFormatListWrapperOpen(writer, context, this); |
| |
| int numOfColumns = 0; |
| // ===== render header row ===== |
| if (!getHideHeader()) { |
| numOfColumns = this.renderHeaderRow(writer, context, formStringRenderer); |
| } |
| |
| // ===== render the item rows ===== |
| this.renderItemRows(writer, context, formStringRenderer, true, numOfColumns); |
| |
| // render formatting wrapper close |
| formStringRenderer.renderFormatListWrapperClose(writer, context, this); |
| |
| } |
| |
| public void renderMultiFormString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer, int positions) throws IOException { |
| if (!skipStart) { |
| formStringRenderer.renderFormOpen(writer, context, this); |
| } |
| |
| // prepare the items iterator and compute the pagination parameters |
| this.preparePager(context); |
| |
| // render formatting wrapper open |
| formStringRenderer.renderFormatListWrapperOpen(writer, context, this); |
| |
| int numOfColumns = 0; |
| // ===== render header row ===== |
| if (!getHideHeader()) { |
| numOfColumns = this.renderHeaderRow(writer, context, formStringRenderer); |
| } |
| |
| // ===== render the item rows ===== |
| this.renderItemRows(writer, context, formStringRenderer, false, numOfColumns); |
| |
| formStringRenderer.renderFormatListWrapperClose(writer, context, this); |
| |
| if (!skipEnd) { |
| formStringRenderer.renderMultiFormClose(writer, context, this); |
| } |
| |
| } |
| |
| public int renderHeaderRow(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) throws IOException { |
| int maxNumOfColumns = 0; |
| |
| // We will render one title/column for all the fields with the same name |
| // in this model: we can have more fields with the same name when use-when |
| // conditions are used or when a form is extended or when the fields are |
| // automatically retrieved by a service or entity definition. |
| List<ModelFormField> tempFieldList = FastList.newInstance(); |
| tempFieldList.addAll(this.fieldList); |
| for (int j = 0; j < tempFieldList.size(); j++) { |
| ModelFormField modelFormField = tempFieldList.get(j); |
| for (int i = j+1; i < tempFieldList.size(); i++) { |
| ModelFormField curField = tempFieldList.get(i); |
| if (curField.getName() != null && curField.getName().equals(modelFormField.getName())) { |
| tempFieldList.remove(i--); |
| } |
| } |
| } |
| |
| // =========================== |
| // Preprocessing |
| // =========================== |
| // We get a sorted (by position, ascending) set of lists; |
| // each list contains all the fields with that position. |
| Collection<List<ModelFormField>> fieldListsByPosition = this.getFieldListsByPosition(tempFieldList); |
| List<Map<String, List<ModelFormField>>> fieldRowsByPosition = FastList.newInstance(); // this list will contain maps, each one containing the list of fields for a position |
| for (List<ModelFormField> mainFieldList: fieldListsByPosition) { |
| int numOfColumns = 0; |
| |
| List<ModelFormField> innerDisplayHyperlinkFieldsBegin = FastList.newInstance(); |
| List<ModelFormField> innerFormFields = FastList.newInstance(); |
| List<ModelFormField> innerDisplayHyperlinkFieldsEnd = FastList.newInstance(); |
| |
| // render title for each field, except hidden & ignored, etc |
| |
| // start by rendering all display and hyperlink fields, until we |
| //get to a field that should go into the form cell, then render |
| //the form cell with all non-display and non-hyperlink fields, then |
| //do a start after the first form input field and |
| //render all display and hyperlink fields after the form |
| |
| // prepare the two lists of display and hyperlink fields |
| // the fields in the first list will be rendered as columns before the |
| // combined column for the input fields; the fields in the second list |
| // will be rendered as columns after it |
| boolean inputFieldFound = false; |
| for (ModelFormField modelFormField: mainFieldList) { |
| ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo(); |
| |
| // if the field's title is explicitly set to "" (title="") then |
| // the header is not created for it; this is useful for position list |
| // where one line can be rendered with more than one row, and we |
| // only want to display the title header for the main row |
| String modelFormFieldTitle = modelFormField.getTitle(context); |
| if ("".equals(modelFormFieldTitle)) { |
| continue; |
| } |
| // don't do any header for hidden or ignored fields |
| if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) { |
| continue; |
| } |
| |
| if (fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY && fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY_ENTITY && fieldInfo.getFieldType() != ModelFormField.FieldInfo.HYPERLINK) { |
| inputFieldFound = true; |
| continue; |
| } |
| |
| // separate into two lists the display/hyperlink fields found before and after the first input fields |
| if (!inputFieldFound) { |
| innerDisplayHyperlinkFieldsBegin.add(modelFormField); |
| } else { |
| innerDisplayHyperlinkFieldsEnd.add(modelFormField); |
| } |
| numOfColumns++; |
| } |
| |
| // prepare the combined title for the column that will contain the form/input fields |
| for (ModelFormField modelFormField: mainFieldList) { |
| ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo(); |
| |
| // don't do any header for hidden or ignored fields |
| if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) { |
| continue; |
| } |
| |
| // skip all of the display/hyperlink fields |
| if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.DISPLAY || fieldInfo.getFieldType() == ModelFormField.FieldInfo.DISPLAY_ENTITY || fieldInfo.getFieldType() == ModelFormField.FieldInfo.HYPERLINK) { |
| continue; |
| } |
| |
| innerFormFields.add(modelFormField); |
| } |
| if (innerFormFields.size() > 0) { |
| numOfColumns++; |
| } |
| |
| if (maxNumOfColumns < numOfColumns) { |
| maxNumOfColumns = numOfColumns; |
| } |
| |
| Map<String, List<ModelFormField>> fieldRow = UtilMisc.toMap("displayBefore", innerDisplayHyperlinkFieldsBegin, |
| "inputFields", innerFormFields, |
| "displayAfter", innerDisplayHyperlinkFieldsEnd, |
| "mainFieldList", mainFieldList); |
| fieldRowsByPosition.add(fieldRow); |
| } |
| // =========================== |
| // Rendering |
| // =========================== |
| for (Map<String, List<ModelFormField>> listsMap: fieldRowsByPosition) { |
| List<ModelFormField> innerDisplayHyperlinkFieldsBegin = listsMap.get("displayBefore"); |
| List<ModelFormField> innerFormFields = listsMap.get("inputFields"); |
| List<ModelFormField> innerDisplayHyperlinkFieldsEnd = listsMap.get("displayAfter"); |
| List<ModelFormField> mainFieldList = listsMap.get("mainFieldList"); |
| |
| int numOfCells = innerDisplayHyperlinkFieldsBegin.size() + |
| innerDisplayHyperlinkFieldsEnd.size() + |
| (innerFormFields.size() > 0? 1: 0); |
| int numOfColumnsToSpan = maxNumOfColumns - numOfCells + 1; |
| if (numOfColumnsToSpan < 1) { |
| numOfColumnsToSpan = 1; |
| } |
| |
| if (numOfCells > 0) { |
| formStringRenderer.renderFormatHeaderRowOpen(writer, context, this); |
| |
| if (this.groupColumns) { |
| Iterator<ModelFormField> innerDisplayHyperlinkFieldsBeginIt = innerDisplayHyperlinkFieldsBegin.iterator(); |
| while (innerDisplayHyperlinkFieldsBeginIt.hasNext()) { |
| ModelFormField modelFormField = innerDisplayHyperlinkFieldsBeginIt.next(); |
| // span columns only if this is the last column in the row (not just in this first list) |
| if (innerDisplayHyperlinkFieldsBeginIt.hasNext() || numOfCells > innerDisplayHyperlinkFieldsBegin.size()) { |
| formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, this, modelFormField, 1); |
| } else { |
| formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, this, modelFormField, numOfColumnsToSpan); |
| } |
| formStringRenderer.renderFieldTitle(writer, context, modelFormField); |
| formStringRenderer.renderFormatHeaderRowCellClose(writer, context, this, modelFormField); |
| } |
| if (innerFormFields.size() > 0) { |
| // TODO: manage colspan |
| formStringRenderer.renderFormatHeaderRowFormCellOpen(writer, context, this); |
| Iterator<ModelFormField> innerFormFieldsIt = innerFormFields.iterator(); |
| while (innerFormFieldsIt.hasNext()) { |
| ModelFormField modelFormField = innerFormFieldsIt.next(); |
| |
| if (separateColumns || modelFormField.getSeparateColumn()) { |
| formStringRenderer.renderFormatItemRowCellOpen(writer, context, this, modelFormField, 1); |
| } |
| |
| // render title (unless this is a submit or a reset field) |
| formStringRenderer.renderFieldTitle(writer, context, modelFormField); |
| |
| if (separateColumns || modelFormField.getSeparateColumn()) { |
| formStringRenderer.renderFormatItemRowCellClose(writer, context, this, modelFormField); |
| } |
| |
| if (innerFormFieldsIt.hasNext()) { |
| // TODO: determine somehow if this is the last one... how? |
| if (!separateColumns && !modelFormField.getSeparateColumn()) { |
| formStringRenderer.renderFormatHeaderRowFormCellTitleSeparator(writer, context, this, modelFormField, false); |
| } |
| } |
| } |
| formStringRenderer.renderFormatHeaderRowFormCellClose(writer, context, this); |
| } |
| Iterator<ModelFormField> innerDisplayHyperlinkFieldsEndIt = innerDisplayHyperlinkFieldsEnd.iterator(); |
| while (innerDisplayHyperlinkFieldsEndIt.hasNext()) { |
| ModelFormField modelFormField = innerDisplayHyperlinkFieldsEndIt.next(); |
| // span columns only if this is the last column in the row (not just in this first list) |
| if (innerDisplayHyperlinkFieldsEndIt.hasNext() || numOfCells > innerDisplayHyperlinkFieldsEnd.size()) { |
| formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, this, modelFormField, 1); |
| } else { |
| formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, this, modelFormField, numOfColumnsToSpan); |
| } |
| formStringRenderer.renderFieldTitle(writer, context, modelFormField); |
| formStringRenderer.renderFormatHeaderRowCellClose(writer, context, this, modelFormField); |
| } |
| } else { |
| Iterator<ModelFormField> mainFieldListIter = mainFieldList.iterator(); |
| while (mainFieldListIter.hasNext()) { |
| ModelFormField modelFormField = mainFieldListIter.next(); |
| |
| // don't do any header for hidden or ignored fields |
| ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo(); |
| if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) { |
| continue; |
| } |
| |
| // span columns only if this is the last column in the row (not just in this first list) |
| if (mainFieldListIter.hasNext() || numOfCells > mainFieldList.size()) { |
| formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, this, modelFormField, 1); |
| } else { |
| formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, this, modelFormField, numOfColumnsToSpan); |
| } |
| formStringRenderer.renderFieldTitle(writer, context, modelFormField); |
| formStringRenderer.renderFormatHeaderRowCellClose(writer, context, this, modelFormField); |
| } |
| } |
| |
| formStringRenderer.renderFormatHeaderRowClose(writer, context, this); |
| } |
| } |
| |
| return maxNumOfColumns; |
| } |
| |
| protected <X> X safeNext(Iterator<X> iterator) { |
| try { |
| return iterator.next(); |
| } catch (NoSuchElementException e) { |
| return null; |
| } |
| } |
| |
| public void preparePager(Map<String, Object> context) { |
| |
| this.rowCount = 0; |
| String lookupName = this.getListName(); |
| if (UtilValidate.isEmpty(lookupName)) { |
| Debug.logError("No value for list or iterator name found.", module); |
| return; |
| } |
| Object obj = context.get(lookupName); |
| if (obj == null) { |
| if (Debug.verboseOn()) Debug.logVerbose("No object for list or iterator name [" + lookupName + "] found, so not running pagination.", module); |
| return; |
| } |
| // if list is empty, do not render rows |
| Iterator<?> iter = null; |
| if (obj instanceof Iterator<?>) { |
| iter = (Iterator<?>) obj; |
| } else if (obj instanceof List<?>) { |
| iter = ((List<?>) obj).listIterator(); |
| } |
| |
| // set low and high index |
| getListLimits(context, obj); |
| |
| int listSize = ((Integer) context.get("listSize")).intValue(); |
| int lowIndex = ((Integer) context.get("lowIndex")).intValue(); |
| int highIndex = ((Integer) context.get("highIndex")).intValue(); |
| // Debug.logInfo("preparePager: low - high = " + lowIndex + " - " + highIndex, module); |
| |
| // we're passed a subset of the list, so use (0, viewSize) range |
| if (isOverridenListSize()) { |
| lowIndex = 0; |
| highIndex = ((Integer) context.get("viewSize")).intValue(); |
| } |
| |
| if (iter == null) return; |
| |
| // count item rows |
| int itemIndex = -1; |
| Object item = this.safeNext(iter); |
| while (item != null && itemIndex < highIndex) { |
| itemIndex++; |
| item = this.safeNext(iter); |
| } |
| |
| // Debug.logInfo("preparePager: Found rows = " + itemIndex, module); |
| |
| // reduce the highIndex if number of items falls short |
| if ((itemIndex + 1) < highIndex) { |
| highIndex = itemIndex + 1; |
| // if list size is overridden, use full listSize |
| context.put("highIndex", Integer.valueOf(isOverridenListSize() ? listSize : highIndex)); |
| } |
| context.put("actualPageSize", Integer.valueOf(highIndex - lowIndex)); |
| |
| if (iter instanceof EntityListIterator) { |
| try { |
| ((EntityListIterator) iter).beforeFirst(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Error rewinding list form render EntityListIterator: " + e.toString(), module); |
| } |
| } |
| } |
| |
| public void renderItemRows(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer, boolean formPerItem, int numOfColumns) throws IOException { |
| this.rowCount = 0; |
| String lookupName = this.getListName(); |
| if (UtilValidate.isEmpty(lookupName)) { |
| Debug.logError("No value for list or iterator name found.", module); |
| return; |
| } |
| Object obj = context.get(lookupName); |
| if (obj == null) { |
| if (Debug.verboseOn()) Debug.logVerbose("No object for list or iterator name [" + lookupName + "] found, so not rendering rows.", module); |
| return; |
| } |
| // if list is empty, do not render rows |
| Iterator<?> iter = null; |
| if (obj instanceof Iterator<?>) { |
| iter = (Iterator<?>) obj; |
| } else if (obj instanceof List<?>) { |
| iter = ((List<?>) obj).listIterator(); |
| } |
| |
| // set low and high index |
| getListLimits(context, obj); |
| |
| int listSize = ((Integer) context.get("listSize")).intValue(); |
| int lowIndex = ((Integer) context.get("lowIndex")).intValue(); |
| int highIndex = ((Integer) context.get("highIndex")).intValue(); |
| |
| // we're passed a subset of the list, so use (0, viewSize) range |
| if (isOverridenListSize()) { |
| lowIndex = 0; |
| highIndex = ((Integer) context.get("viewSize")).intValue(); |
| } |
| |
| if (iter != null) { |
| // render item rows |
| int itemIndex = -1; |
| Object item = null; |
| context.put("wholeFormContext", context); |
| Map<String, Object> previousItem = FastMap.newInstance(); |
| while ((item = this.safeNext(iter)) != null) { |
| itemIndex++; |
| if (itemIndex >= highIndex) { |
| break; |
| } |
| |
| // TODO: this is a bad design, for EntityListIterators we should skip to the lowIndex and go from there, MUCH more efficient... |
| if (itemIndex < lowIndex) { |
| continue; |
| } |
| |
| // reset/remove the BshInterpreter now as well as later because chances are there is an interpreter at this level of the stack too |
| this.resetBshInterpreter(context); |
| |
| Map<String, Object> itemMap = UtilGenerics.checkMap(item); |
| MapStack<String> localContext = MapStack.create(context); |
| if (UtilValidate.isNotEmpty(this.getListEntryName())) { |
| localContext.put(this.getListEntryName(), item); |
| } else { |
| if (itemMap instanceof GenericEntity) { |
| // Rendering code might try to modify the GenericEntity instance, |
| // so we make a copy of it. |
| Map<String, Object> genericEntityClone = UtilGenerics.cast(((GenericEntity)itemMap).clone()); |
| localContext.push(genericEntityClone); |
| } else { |
| localContext.push(itemMap); |
| } |
| } |
| |
| // reset/remove the BshInterpreter now as well as later because chances are there is an interpreter at this level of the stack too |
| this.resetBshInterpreter(localContext); |
| localContext.push(); |
| localContext.put("previousItem", previousItem); |
| previousItem = FastMap.newInstance(); |
| previousItem.putAll(itemMap); |
| |
| ModelFormAction.runSubActions(this.rowActions, localContext); |
| |
| localContext.put("itemIndex", Integer.valueOf(itemIndex - lowIndex)); |
| if (UtilValidate.isNotEmpty(context.get("renderFormSeqNumber"))) { |
| localContext.put("formUniqueId", "_"+context.get("renderFormSeqNumber")); |
| } |
| |
| this.resetBshInterpreter(localContext); |
| |
| if (Debug.verboseOn()) Debug.logVerbose("In form got another row, context is: " + localContext, module); |
| |
| // Check to see if there is a field, same name and same use-when (could come from extended form) |
| List<ModelFormField> tempFieldList = FastList.newInstance(); |
| tempFieldList.addAll(this.fieldList); |
| for (int j = 0; j < tempFieldList.size(); j++) { |
| ModelFormField modelFormField = tempFieldList.get(j); |
| if (!modelFormField.isUseWhenEmpty()) { |
| boolean shouldUse1 = modelFormField.shouldUse(localContext); |
| for (int i = j+1; i < tempFieldList.size(); i++) { |
| ModelFormField curField = tempFieldList.get(i); |
| if (curField.getName() != null && curField.getName().equals(modelFormField.getName())) { |
| boolean shouldUse2 = curField.shouldUse(localContext); |
| if (shouldUse1 == shouldUse2) { |
| tempFieldList.remove(i--); |
| } |
| } else { |
| continue; |
| } |
| } |
| } |
| } |
| |
| // Each single item is rendered in one or more rows if its fields have |
| // different "position" attributes. All the fields with the same position |
| // are rendered in the same row. |
| // The default position is 1, and represents the main row: |
| // it contains the fields that are in the list header (columns). |
| // The positions lower than 1 are rendered in rows before the main one; |
| // positions higher than 1 are rendered after the main one. |
| |
| // We get a sorted (by position, ascending) set of lists; |
| // each list contains all the fields with that position. |
| Collection<List<ModelFormField>> fieldListsByPosition = this.getFieldListsByPosition(tempFieldList); |
| //List hiddenIgnoredFieldList = getHiddenIgnoredFields(localContext, null, tempFieldList); |
| for (List<ModelFormField> fieldListByPosition: fieldListsByPosition) { |
| // For each position (the subset of fields with the same position attribute) |
| // we have two phases: preprocessing and rendering |
| this.rowCount++; |
| |
| List<ModelFormField> innerDisplayHyperlinkFieldsBegin = FastList.newInstance(); |
| List<ModelFormField> innerFormFields = FastList.newInstance(); |
| List<ModelFormField> innerDisplayHyperlinkFieldsEnd = FastList.newInstance(); |
| |
| // Preprocessing: |
| // all the form fields are evaluated and the ones that will |
| // appear in the form are put into three separate lists: |
| // - hyperlink fields that will appear at the beginning of the row |
| // - fields of other types |
| // - hyperlink fields that will appear at the end of the row |
| Iterator<ModelFormField> innerDisplayHyperlinkFieldIter = fieldListByPosition.iterator(); |
| int currentPosition = 1; |
| while (innerDisplayHyperlinkFieldIter.hasNext()) { |
| ModelFormField modelFormField = innerDisplayHyperlinkFieldIter.next(); |
| ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo(); |
| |
| // don't do any header for hidden or ignored fields |
| if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) { |
| continue; |
| } |
| |
| if (fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY && fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY_ENTITY && fieldInfo.getFieldType() != ModelFormField.FieldInfo.HYPERLINK) { |
| // okay, now do the form cell |
| break; |
| } |
| |
| // if this is a list or multi form don't skip here because we don't want to skip the table cell, will skip the actual field later |
| if (!"list".equals(this.getType()) && !"multi".equals(this.getType()) && |
| !modelFormField.shouldUse(localContext)) { |
| continue; |
| } |
| innerDisplayHyperlinkFieldsBegin.add(modelFormField); |
| currentPosition = modelFormField.getPosition(); |
| } |
| Iterator<ModelFormField> innerFormFieldIter = fieldListByPosition.iterator(); |
| while (innerFormFieldIter.hasNext()) { |
| ModelFormField modelFormField = innerFormFieldIter.next(); |
| ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo(); |
| |
| // don't do any header for hidden or ignored fields |
| if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) { |
| continue; |
| } |
| |
| // skip all of the display/hyperlink fields |
| if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.DISPLAY || fieldInfo.getFieldType() == ModelFormField.FieldInfo.DISPLAY_ENTITY || fieldInfo.getFieldType() == ModelFormField.FieldInfo.HYPERLINK) { |
| continue; |
| } |
| |
| // if this is a list or multi form don't skip here because we don't want to skip the table cell, will skip the actual field later |
| if (!"list".equals(this.getType()) && !"multi".equals(this.getType()) && |
| !modelFormField.shouldUse(localContext)) { |
| continue; |
| } |
| innerFormFields.add(modelFormField); |
| currentPosition = modelFormField.getPosition(); |
| } |
| while (innerDisplayHyperlinkFieldIter.hasNext()) { |
| ModelFormField modelFormField = innerDisplayHyperlinkFieldIter.next(); |
| ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo(); |
| |
| // don't do any header for hidden or ignored fields |
| if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) { |
| continue; |
| } |
| |
| // skip all non-display and non-hyperlink fields |
| if (fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY && fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY_ENTITY && fieldInfo.getFieldType() != ModelFormField.FieldInfo.HYPERLINK) { |
| continue; |
| } |
| |
| // if this is a list or multi form don't skip here because we don't want to skip the table cell, will skip the actual field later |
| if (!"list".equals(this.getType()) && !"multi".equals(this.getType()) && |
| !modelFormField.shouldUse(localContext)) { |
| continue; |
| } |
| innerDisplayHyperlinkFieldsEnd.add(modelFormField); |
| currentPosition = modelFormField.getPosition(); |
| } |
| List<ModelFormField> hiddenIgnoredFieldList = getHiddenIgnoredFields(localContext, null, tempFieldList, currentPosition); |
| |
| // Rendering: |
| // the fields in the three lists created in the preprocessing phase |
| // are now rendered: this will create a visual representation |
| // of one row (for the current position). |
| if (innerDisplayHyperlinkFieldsBegin.size() > 0 || innerFormFields.size() > 0 || innerDisplayHyperlinkFieldsEnd.size() > 0) { |
| this.renderItemRow(writer, localContext, formStringRenderer, formPerItem, hiddenIgnoredFieldList, |
| innerDisplayHyperlinkFieldsBegin, innerFormFields, innerDisplayHyperlinkFieldsEnd, fieldListByPosition, |
| currentPosition, numOfColumns); |
| } |
| } // iteration on positions |
| } // iteration on items |
| |
| // reduce the highIndex if number of items falls short |
| if ((itemIndex + 1) < highIndex) { |
| highIndex = itemIndex + 1; |
| // if list size is overridden, use full listSize |
| context.put("highIndex", Integer.valueOf(isOverridenListSize() ? listSize : highIndex)); |
| } |
| context.put("actualPageSize", Integer.valueOf(highIndex - lowIndex)); |
| |
| if (iter instanceof EntityListIterator) { |
| try { |
| ((EntityListIterator) iter).close(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Error closing list form render EntityListIterator: " + e.toString(), module); |
| } |
| } |
| } |
| } |
| |
| // The fields in the three lists, usually created in the preprocessing phase |
| // of the renderItemRows method are rendered: this will create a visual representation |
| // of one row (corresponding to one position). |
| public void renderItemRow(Appendable writer, Map<String, Object> localContext, FormStringRenderer formStringRenderer, |
| boolean formPerItem, List<ModelFormField> hiddenIgnoredFieldList, List<ModelFormField> innerDisplayHyperlinkFieldsBegin, |
| List<ModelFormField> innerFormFields, List<ModelFormField> innerDisplayHyperlinkFieldsEnd, List<ModelFormField> mainFieldList, |
| int position, int numOfColumns) throws IOException { |
| int numOfCells = innerDisplayHyperlinkFieldsBegin.size() + |
| innerDisplayHyperlinkFieldsEnd.size() + |
| (innerFormFields.size() > 0? 1: 0); |
| int numOfColumnsToSpan = numOfColumns - numOfCells + 1; |
| if (numOfColumnsToSpan < 1) { |
| numOfColumnsToSpan = 1; |
| } |
| |
| // render row formatting open |
| formStringRenderer.renderFormatItemRowOpen(writer, localContext, this); |
| Iterator<ModelFormField> innerDisplayHyperlinkFieldsBeginIter = innerDisplayHyperlinkFieldsBegin.iterator(); |
| Map<String, Integer> fieldCount = FastMap.newInstance(); |
| while(innerDisplayHyperlinkFieldsBeginIter.hasNext()){ |
| ModelFormField modelFormField = innerDisplayHyperlinkFieldsBeginIter.next(); |
| if(fieldCount.containsKey(modelFormField.getFieldName())){ |
| fieldCount.put(modelFormField.getFieldName(), fieldCount.get(modelFormField.getFieldName())+1); |
| } |
| else{ |
| fieldCount.put(modelFormField.getFieldName(), 1); |
| } |
| } |
| |
| if (this.groupColumns) { |
| // do the first part of display and hyperlink fields |
| Iterator<ModelFormField> innerDisplayHyperlinkFieldIter = innerDisplayHyperlinkFieldsBegin.iterator(); |
| while (innerDisplayHyperlinkFieldIter.hasNext()) { |
| boolean cellOpen = false; |
| ModelFormField modelFormField = innerDisplayHyperlinkFieldIter.next(); |
| // span columns only if this is the last column in the row (not just in this first list) |
| if( fieldCount.get(modelFormField.getName()) < 2 ){ |
| if ((innerDisplayHyperlinkFieldIter.hasNext() || numOfCells > innerDisplayHyperlinkFieldsBegin.size())) { |
| formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, this, modelFormField, 1); |
| } else { |
| formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, this, modelFormField, numOfColumnsToSpan); |
| } |
| cellOpen = true; |
| } |
| if ((!"list".equals(this.getType()) && !"multi".equals(this.getType())) || modelFormField.shouldUse(localContext)) { |
| if(( fieldCount.get(modelFormField.getName()) > 1 )){ |
| if ((innerDisplayHyperlinkFieldIter.hasNext() || numOfCells > innerDisplayHyperlinkFieldsBegin.size())) { |
| formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, this, modelFormField, 1); |
| } else { |
| formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, this, modelFormField, numOfColumnsToSpan); |
| } |
| cellOpen = true; |
| } |
| modelFormField.renderFieldString(writer, localContext, formStringRenderer); |
| } |
| if (cellOpen) { |
| formStringRenderer.renderFormatItemRowCellClose(writer, localContext, this, modelFormField); |
| } |
| } |
| |
| // The form cell is rendered only if there is at least an input field |
| if (innerFormFields.size() > 0) { |
| // render the "form" cell |
| formStringRenderer.renderFormatItemRowFormCellOpen(writer, localContext, this); // TODO: colspan |
| |
| if (formPerItem) { |
| formStringRenderer.renderFormOpen(writer, localContext, this); |
| } |
| |
| // do all of the hidden fields... |
| this.renderHiddenIgnoredFields(writer, localContext, formStringRenderer, hiddenIgnoredFieldList); |
| |
| Iterator<ModelFormField> innerFormFieldIter = innerFormFields.iterator(); |
| while (innerFormFieldIter.hasNext()) { |
| ModelFormField modelFormField = innerFormFieldIter.next(); |
| if (separateColumns || modelFormField.getSeparateColumn()) { |
| formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, this, modelFormField, 1); |
| } |
| // render field widget |
| if ((!"list".equals(this.getType()) && !"multi".equals(this.getType())) || modelFormField.shouldUse(localContext)) { |
| modelFormField.renderFieldString(writer, localContext, formStringRenderer); |
| } |
| |
| if (separateColumns || modelFormField.getSeparateColumn()) { |
| formStringRenderer.renderFormatItemRowCellClose(writer, localContext, this, modelFormField); |
| } |
| } |
| |
| if (formPerItem) { |
| formStringRenderer.renderFormClose(writer, localContext, this); |
| } |
| |
| formStringRenderer.renderFormatItemRowFormCellClose(writer, localContext, this); |
| } |
| |
| // render the rest of the display/hyperlink fields |
| innerDisplayHyperlinkFieldIter = innerDisplayHyperlinkFieldsEnd.iterator(); |
| while (innerDisplayHyperlinkFieldIter.hasNext()) { |
| ModelFormField modelFormField = innerDisplayHyperlinkFieldIter.next(); |
| // span columns only if this is the last column in the row |
| if (innerDisplayHyperlinkFieldIter.hasNext()) { |
| formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, this, modelFormField, 1); |
| } else { |
| formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, this, modelFormField, numOfColumnsToSpan); |
| } |
| if ((!"list".equals(this.getType()) && !"multi".equals(this.getType())) || modelFormField.shouldUse(localContext)) { |
| modelFormField.renderFieldString(writer, localContext, formStringRenderer); |
| } |
| formStringRenderer.renderFormatItemRowCellClose(writer, localContext, this, modelFormField); |
| } |
| } else { |
| // do all of the hidden fields... |
| this.renderHiddenIgnoredFields(writer, localContext, formStringRenderer, hiddenIgnoredFieldList); |
| |
| Iterator<ModelFormField> mainFieldIter = mainFieldList.iterator(); |
| while (mainFieldIter.hasNext()) { |
| ModelFormField modelFormField = mainFieldIter.next(); |
| |
| // don't do any header for hidden or ignored fields inside this loop |
| ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo(); |
| if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) { |
| continue; |
| } |
| |
| // span columns only if this is the last column in the row |
| if (mainFieldIter.hasNext()) { |
| formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, this, modelFormField, 1); |
| } else { |
| formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, this, modelFormField, numOfColumnsToSpan); |
| } |
| if ((!"list".equals(this.getType()) && !"multi".equals(this.getType())) || modelFormField.shouldUse(localContext)) { |
| modelFormField.renderFieldString(writer, localContext, formStringRenderer); |
| } |
| formStringRenderer.renderFormatItemRowCellClose(writer, localContext, this, modelFormField); |
| } |
| } |
| |
| |
| // render row formatting close |
| formStringRenderer.renderFormatItemRowClose(writer, localContext, this); |
| } |
| |
| public List<ModelFormField> getHiddenIgnoredFields(Map<String, Object> context, Set<String> alreadyRendered, List<ModelFormField> fieldList, int position) { |
| List<ModelFormField> hiddenIgnoredFieldList = FastList.newInstance(); |
| for (ModelFormField modelFormField: fieldList) { |
| // with position == -1 then gets all the hidden fields |
| if (position != -1 && modelFormField.getPosition() != position) { |
| continue; |
| } |
| ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo(); |
| |
| // render hidden/ignored field widget |
| switch (fieldInfo.getFieldType()) { |
| case ModelFormField.FieldInfo.HIDDEN : |
| case ModelFormField.FieldInfo.IGNORED : |
| if (modelFormField.shouldUse(context)) { |
| hiddenIgnoredFieldList.add(modelFormField); |
| if (alreadyRendered != null) |
| alreadyRendered.add(modelFormField.getName()); |
| } |
| break; |
| |
| case ModelFormField.FieldInfo.DISPLAY : |
| case ModelFormField.FieldInfo.DISPLAY_ENTITY : |
| ModelFormField.DisplayField displayField = (ModelFormField.DisplayField) fieldInfo; |
| if (displayField.getAlsoHidden() && modelFormField.shouldUse(context)) { |
| hiddenIgnoredFieldList.add(modelFormField); |
| // don't add to already rendered here, or the display won't ger rendered: if (alreadyRendered != null) alreadyRendered.add(modelFormField.getName()); |
| } |
| break; |
| |
| case ModelFormField.FieldInfo.HYPERLINK : |
| ModelFormField.HyperlinkField hyperlinkField = (ModelFormField.HyperlinkField) fieldInfo; |
| if (hyperlinkField.getAlsoHidden() && modelFormField.shouldUse(context)) { |
| hiddenIgnoredFieldList.add(modelFormField); |
| // don't add to already rendered here, or the hyperlink won't ger rendered: if (alreadyRendered != null) alreadyRendered.add(modelFormField.getName()); |
| } |
| break; |
| } |
| } |
| return hiddenIgnoredFieldList; |
| } |
| public void renderHiddenIgnoredFields(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer, List<ModelFormField> fieldList) throws IOException { |
| for (ModelFormField modelFormField: fieldList) { |
| ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo(); |
| |
| // render hidden/ignored field widget |
| switch (fieldInfo.getFieldType()) { |
| case ModelFormField.FieldInfo.HIDDEN : |
| case ModelFormField.FieldInfo.IGNORED : |
| modelFormField.renderFieldString(writer, context, formStringRenderer); |
| break; |
| |
| case ModelFormField.FieldInfo.DISPLAY : |
| case ModelFormField.FieldInfo.DISPLAY_ENTITY : |
| case ModelFormField.FieldInfo.HYPERLINK : |
| formStringRenderer.renderHiddenField(writer, context, modelFormField, modelFormField.getEntry(context)); |
| break; |
| } |
| } |
| } |
| |
| public Collection<List<ModelFormField>> getFieldListsByPosition(List<ModelFormField> modelFormFieldList) { |
| Map<Integer, List<ModelFormField>> fieldsByPosition = new TreeMap<Integer, List<ModelFormField>>(); |
| for (ModelFormField modelFormField: modelFormFieldList) { |
| Integer position = Integer.valueOf(modelFormField.getPosition()); |
| List<ModelFormField> fieldListByPosition = fieldsByPosition.get(position); |
| if (fieldListByPosition == null) { |
| fieldListByPosition = FastList.newInstance(); |
| fieldsByPosition.put(position, fieldListByPosition); |
| } |
| fieldListByPosition.add(modelFormField); |
| } |
| return fieldsByPosition.values(); |
| } |
| |
| public List<ModelFormField> getFieldListByPosition(List<ModelFormField> modelFormFieldList, int position) { |
| List<ModelFormField> fieldListByPosition = FastList.newInstance(); |
| for (ModelFormField modelFormField: modelFormFieldList) { |
| if (modelFormField.getPosition() == position) { |
| fieldListByPosition.add(modelFormField); |
| } |
| } |
| return fieldListByPosition; |
| } |
| |
| public String getTargetType() { |
| return this.targetType; |
| } |
| |
| public String getParentFormName() { |
| return this.parentFormName; |
| } |
| |
| public String getParentFormLocation() { |
| if (this.parentFormName != null && this.parentFormLocation == null) { |
| return this.formLocation; |
| } |
| return this.parentFormLocation; |
| } |
| |
| public ModelForm getParentModelForm() { |
| return parentModelForm; |
| } |
| |
| public String getDefaultEntityName() { |
| return this.defaultEntityName; |
| } |
| |
| public String getDefaultMapName() { |
| return this.defaultMapName.getOriginalName(); |
| } |
| |
| public Map<String, ? extends Object> getDefaultMap(Map<String, ? extends Object> context) { |
| return this.defaultMapName.get(context); |
| } |
| |
| public String getDefaultRequiredFieldStyle() { |
| return this.defaultRequiredFieldStyle; |
| } |
| |
| public String getDefaultSortFieldStyle() { |
| return (UtilValidate.isEmpty(this.defaultSortFieldStyle) ? DEFAULT_SORT_FIELD_STYLE : this.defaultSortFieldStyle); |
| } |
| |
| public String getDefaultSortFieldAscStyle() { |
| return (UtilValidate.isEmpty(this.defaultSortFieldAscStyle) ? DEFAULT_SORT_FIELD_ASC_STYLE : this.defaultSortFieldAscStyle); |
| } |
| |
| public String getDefaultSortFieldDescStyle() { |
| return (UtilValidate.isEmpty(this.defaultSortFieldDescStyle) ? DEFAULT_SORT_FIELD_DESC_STYLE : this.defaultSortFieldDescStyle); |
| } |
| |
| |
| public String getDefaultServiceName() { |
| return this.defaultServiceName; |
| } |
| |
| public String getFormTitleAreaStyle() { |
| return this.formTitleAreaStyle; |
| } |
| |
| public String getFormWidgetAreaStyle() { |
| return this.formWidgetAreaStyle; |
| } |
| |
| public String getDefaultTitleAreaStyle() { |
| return this.defaultTitleAreaStyle; |
| } |
| |
| public String getDefaultWidgetAreaStyle() { |
| return this.defaultWidgetAreaStyle; |
| } |
| |
| public String getOddRowStyle() { |
| return this.oddRowStyle; |
| } |
| |
| public String getEvenRowStyle() { |
| return this.evenRowStyle; |
| } |
| |
| public String getDefaultTableStyle() { |
| return this.defaultTableStyle; |
| } |
| |
| public String getHeaderRowStyle() { |
| return this.headerRowStyle; |
| } |
| |
| public String getDefaultTitleStyle() { |
| return this.defaultTitleStyle; |
| } |
| |
| public String getDefaultWidgetStyle() { |
| return this.defaultWidgetStyle; |
| } |
| |
| public String getDefaultTooltipStyle() { |
| return this.defaultTooltipStyle; |
| } |
| |
| public String getItemIndexSeparator() { |
| if (UtilValidate.isNotEmpty(this.itemIndexSeparator)) { |
| return this.itemIndexSeparator; |
| } else { |
| return "_o_"; |
| } |
| } |
| |
| public String getListEntryName() { |
| return this.listEntryName; |
| } |
| |
| public String getListName() { |
| String lstNm = this.listName; |
| if (UtilValidate.isEmpty(lstNm)) { |
| lstNm = DEFAULT_FORM_RESULT_LIST_NAME; |
| } |
| return lstNm; |
| } |
| |
| @Override |
| public String getName() { |
| return this.name; |
| } |
| |
| public String getCurrentFormName(Map<String, Object> context) { |
| Integer itemIndex = (Integer) context.get("itemIndex"); |
| String formName = (String) context.get("formName"); |
| if (UtilValidate.isEmpty(formName)) { |
| formName = this.getName(); |
| } |
| |
| if (itemIndex != null && "list".equals(this.getType())) { |
| return formName + this.getItemIndexSeparator() + itemIndex.intValue(); |
| } else { |
| return formName; |
| } |
| } |
| |
| /** 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; |
| StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder"); |
| if (simpleEncoder != null) { |
| expanderContext = StringUtil.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 " + this.name); |
| } |
| |
| if (condTrue && !targetType.equals("inter-app")) { |
| return altTarget.targetExdr.expandString(expanderContext); |
| } |
| } |
| } catch (EvalError e) { |
| String errmsg = "Error evaluating BeanShell target conditions on form " + this.name; |
| Debug.logError(e, errmsg, module); |
| throw new IllegalArgumentException(errmsg); |
| } |
| |
| return target.expandString(expanderContext); |
| } |
| |
| 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 getCurrentContainerId(Map<String, Object> context) { |
| Locale locale = UtilMisc.ensureLocale(context.get("locale")); |
| |
| String retVal = FlexibleStringExpander.expandString(this.getContainerId(), context, locale); |
| |
| Integer itemIndex = (Integer) context.get("itemIndex"); |
| if (itemIndex != null && "list".equals(this.getType())) { |
| return retVal + this.getItemIndexSeparator() + itemIndex.intValue(); |
| } |
| |
| return retVal; |
| } |
| |
| public String getContainerStyle() { |
| return this.containerStyle; |
| } |
| |
| public String getfocusFieldName() { |
| return this.focusFieldName; |
| } |
| |
| public String getTitle() { |
| return this.title; |
| } |
| |
| public String getTooltip() { |
| return this.tooltip; |
| } |
| |
| public String getType() { |
| return this.type; |
| } |
| |
| @Override |
| public String getBoundaryCommentName() { |
| return formLocation + "#" + name; |
| } |
| |
| public void resetBshInterpreter(Map<String, Object> context) { |
| context.remove("bshInterpreter"); |
| } |
| |
| 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; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setDefaultEntityName(String string) { |
| this.defaultEntityName = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setDefaultMapName(String string) { |
| this.defaultMapName = FlexibleMapAccessor.getInstance(string); |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setDefaultServiceName(String string) { |
| this.defaultServiceName = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setFormTitleAreaStyle(String string) { |
| this.formTitleAreaStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setFormWidgetAreaStyle(String string) { |
| this.formWidgetAreaStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setDefaultTitleAreaStyle(String string) { |
| this.defaultTitleAreaStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setDefaultWidgetAreaStyle(String string) { |
| this.defaultWidgetAreaStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setOddRowStyle(String string) { |
| this.oddRowStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setEvenRowStyle(String string) { |
| this.evenRowStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setDefaultTableStyle(String string) { |
| this.defaultTableStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setHeaderRowStyle(String string) { |
| this.headerRowStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setDefaultTitleStyle(String string) { |
| this.defaultTitleStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setDefaultWidgetStyle(String string) { |
| this.defaultWidgetStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setDefaultTooltipStyle(String string) { |
| this.defaultTooltipStyle = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setItemIndexSeparator(String string) { |
| this.itemIndexSeparator = string; |
| } |
| |
| /** |
| * @param formLocation string Form's location |
| */ |
| public void setFormLocation(String formLocation) { |
| this.formLocation = formLocation; |
| } |
| |
| public String getFormLocation() { |
| return this.formLocation; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setListEntryName(String string) { |
| this.listEntryName = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setListName(String string) { |
| this.listName = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setName(String string) { |
| this.name = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setTarget(String string) { |
| this.target = FlexibleStringExpander.getInstance(string); |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setContainerId(String string) { |
| this.containerId = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setfocusFieldName(String string) { |
| this.focusFieldName = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setTitle(String string) { |
| this.title = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setTooltip(String string) { |
| this.tooltip = string; |
| } |
| |
| /** |
| * @param string |
| */ |
| public void setType(String string) { |
| this.type = string; |
| } |
| |
| public List<UpdateArea> getOnSortColumnUpdateAreas() { |
| return this.onSortColumnUpdateAreas; |
| } |
| |
| public List<UpdateArea> getOnPaginateUpdateAreas() { |
| return this.onPaginateUpdateAreas; |
| } |
| |
| public String getPaginateTarget(Map<String, Object> context) { |
| String targ = this.paginateTarget.expandString(context); |
| if (UtilValidate.isEmpty(targ)) { |
| 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 getPaginateIndexField(Map<String, Object> context) { |
| String field = this.paginateIndexField.expandString(context); |
| if (UtilValidate.isEmpty(field)) { |
| field = DEFAULT_PAG_INDEX_FIELD; |
| } |
| return field; |
| } |
| |
| 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 int getPaginateIndex(Map<String, Object> context) { |
| String field = this.getMultiPaginateIndexField(context); |
| |
| int viewIndex = 0; |
| try { |
| Object value = context.get(field); |
| |
| if (value == null) { |
| // try parameters.VIEW_INDEX as that is an old OFBiz convention |
| Map<String, Object> parameters = UtilGenerics.cast(context.get("parameters")); |
| if (parameters != null) { |
| value = parameters.get("VIEW_INDEX" + "_" + WidgetWorker.getPaginatorNumber(context)); |
| |
| if (value == null) { |
| value = parameters.get(field); |
| } |
| } |
| } |
| |
| // try paginate index field without paginator number |
| if (value == null) { |
| field = this.getPaginateIndexField(context); |
| value = context.get(field); |
| } |
| |
| if (value instanceof Integer) { |
| viewIndex = ((Integer) value).intValue(); |
| } else if (value instanceof String) { |
| viewIndex = Integer.parseInt((String) value); |
| } |
| } catch (Exception e) { |
| Debug.logWarning(e, "Error getting paginate view index: " + e.toString(), module); |
| } |
| |
| return viewIndex; |
| } |
| |
| public String getPaginateSizeField(Map<String, Object> context) { |
| String field = this.paginateSizeField.expandString(context); |
| if (UtilValidate.isEmpty(field)) { |
| field = DEFAULT_PAG_SIZE_FIELD; |
| } |
| 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 int getPaginateSize(Map<String, Object> context) { |
| String field = this.getMultiPaginateSizeField(context); |
| |
| int viewSize = this.defaultViewSize; |
| try { |
| Object value = context.get(field); |
| |
| if (value == null) { |
| // try parameters.VIEW_SIZE as that is an old OFBiz convention |
| Map<String, Object> parameters = UtilGenerics.cast(context.get("parameters")); |
| if (parameters != null) { |
| value = parameters.get("VIEW_SIZE" + "_" + WidgetWorker.getPaginatorNumber(context)); |
| |
| if (value == null) { |
| value = parameters.get(field); |
| } |
| } |
| } |
| |
| // try the page size field without paginator number |
| if (value == null) { |
| field = this.getPaginateSizeField(context); |
| value = context.get(field); |
| } |
| |
| if (value instanceof Integer) { |
| viewSize = ((Integer) value).intValue(); |
| } else if (value instanceof String && UtilValidate.isNotEmpty(value)) { |
| viewSize = Integer.parseInt((String) value); |
| } |
| } catch (Exception e) { |
| Debug.logWarning(e, "Error getting paginate view size: " + e.toString(), module); |
| } |
| |
| return viewSize; |
| } |
| |
| 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 getPaginatePreviousLabel(Map<String, Object> context) { |
| Locale locale = (Locale)context.get("locale"); |
| String field = this.paginatePreviousLabel.expandString(context); |
| if (UtilValidate.isEmpty(field)) { |
| field = UtilProperties.getMessage("CommonUiLabels", "CommonPrevious", locale); |
| } |
| return field; |
| } |
| |
| public String getPaginateNextLabel(Map<String, Object> context) { |
| Locale locale = (Locale)context.get("locale"); |
| String field = this.paginateNextLabel.expandString(context); |
| if (UtilValidate.isEmpty(field)) { |
| field = UtilProperties.getMessage("CommonUiLabels", "CommonNext", locale); |
| } |
| return field; |
| } |
| |
| 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 getPaginateViewSizeLabel(Map<String, Object> context) { |
| Locale locale = (Locale)context.get("locale"); |
| String field = this.paginateViewSizeLabel.expandString(context); |
| if (UtilValidate.isEmpty(field)) { |
| field = UtilProperties.getMessage("CommonUiLabels", "CommonItemsPerPage", locale); |
| } |
| return field; |
| } |
| |
| public String getPaginateStyle() { |
| return this.paginateStyle; |
| } |
| |
| public String getPaginateFirstStyle() { |
| return DEFAULT_PAG_FIRST_STYLE; |
| } |
| |
| public String getPaginatePreviousStyle() { |
| return DEFAULT_PAG_PREV_STYLE; |
| } |
| |
| public String getPaginateNextStyle() { |
| return DEFAULT_PAG_NEXT_STYLE; |
| } |
| |
| public String getPaginateLastStyle() { |
| return DEFAULT_PAG_LAST_STYLE; |
| } |
| |
| public String getTargetWindow(Map<String, Object> context) { |
| return this.targetWindowExdr.expandString(context); |
| } |
| |
| public void setTargetWindow(String val) { |
| this.targetWindowExdr = FlexibleStringExpander.getInstance(val); |
| } |
| |
| public boolean getSeparateColumns() { |
| return this.separateColumns; |
| } |
| |
| public boolean getPaginate(Map<String, Object> context) { |
| if (UtilValidate.isNotEmpty(this.paginate) && UtilValidate.isNotEmpty(this.paginate.expandString(context))) { |
| return Boolean.valueOf(this.paginate.expandString(context)).booleanValue(); |
| } else { |
| return true; |
| } |
| } |
| |
| public boolean getSkipStart() { |
| return this.skipStart; |
| } |
| |
| public boolean getSkipEnd() { |
| return this.skipEnd; |
| } |
| |
| public boolean isOverridenListSize() { |
| return this.overridenListSize; |
| } |
| |
| public void setSkipStart(boolean val) { |
| this.skipStart = val; |
| } |
| |
| public void setSkipEnd(boolean val) { |
| this.skipEnd = val; |
| } |
| |
| public boolean getHideHeader() { |
| return this.hideHeader; |
| } |
| |
| public boolean getClientAutocompleteFields() { |
| return this.clientAutocompleteFields; |
| } |
| |
| public void setPaginate(boolean val) { |
| this.paginate = FlexibleStringExpander.getInstance(Boolean.valueOf(val).toString()); |
| } |
| |
| public void setOverridenListSize(boolean overridenListSize) { |
| this.overridenListSize = overridenListSize; |
| } |
| |
| public void setPaginateTarget(String string) { |
| this.paginateTarget = FlexibleStringExpander.getInstance(string); |
| } |
| |
| public void setPaginateIndexField(String string) { |
| this.paginateIndexField = FlexibleStringExpander.getInstance(string); |
| } |
| |
| public void setPaginateSizeField(String string) { |
| this.paginateSizeField = FlexibleStringExpander.getInstance(string); |
| } |
| |
| public void setPaginateStyle(String string) { |
| this.paginateStyle = (UtilValidate.isEmpty(string) ? DEFAULT_PAG_STYLE : string); |
| } |
| |
| public void setDefaultViewSize(int val) { |
| defaultViewSize = val; |
| } |
| |
| public void setDefaultViewSize(String val) { |
| try { |
| Integer sz = Integer.valueOf(val); |
| defaultViewSize = sz.intValue(); |
| } catch (NumberFormatException e) { |
| defaultViewSize = DEFAULT_PAGE_SIZE; |
| } |
| } |
| |
| public int getListSize(Map<String, Object> context) { |
| Integer value = (Integer) context.get("listSize"); |
| return value != null ? value.intValue() : 0; |
| } |
| |
| public int getViewIndex(Map<String, Object> context) { |
| return getPaginateIndex(context); |
| } |
| |
| public int getViewSize(Map<String, Object> context) { |
| return getPaginateSize(context); |
| } |
| |
| public int getLowIndex(Map<String, Object> context) { |
| Integer value = (Integer) context.get("lowIndex"); |
| return value != null ? value.intValue() : 0; |
| } |
| |
| public int getHighIndex(Map<String, Object> context) { |
| Integer value = (Integer) context.get("highIndex"); |
| return value != null ? value.intValue() : 0; |
| } |
| |
| public int getActualPageSize(Map<String, Object> context) { |
| Integer value = (Integer) context.get("actualPageSize"); |
| return value != null ? value.intValue() : (getHighIndex(context) - getLowIndex(context)); |
| } |
| |
| public List<ModelFormField> getFieldList() { |
| return fieldList; |
| } |
| |
| private int getOverrideListSize(Map<String, Object> context) { |
| int listSize = 0; |
| String size = this.overrideListSize.expandString(context); |
| if (UtilValidate.isNotEmpty(size)) { |
| 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 void getListLimits(Map<String, Object> context, Object entryList) { |
| int listSize = 0; |
| int viewIndex = 0; |
| int viewSize = 0; |
| int lowIndex = 0; |
| int highIndex = 0; |
| |
| listSize = getOverrideListSize(context); |
| if (listSize > 0) { |
| setOverridenListSize(true); |
| } else if (entryList instanceof EntityListIterator) { |
| EntityListIterator iter = (EntityListIterator) entryList; |
| try { |
| listSize = iter.getResultsSizeAfterPartialList(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Error getting list size", module); |
| listSize = 0; |
| } |
| } else if (entryList instanceof List<?>) { |
| List<?> items = (List<?>) entryList; |
| listSize = items.size(); |
| } |
| |
| if (getPaginate(context)) { |
| viewIndex = this.getPaginateIndex(context); |
| viewSize = this.getPaginateSize(context); |
| lowIndex = viewIndex * viewSize; |
| highIndex = (viewIndex + 1) * viewSize; |
| } else { |
| viewIndex = 0; |
| viewSize = MAX_PAGE_SIZE; |
| lowIndex = 0; |
| highIndex = MAX_PAGE_SIZE; |
| } |
| |
| context.put("listSize", Integer.valueOf(listSize)); |
| context.put("viewIndex", Integer.valueOf(viewIndex)); |
| context.put("viewSize", Integer.valueOf(viewSize)); |
| context.put("lowIndex", Integer.valueOf(lowIndex)); |
| context.put("highIndex", Integer.valueOf(highIndex)); |
| } |
| |
| public String getPassedRowCount(Map<String, Object> context) { |
| return rowCountExdr.expandString(context); |
| } |
| |
| public int getRowCount() { |
| return this.rowCount; |
| } |
| |
| public boolean getUseRowSubmit() { |
| return this.useRowSubmit; |
| } |
| |
| public List<ModelFormField> getMultiSubmitFields() { |
| return this.multiSubmitFields; |
| } |
| |
| public List<FieldGroupBase> getInbetweenList(FieldGroup startFieldGroup, FieldGroup endFieldGroup) { |
| ArrayList<FieldGroupBase> inbetweenList = new ArrayList<FieldGroupBase>(); |
| boolean firstFound = false; |
| String startFieldGroupId = null; |
| String endFieldGroupId = null; |
| if (endFieldGroup != null) { |
| endFieldGroupId = endFieldGroup.getId(); |
| } |
| if (startFieldGroup == null) { |
| firstFound = true; |
| } else { |
| startFieldGroupId = startFieldGroup.getId(); |
| } |
| Iterator<FieldGroupBase> iter = fieldGroupList.iterator(); |
| while (iter.hasNext()) { |
| FieldGroupBase obj = iter.next(); |
| if (obj instanceof ModelForm.Banner) { |
| if (firstFound) inbetweenList.add(obj); |
| } else { |
| FieldGroup fieldGroup = (FieldGroup)obj; |
| String fieldGroupId = fieldGroup.getId(); |
| if (!firstFound) { |
| if (fieldGroupId.equals(startFieldGroupId)) { |
| firstFound = true; |
| continue; |
| } |
| } |
| if (firstFound) { |
| if (fieldGroupId.equals(endFieldGroupId)) { |
| break; |
| } else { |
| inbetweenList.add(fieldGroup); |
| } |
| } |
| } |
| } |
| return inbetweenList; |
| } |
| |
| 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; |
| } |
| |
| /* Returns the list of ModelForm.UpdateArea objects. |
| */ |
| public List<UpdateArea> getOnSubmitUpdateAreas() { |
| return this.onSubmitUpdateAreas; |
| } |
| |
| public void setDefaultEntityNameOnUpdateAreas() { |
| List<UpdateArea> allUpdateAreas = FastList.newInstance(); |
| if (UtilValidate.isNotEmpty(this.onSubmitUpdateAreas)) allUpdateAreas.addAll(this.onSubmitUpdateAreas); |
| if (UtilValidate.isNotEmpty(this.onPaginateUpdateAreas)) allUpdateAreas.addAll(this.onPaginateUpdateAreas); |
| for (UpdateArea updateArea : allUpdateAreas) { |
| if (UtilValidate.isEmpty(updateArea.defaultEntityName)) { |
| updateArea.defaultEntityName = this.defaultEntityName; |
| } |
| } |
| } |
| |
| public void setDefaultServiceNameOnUpdateAreas() { |
| List<UpdateArea> allUpdateAreas = FastList.newInstance(); |
| if (UtilValidate.isNotEmpty(this.onSubmitUpdateAreas)) allUpdateAreas.addAll(this.onSubmitUpdateAreas); |
| if (UtilValidate.isNotEmpty(this.onPaginateUpdateAreas)) allUpdateAreas.addAll(this.onPaginateUpdateAreas); |
| for (UpdateArea updateArea : allUpdateAreas) { |
| if (UtilValidate.isEmpty(updateArea.defaultServiceName)) { |
| updateArea.defaultServiceName = this.defaultServiceName; |
| } |
| } |
| } |
| |
| public static class AltRowStyle { |
| public String useWhen; |
| public String style; |
| public AltRowStyle(Element altRowStyleElement) { |
| this.useWhen = altRowStyleElement.getAttribute("use-when"); |
| this.style = altRowStyleElement.getAttribute("style"); |
| } |
| } |
| |
| /** |
| * 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 " + this.name); |
| } |
| } |
| } catch (EvalError e) { |
| String errmsg = "Error evaluating BeanShell style conditions on form " + this.name; |
| Debug.logError(e, errmsg, module); |
| throw new IllegalArgumentException(errmsg); |
| } |
| |
| return styles; |
| } |
| |
| public static class AltTarget { |
| public String useWhen; |
| public FlexibleStringExpander targetExdr; |
| public AltTarget(Element altTargetElement) { |
| this.useWhen = altTargetElement.getAttribute("use-when"); |
| this.targetExdr = FlexibleStringExpander.getInstance(altTargetElement.getAttribute("target")); |
| } |
| @Override |
| public int hashCode() { |
| return useWhen.hashCode(); |
| } |
| @Override |
| public boolean equals(Object obj) { |
| return obj instanceof AltTarget && obj.hashCode() == this.hashCode(); |
| } |
| } |
| |
| /** The UpdateArea class implements the <code><on-event-update-area></code> |
| * elements used in form widgets. |
| */ |
| public static class UpdateArea { |
| protected String eventType; |
| protected String areaId; |
| protected String areaTarget; |
| protected String defaultServiceName; |
| protected String defaultEntityName; |
| protected WidgetWorker.AutoEntityParameters autoEntityParameters; |
| protected WidgetWorker.AutoEntityParameters autoServiceParameters; |
| List<WidgetWorker.Parameter> parameterList = FastList.newInstance(); |
| /** XML constructor. |
| * @param updateAreaElement The <code><on-xxx-update-area></code> |
| * XML element. |
| */ |
| public UpdateArea(Element updateAreaElement) { |
| this.eventType = updateAreaElement.getAttribute("event-type"); |
| this.areaId = updateAreaElement.getAttribute("area-id"); |
| this.areaTarget = updateAreaElement.getAttribute("area-target"); |
| List<? extends Element> parameterElementList = UtilXml.childElementList(updateAreaElement, "parameter"); |
| for (Element parameterElement: parameterElementList) { |
| this.parameterList.add(new WidgetWorker.Parameter(parameterElement)); |
| } |
| Element autoServiceParamsElement = UtilXml.firstChildElement(updateAreaElement, "auto-parameters-service"); |
| if (autoServiceParamsElement != null) { |
| autoServiceParameters = new WidgetWorker.AutoEntityParameters(autoServiceParamsElement); |
| } |
| Element autoEntityParamsElement = UtilXml.firstChildElement(updateAreaElement, "auto-parameters-entity"); |
| if (autoEntityParamsElement != null) { |
| autoEntityParameters = new WidgetWorker.AutoEntityParameters(autoEntityParamsElement); |
| } |
| } |
| /** String constructor. |
| * @param areaId The id of the widget element to be updated |
| * @param areaTarget The target URL called to update the area |
| */ |
| public UpdateArea(String eventType, String areaId, String areaTarget) { |
| this.eventType = eventType; |
| this.areaId = areaId; |
| this.areaTarget = areaTarget; |
| } |
| @Override |
| public int hashCode() { |
| return areaId.hashCode(); |
| } |
| @Override |
| public boolean equals(Object obj) { |
| return obj instanceof UpdateArea && obj.hashCode() == this.hashCode(); |
| } |
| public String getEventType() { |
| return eventType; |
| } |
| public String getAreaId() { |
| return areaId; |
| } |
| public String getAreaTarget(Map<String, ? extends Object> context) { |
| return FlexibleStringExpander.expandString(areaTarget, context); |
| } |
| public Map<String, String> getParameterMap(Map<String, Object> context) { |
| Map<String, String> fullParameterMap = FastMap.newInstance(); |
| if (autoServiceParameters != null) { |
| fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, defaultServiceName)); |
| } |
| if (autoEntityParameters != null) { |
| fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, defaultEntityName)); |
| } |
| for (WidgetWorker.Parameter parameter: this.parameterList) { |
| fullParameterMap.put(parameter.getName(), parameter.getValue(context)); |
| } |
| |
| return fullParameterMap; |
| } |
| } |
| |
| public static class AutoFieldsService { |
| public String serviceName; |
| public String mapName; |
| public String defaultFieldType; |
| public int defaultPosition; |
| public AutoFieldsService(Element element) { |
| this.serviceName = element.getAttribute("service-name"); |
| this.mapName = element.getAttribute("map-name"); |
| this.defaultFieldType = element.getAttribute("default-field-type"); |
| String positionStr = element.getAttribute("default-position"); |
| int position = 1; |
| try { |
| if (UtilValidate.isNotEmpty(positionStr)) { |
| position = Integer.valueOf(positionStr); |
| } |
| } catch (Exception e) { |
| Debug.logError(e, |
| "Could not convert position attribute of the field element to an integer: [" + positionStr + "], using the default of the form renderer", |
| module); |
| } |
| this.defaultPosition = position; |
| } |
| } |
| |
| public static class AutoFieldsEntity { |
| public String entityName; |
| public String mapName; |
| public String defaultFieldType; |
| public int defaultPosition; |
| public AutoFieldsEntity(Element element) { |
| this.entityName = element.getAttribute("entity-name"); |
| this.mapName = element.getAttribute("map-name"); |
| this.defaultFieldType = element.getAttribute("default-field-type"); |
| String positionStr = element.getAttribute("default-position"); |
| int position = 1; |
| try { |
| if (UtilValidate.isNotEmpty(positionStr)) { |
| position = Integer.valueOf(positionStr); |
| } |
| } catch (Exception e) { |
| Debug.logError(e, |
| "Could not convert position attribute of the field element to an integer: [" + positionStr + "], using the default of the form renderer", |
| module); |
| } |
| this.defaultPosition = position; |
| } |
| } |
| |
| public static class SortField { |
| protected String fieldName; |
| protected Integer position = null; |
| |
| public SortField(String name, String position) { |
| this.fieldName = name; |
| if (UtilValidate.isNotEmpty(position)){ |
| Integer posParam = null; |
| try { |
| posParam = Integer.valueOf(position); |
| } |
| catch(Exception e) {/* just ignore the exception*/} |
| this.position = posParam; |
| } |
| } |
| |
| public SortField(String name) { |
| this(name, null); |
| } |
| |
| public String getFieldName() { |
| return this.fieldName; |
| } |
| |
| public Integer getPosition() { |
| return this.position; |
| } |
| } |
| |
| public static interface FieldGroupBase {} |
| |
| public static class FieldGroup implements FieldGroupBase { |
| public String id; |
| public String style; |
| public String title; |
| public boolean collapsible = false; |
| public boolean initiallyCollapsed = false; |
| protected ModelForm modelForm; |
| protected static int baseSeqNo = 0; |
| protected static String baseId = "_G"; |
| public FieldGroup(Element sortOrderElement, ModelForm modelForm) { |
| |
| this.modelForm = modelForm; |
| if (sortOrderElement != null) { |
| this.id = sortOrderElement.getAttribute("id"); |
| if (UtilValidate.isEmpty(this.id)) { |
| String lastGroupId = baseId + baseSeqNo++ + "_"; |
| this.setId(lastGroupId); |
| } |
| this.style = sortOrderElement.getAttribute("style"); |
| this.title = sortOrderElement.getAttribute("title"); |
| this.collapsible = "true".equals(sortOrderElement.getAttribute("collapsible")); |
| this.initiallyCollapsed = "true".equals(sortOrderElement.getAttribute("initially-collapsed")); |
| if (this.initiallyCollapsed) { |
| this.collapsible = true; |
| } |
| |
| for (Element sortFieldElement: UtilXml.childElementList(sortOrderElement, "sort-field")) { |
| modelForm.sortOrderFields.add(new SortField(sortFieldElement.getAttribute("name"),sortFieldElement.getAttribute("position"))); |
| modelForm.fieldGroupMap.put(sortFieldElement.getAttribute("name"), this); |
| } |
| } else { |
| String lastGroupId = baseId + baseSeqNo++ + "_"; |
| this.setId(lastGroupId); |
| } |
| } |
| |
| public String getId() { |
| return this.id; |
| } |
| |
| public void setId(String id) { |
| this.id = id; |
| } |
| |
| public String getStyle() { |
| return this.style; |
| } |
| |
| public String getTitle() { |
| return this.title; |
| } |
| |
| public Boolean collapsible() { |
| return this.collapsible; |
| } |
| |
| public Boolean initiallyCollapsed() { |
| return this.initiallyCollapsed; |
| } |
| |
| public void renderStartString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) throws IOException { |
| if (!modelForm.fieldGroupList.isEmpty()) { |
| if (shouldUse(context)) { |
| formStringRenderer.renderFieldGroupOpen(writer, context, this); |
| } |
| } |
| formStringRenderer.renderFormatSingleWrapperOpen(writer, context, modelForm); |
| } |
| |
| public void renderEndString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) throws IOException { |
| formStringRenderer.renderFormatSingleWrapperClose(writer, context, modelForm); |
| if (!modelForm.fieldGroupList.isEmpty()) { |
| if (shouldUse(context)) { |
| formStringRenderer.renderFieldGroupClose(writer, context, this); |
| } |
| } |
| } |
| |
| public boolean shouldUse(Map<String, Object> context) { |
| for (String fieldName : modelForm.fieldGroupMap.keySet()) { |
| FieldGroupBase group = modelForm.fieldGroupMap.get(fieldName); |
| if (group instanceof FieldGroup) { |
| FieldGroup fieldgroup =(FieldGroup) group; |
| if (this.id.equals(fieldgroup.getId())) { |
| for (ModelFormField modelField : modelForm.fieldList) { |
| if (fieldName.equals(modelField.getName()) && modelField.shouldUse(context)) { |
| return true; |
| } |
| } |
| } |
| } |
| } |
| return false; |
| } |
| } |
| |
| public static class Banner implements FieldGroupBase { |
| protected ModelForm modelForm; |
| public FlexibleStringExpander style; |
| public FlexibleStringExpander text; |
| public FlexibleStringExpander textStyle; |
| public FlexibleStringExpander leftText; |
| public FlexibleStringExpander leftTextStyle; |
| public FlexibleStringExpander rightText; |
| public FlexibleStringExpander rightTextStyle; |
| |
| public Banner(Element sortOrderElement, ModelForm modelForm) { |
| this.modelForm = modelForm; |
| this.style = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("style")); |
| this.text = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("text")); |
| this.textStyle = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("text-style")); |
| this.leftText = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("left-text")); |
| this.leftTextStyle = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("left-text-style")); |
| this.rightText = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("right-text")); |
| this.rightTextStyle = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("right-text-style")); |
| } |
| |
| public String getStyle(Map<String, Object> context) { return this.style.expandString(context); } |
| public String getText(Map<String, Object> context) { return this.text.expandString(context); } |
| public String getTextStyle(Map<String, Object> context) { return this.textStyle.expandString(context); } |
| public String getLeftText(Map<String, Object> context) { return this.leftText.expandString(context); } |
| public String getLeftTextStyle(Map<String, Object> context) { return this.leftTextStyle.expandString(context); } |
| public String getRightText(Map<String, Object> context) { return this.rightText.expandString(context); } |
| public String getRightTextStyle(Map<String, Object> context) { return this.rightTextStyle.expandString(context); } |
| |
| public void renderString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) throws IOException { |
| formStringRenderer.renderBanner(writer, context, this); |
| } |
| } |
| |
| public Set<String> getAllEntityNamesUsed() { |
| Set<String> allEntityNamesUsed = FastSet.newInstance(); |
| for (AutoFieldsEntity autoFieldsEntity: this.autoFieldsEntities) { |
| allEntityNamesUsed.add(autoFieldsEntity.entityName); |
| } |
| if (this.actions != null) { |
| for (ModelFormAction modelFormAction: this.actions) { |
| if (modelFormAction instanceof ModelFormAction.EntityOne) { |
| allEntityNamesUsed.add(((ModelFormAction.EntityOne)modelFormAction).finder.getEntityName()); |
| } else if (modelFormAction instanceof ModelFormAction.EntityAnd) { |
| allEntityNamesUsed.add(((ModelFormAction.EntityAnd)modelFormAction).finder.getEntityName()); |
| } else if (modelFormAction instanceof ModelFormAction.EntityCondition) { |
| allEntityNamesUsed.add(((ModelFormAction.EntityCondition)modelFormAction).finder.getEntityName()); |
| } |
| |
| } |
| } |
| if (this.rowActions != null) { |
| for (ModelFormAction modelFormAction: this.rowActions) { |
| if (modelFormAction instanceof ModelFormAction.EntityOne) { |
| allEntityNamesUsed.add(((ModelFormAction.EntityOne)modelFormAction).finder.getEntityName()); |
| } else if (modelFormAction instanceof ModelFormAction.EntityAnd) { |
| allEntityNamesUsed.add(((ModelFormAction.EntityAnd)modelFormAction).finder.getEntityName()); |
| } else if (modelFormAction instanceof ModelFormAction.EntityCondition) { |
| allEntityNamesUsed.add(((ModelFormAction.EntityCondition)modelFormAction).finder.getEntityName()); |
| } |
| } |
| } |
| for (ModelFormField modelFormField: this.fieldList) { |
| if (UtilValidate.isNotEmpty(modelFormField.getEntityName())) { |
| allEntityNamesUsed.add(modelFormField.getEntityName()); |
| } |
| if (modelFormField.getFieldInfo() instanceof ModelFormField.DisplayEntityField) { |
| allEntityNamesUsed.add(((ModelFormField.DisplayEntityField)modelFormField.getFieldInfo()).entityName); |
| } |
| if (modelFormField.getFieldInfo() instanceof ModelFormField.FieldInfoWithOptions) { |
| for (ModelFormField.OptionSource optionSource: ((ModelFormField.FieldInfoWithOptions)modelFormField.getFieldInfo()).optionSources) { |
| if (optionSource instanceof ModelFormField.EntityOptions) { |
| allEntityNamesUsed.add(((ModelFormField.EntityOptions)optionSource).entityName); |
| } |
| } |
| } |
| } |
| return allEntityNamesUsed; |
| } |
| |
| public Set<String> getAllServiceNamesUsed() { |
| Set<String> allServiceNamesUsed = FastSet.newInstance(); |
| for (AutoFieldsService autoFieldsService: this.autoFieldsServices) { |
| allServiceNamesUsed.add(autoFieldsService.serviceName); |
| } |
| if (this.actions != null) { |
| for (ModelFormAction modelFormAction: this.actions) { |
| try { |
| ModelFormAction.Service service = (ModelFormAction.Service) modelFormAction; |
| if (!service.serviceNameExdr.isEmpty()) { |
| allServiceNamesUsed.add(service.serviceNameExdr.toString()); |
| } |
| } catch (ClassCastException e) {} |
| } |
| } |
| if (this.rowActions != null) { |
| for (ModelFormAction modelFormAction: this.rowActions) { |
| try { |
| ModelFormAction.Service service = (ModelFormAction.Service) modelFormAction; |
| if (!service.serviceNameExdr.isEmpty()) { |
| allServiceNamesUsed.add(service.serviceNameExdr.toString()); |
| } |
| } catch (ClassCastException e) {} |
| } |
| } |
| for (ModelFormField modelFormField: this.fieldList) { |
| if (UtilValidate.isNotEmpty(modelFormField.getServiceName())) { |
| allServiceNamesUsed.add(modelFormField.getServiceName()); |
| } |
| } |
| return allServiceNamesUsed; |
| } |
| |
| public Set<String> getLinkedRequestsLocationAndUri() throws GeneralException { |
| Set<String> allRequestsUsed = FastSet.newInstance(); |
| |
| if (this.fieldList != null) { |
| for (ModelFormField modelFormField: this.fieldList) { |
| if (modelFormField.getFieldInfo() instanceof ModelFormField.HyperlinkField) { |
| ModelFormField.HyperlinkField link = (ModelFormField.HyperlinkField) modelFormField.getFieldInfo(); |
| String target = link.getTarget(null); |
| String urlMode = link.getTargetType(); |
| |
| Set<String> controllerLocAndRequestSet = ConfigXMLReader.findControllerRequestUniqueForTargetType(target, urlMode); |
| if (controllerLocAndRequestSet != null) { |
| allRequestsUsed.addAll(controllerLocAndRequestSet); |
| } |
| } else if (modelFormField.getFieldInfo() instanceof ModelFormField.DisplayEntityField) { |
| ModelFormField.DisplayEntityField parentField = (ModelFormField.DisplayEntityField) modelFormField.getFieldInfo(); |
| if (parentField.subHyperlink != null) { |
| Set<String> controllerLocAndRequestSet = ConfigXMLReader.findControllerRequestUniqueForTargetType(parentField.subHyperlink.getTarget(null), parentField.subHyperlink.getTargetType()); |
| if (controllerLocAndRequestSet != null) { |
| allRequestsUsed.addAll(controllerLocAndRequestSet); |
| } |
| } |
| } else if (modelFormField.getFieldInfo() instanceof ModelFormField.TextField) { |
| ModelFormField.TextField parentField = (ModelFormField.TextField) modelFormField.getFieldInfo(); |
| if (parentField.subHyperlink != null) { |
| Set<String> controllerLocAndRequestSet = ConfigXMLReader.findControllerRequestUniqueForTargetType(parentField.subHyperlink.getTarget(null), parentField.subHyperlink.getTargetType()); |
| if (controllerLocAndRequestSet != null) { |
| allRequestsUsed.addAll(controllerLocAndRequestSet); |
| } |
| } |
| } else if (modelFormField.getFieldInfo() instanceof ModelFormField.DropDownField) { |
| ModelFormField.DropDownField parentField = (ModelFormField.DropDownField) modelFormField.getFieldInfo(); |
| if (parentField.subHyperlink != null) { |
| Set<String> controllerLocAndRequestSet = ConfigXMLReader.findControllerRequestUniqueForTargetType(parentField.subHyperlink.getTarget(null), parentField.subHyperlink.getTargetType()); |
| if (controllerLocAndRequestSet != null) { |
| allRequestsUsed.addAll(controllerLocAndRequestSet); |
| } |
| } |
| } else if (modelFormField.getFieldInfo() instanceof ModelFormField.ImageField) { |
| ModelFormField.ImageField parentField = (ModelFormField.ImageField) modelFormField.getFieldInfo(); |
| if (parentField.subHyperlink != null) { |
| Set<String> controllerLocAndRequestSet = ConfigXMLReader.findControllerRequestUniqueForTargetType(parentField.subHyperlink.getTarget(null), parentField.subHyperlink.getTargetType()); |
| if (controllerLocAndRequestSet != null) { |
| allRequestsUsed.addAll(controllerLocAndRequestSet); |
| } |
| } |
| } |
| } |
| } |
| return allRequestsUsed; |
| } |
| |
| public Set<String> getTargetedRequestsLocationAndUri() throws GeneralException { |
| Set<String> allRequestsUsed = FastSet.newInstance(); |
| |
| if (this.altTargets != null) { |
| for (AltTarget altTarget: this.altTargets) { |
| String target = altTarget.targetExdr.getOriginal(); |
| String urlMode = "intra-app"; |
| |
| Set<String> controllerLocAndRequestSet = ConfigXMLReader.findControllerRequestUniqueForTargetType(target, urlMode); |
| if (controllerLocAndRequestSet != null) { |
| allRequestsUsed.addAll(controllerLocAndRequestSet); |
| } |
| } |
| } |
| |
| if (!this.target.isEmpty()) { |
| String target = this.target.getOriginal(); |
| String urlMode = UtilValidate.isNotEmpty(this.targetType) ? this.targetType : "intra-app"; |
| if (target.indexOf("${") < 0) { |
| Set<String> controllerLocAndRequestSet = ConfigXMLReader.findControllerRequestUniqueForTargetType(target, urlMode); |
| if (controllerLocAndRequestSet != null) { |
| allRequestsUsed.addAll(controllerLocAndRequestSet); |
| } |
| } |
| } |
| |
| return allRequestsUsed; |
| } |
| } |