You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2015/01/25 18:18:25 UTC

svn commit: r1654670 [2/2] - in /ofbiz/trunk: applications/accounting/widget/ framework/widget/dtd/ framework/widget/src/org/ofbiz/widget/artifact/ framework/widget/src/org/ofbiz/widget/model/ framework/widget/src/org/ofbiz/widget/renderer/ framework/w...

Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelGrid.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelGrid.java?rev=1654670&view=auto
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelGrid.java (added)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelGrid.java Sun Jan 25 17:18:24 2015
@@ -0,0 +1,656 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.widget.model;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.ofbiz.base.util.BshUtil;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.model.ModelReader;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.widget.WidgetWorker;
+import org.w3c.dom.Element;
+
+import bsh.EvalError;
+import bsh.Interpreter;
+
+/**
+ * Models the <grid> element.
+ * 
+ * @see <code>widget-form.xsd</code>
+ */
+@SuppressWarnings("serial")
+public class ModelGrid extends ModelForm {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     DEVELOPERS PLEASE READ
+     * ----------------------------------------------------------------------- *
+     * 
+     * This model is intended to be a read-only data structure that represents
+     * an XML element. Outside of object construction, the class should not
+     * have any behaviors. All behavior should be contained in model visitors.
+     * 
+     * Instances of this class will be shared by multiple threads - therefore
+     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
+     * 
+     * BE VERY CAREFUL when implementing "extends" - parent form collections
+     * must be added to child collections, not replace them. In other words,
+     * do not assign parent collection fields to child collection fields.
+     * 
+     */
+
+    public static final String module = ModelGrid.class.getName();
+
+    /** XML Constructor */
+    public ModelGrid(Element formElement, String formLocation, ModelReader entityModelReader, DispatchContext dispatchContext) {
+        super(formElement, formLocation, entityModelReader, dispatchContext);
+    }
+
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
+    }
+
+    public List<ModelAction> getActions() {
+        return actions;
+    }
+
+    public List<AltRowStyle> getAltRowStyles() {
+        return altRowStyles;
+    }
+
+    public List<AltTarget> getAltTargets() {
+        return altTargets;
+    }
+
+    public List<AutoFieldsEntity> getAutoFieldsEntities() {
+        return autoFieldsEntities;
+    }
+
+    public List<AutoFieldsService> getAutoFieldsServices() {
+        return autoFieldsServices;
+    }
+
+    public Interpreter getBshInterpreter(Map<String, Object> context) throws EvalError {
+        Interpreter bsh = (Interpreter) context.get("bshInterpreter");
+        if (bsh == null) {
+            bsh = BshUtil.makeInterpreter(context);
+            context.put("bshInterpreter", bsh);
+        }
+        return bsh;
+    }
+
+    @Override
+    public String getBoundaryCommentName() {
+        return formLocation + "#" + getName();
+    }
+
+    public boolean getClientAutocompleteFields() {
+        return this.clientAutocompleteFields;
+    }
+
+    public String getContainerId() {
+        // use the name if there is no id
+        if (UtilValidate.isNotEmpty(this.containerId)) {
+            return this.containerId;
+        } else {
+            return this.getName();
+        }
+    }
+
+    public String getContainerStyle() {
+        return this.containerStyle;
+    }
+
+    public String getDefaultEntityName() {
+        return this.defaultEntityName;
+    }
+
+    public FieldGroup getDefaultFieldGroup() {
+        return defaultFieldGroup;
+    }
+
+    public Map<String, ? extends Object> getDefaultMap(Map<String, ? extends Object> context) {
+        return this.defaultMapName.get(context);
+    }
+
+    public String getDefaultMapName() {
+        return this.defaultMapName.getOriginalName();
+    }
+
+    public String getDefaultRequiredFieldStyle() {
+        return this.defaultRequiredFieldStyle;
+    }
+
+    public String getDefaultServiceName() {
+        return this.defaultServiceName;
+    }
+
+    public String getDefaultSortFieldAscStyle() {
+        return this.defaultSortFieldAscStyle;
+    }
+
+    public String getDefaultSortFieldDescStyle() {
+        return this.defaultSortFieldDescStyle;
+    }
+
+    public String getDefaultSortFieldStyle() {
+        return this.defaultSortFieldStyle;
+    }
+
+    public String getDefaultTableStyle() {
+        return this.defaultTableStyle;
+    }
+
+    public String getDefaultTitleAreaStyle() {
+        return this.defaultTitleAreaStyle;
+    }
+
+    public String getDefaultTitleStyle() {
+        return this.defaultTitleStyle;
+    }
+
+    public String getDefaultTooltipStyle() {
+        return this.defaultTooltipStyle;
+    }
+
+    public int getDefaultViewSize() {
+        return defaultViewSize;
+    }
+
+    public String getDefaultWidgetAreaStyle() {
+        return this.defaultWidgetAreaStyle;
+    }
+
+    public String getDefaultWidgetStyle() {
+        return this.defaultWidgetStyle;
+    }
+
+    public String getEvenRowStyle() {
+        return this.evenRowStyle;
+    }
+
+    public List<FieldGroupBase> getFieldGroupList() {
+        return fieldGroupList;
+    }
+
+    public Map<String, FieldGroupBase> getFieldGroupMap() {
+        return fieldGroupMap;
+    }
+
+    public List<ModelFormField> getFieldList() {
+        return fieldList;
+    }
+
+    public String getFocusFieldName() {
+        return focusFieldName;
+    }
+
+    public String getFormLocation() {
+        return this.formLocation;
+    }
+
+    public String getFormTitleAreaStyle() {
+        return this.formTitleAreaStyle;
+    }
+
+    public String getFormWidgetAreaStyle() {
+        return this.formWidgetAreaStyle;
+    }
+
+    public String getHeaderRowStyle() {
+        return this.headerRowStyle;
+    }
+
+    public boolean getHideHeader() {
+        return this.hideHeader;
+    }
+
+    public String getItemIndexSeparator() {
+        if (UtilValidate.isNotEmpty(this.itemIndexSeparator)) {
+            return this.itemIndexSeparator;
+        } else {
+            return "_o_";
+        }
+    }
+
+    public List<String> getLastOrderFields() {
+        return lastOrderFields;
+    }
+
+    public String getListEntryName() {
+        return this.listEntryName;
+    }
+
+    public String getListName() {
+        return this.listName;
+    }
+
+    public String getMultiPaginateIndexField(Map<String, Object> context) {
+        String field = this.paginateIndexField.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = DEFAULT_PAG_INDEX_FIELD;
+        }
+        //  append the paginator number
+        field = field + "_" + WidgetWorker.getPaginatorNumber(context);
+        return field;
+    }
+
+    public String getMultiPaginateSizeField(Map<String, Object> context) {
+        String field = this.paginateSizeField.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = DEFAULT_PAG_SIZE_FIELD;
+        }
+        //  append the paginator number
+        field = field + "_" + WidgetWorker.getPaginatorNumber(context);
+        return field;
+    }
+
+    public List<ModelFormField> getMultiSubmitFields() {
+        return this.multiSubmitFields;
+    }
+
+    public String getOddRowStyle() {
+        return this.oddRowStyle;
+    }
+
+    public List<UpdateArea> getOnPaginateUpdateAreas() {
+        return this.onPaginateUpdateAreas;
+    }
+
+    public List<UpdateArea> getOnSortColumnUpdateAreas() {
+        return this.onSortColumnUpdateAreas;
+    }
+
+    /* Returns the list of ModelForm.UpdateArea objects.
+     */
+    public List<UpdateArea> getOnSubmitUpdateAreas() {
+        return this.onSubmitUpdateAreas;
+    }
+
+    public String getOverrideListSize() {
+        return overrideListSize.getOriginal();
+    }
+
+    public int getOverrideListSize(Map<String, Object> context) {
+        int listSize = 0;
+        if (!this.overrideListSize.isEmpty()) {
+            String size = this.overrideListSize.expandString(context);
+            try {
+                size = size.replaceAll("[^0-9.]", "");
+                listSize = Integer.parseInt(size);
+            } catch (NumberFormatException e) {
+                Debug.logError(e, "Error getting override list size from value " + size, module);
+            }
+        }
+        return listSize;
+    }
+
+    public String getPaginate() {
+        return paginate.getOriginal();
+    }
+
+    public boolean getPaginate(Map<String, Object> context) {
+        String paginate = this.paginate.expandString(context);
+        if (!paginate.isEmpty()) {
+            return Boolean.valueOf(paginate).booleanValue();
+        } else {
+            return true;
+        }
+    }
+
+    public String getPaginateFirstLabel() {
+        return paginateFirstLabel.getOriginal();
+    }
+
+    public String getPaginateFirstLabel(Map<String, Object> context) {
+        Locale locale = (Locale) context.get("locale");
+        String field = this.paginateFirstLabel.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = UtilProperties.getMessage("CommonUiLabels", "CommonFirst", locale);
+        }
+        return field;
+    }
+
+    public String getPaginateFirstStyle() {
+        return DEFAULT_PAG_FIRST_STYLE;
+    }
+
+    public String getPaginateIndexField() {
+        return paginateIndexField.getOriginal();
+    }
+
+    public String getPaginateIndexField(Map<String, Object> context) {
+        String field = this.paginateIndexField.expandString(context);
+        if (field.isEmpty()) {
+            return DEFAULT_PAG_INDEX_FIELD;
+        }
+        return field;
+    }
+
+    public String getPaginateLastLabel() {
+        return paginateLastLabel.getOriginal();
+    }
+
+    public String getPaginateLastLabel(Map<String, Object> context) {
+        Locale locale = (Locale) context.get("locale");
+        String field = this.paginateLastLabel.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = UtilProperties.getMessage("CommonUiLabels", "CommonLast", locale);
+        }
+        return field;
+    }
+
+    public String getPaginateLastStyle() {
+        return DEFAULT_PAG_LAST_STYLE;
+    }
+
+    public String getPaginateNextLabel() {
+        return paginateNextLabel.getOriginal();
+    }
+
+    public String getPaginateNextLabel(Map<String, Object> context) {
+        String field = this.paginateNextLabel.expandString(context);
+        if (field.isEmpty()) {
+            Locale locale = (Locale) context.get("locale");
+            return UtilProperties.getMessage("CommonUiLabels", "CommonNext", locale);
+        }
+        return field;
+    }
+
+    public String getPaginateNextStyle() {
+        return DEFAULT_PAG_NEXT_STYLE;
+    }
+
+    public String getPaginatePreviousLabel() {
+        return paginatePreviousLabel.getOriginal();
+    }
+
+    public String getPaginatePreviousLabel(Map<String, Object> context) {
+        String field = this.paginatePreviousLabel.expandString(context);
+        if (field.isEmpty()) {
+            Locale locale = (Locale) context.get("locale");
+            field = UtilProperties.getMessage("CommonUiLabels", "CommonPrevious", locale);
+        }
+        return field;
+    }
+
+    public String getPaginatePreviousStyle() {
+        return DEFAULT_PAG_PREV_STYLE;
+    }
+
+    public String getPaginateSizeField() {
+        return paginateSizeField.getOriginal();
+    }
+
+    public String getPaginateSizeField(Map<String, Object> context) {
+        String field = this.paginateSizeField.expandString(context);
+        if (field.isEmpty()) {
+            return DEFAULT_PAG_SIZE_FIELD;
+        }
+        return field;
+    }
+
+    public String getPaginateStyle() {
+        return this.paginateStyle;
+    }
+
+    public String getPaginateTarget() {
+        return paginateTarget.getOriginal();
+    }
+
+    public String getPaginateTarget(Map<String, Object> context) {
+        String targ = this.paginateTarget.expandString(context);
+        if (targ.isEmpty()) {
+            Map<String, ?> parameters = UtilGenerics.cast(context.get("parameters"));
+            if (parameters != null && parameters.containsKey("targetRequestUri")) {
+                targ = (String) parameters.get("targetRequestUri");
+            }
+        }
+        return targ;
+    }
+
+    public String getPaginateTargetAnchor() {
+        return this.paginateTargetAnchor;
+    }
+
+    public String getPaginateViewSizeLabel() {
+        return paginateViewSizeLabel.getOriginal();
+    }
+
+    public String getPaginateViewSizeLabel(Map<String, Object> context) {
+        String field = this.paginateViewSizeLabel.expandString(context);
+        if (field.isEmpty()) {
+            Locale locale = (Locale) context.get("locale");
+            return UtilProperties.getMessage("CommonUiLabels", "CommonItemsPerPage", locale);
+        }
+        return field;
+    }
+
+    protected ModelForm getParentModel(Element gridElement, ModelReader entityModelReader, DispatchContext dispatchContext) {
+        ModelForm parentModel = null;
+        String parentResource = gridElement.getAttribute("extends-resource");
+        String parentGrid = gridElement.getAttribute("extends");
+        String gridType = gridElement.getAttribute("type");
+        if (!parentGrid.isEmpty()) {
+            // check if we have a resource name
+            if (!parentResource.isEmpty()) {
+                try {
+                    parentModel = GridFactory.getGridFromLocation(parentResource, parentGrid, entityModelReader, dispatchContext);
+                } catch (Exception e) {
+                    Debug.logError(e, "Failed to load parent grid definition '" + parentGrid + "' at resource '" + parentResource
+                            + "'", module);
+                }
+            } else if (!parentGrid.equals(gridElement.getAttribute("name"))) {
+                // try to find a grid definition in the same file
+                Element rootElement = gridElement.getOwnerDocument().getDocumentElement();
+                List<? extends Element> gridElements = UtilXml.childElementList(rootElement, "grid");
+                if (gridElements.isEmpty()) {
+                    // Backwards compatibility - look for form definitions
+                    gridElements = UtilXml.childElementList(rootElement, "form");
+                }
+                for (Element parentElement : gridElements) {
+                    if (parentElement.getAttribute("name").equals(parentGrid) && gridType.equals(parentElement.getAttribute("type"))) {
+                        parentModel = GridFactory.createModelGrid(parentElement, entityModelReader, dispatchContext, parentResource, parentGrid);
+                        break;
+                    }
+                }
+                if (parentModel == null) {
+                    Debug.logError("Failed to find parent grid definition '" + parentGrid + "' in same document.", module);
+                }
+            } else {
+                Debug.logError("Recursive grid definition found for '" + gridElement.getAttribute("name") + ".'", module);
+            }
+        }
+        return parentModel;
+    }
+
+    public String getPassedRowCount(Map<String, Object> context) {
+        return rowCountExdr.expandString(context);
+    }
+
+    public List<ModelAction> getRowActions() {
+        return rowActions;
+    }
+
+    public String getRowCount() {
+        return rowCountExdr.getOriginal();
+    }
+
+    public boolean getSeparateColumns() {
+        return this.separateColumns;
+    }
+
+    public boolean getSkipEnd() {
+        return this.skipEnd;
+    }
+
+    public boolean getSkipStart() {
+        return this.skipStart;
+    }
+
+    public String getSortField(Map<String, Object> context) {
+        String value = null;
+        try {
+            value = (String) context.get(this.sortFieldParameterName);
+            if (value == null) {
+                Map<String, String> parameters = UtilGenerics.cast(context.get("parameters"));
+                if (parameters != null) {
+                    value = parameters.get(this.sortFieldParameterName);
+                }
+            }
+        } catch (Exception e) {
+            Debug.logWarning(e, "Error getting sortField: " + e.toString(), module);
+        }
+        return value;
+    }
+
+    public String getSortFieldParameterName() {
+        return this.sortFieldParameterName;
+    }
+
+    public List<SortField> getSortOrderFields() {
+        return sortOrderFields;
+    }
+
+    /**
+     * iterate through alt-row-styles list to see if should be used, then add style
+     * @return The style for item row
+     */
+    public String getStyleAltRowStyle(Map<String, Object> context) {
+        String styles = "";
+        try {
+            // use the same Interpreter (ie with the same context setup) for all evals
+            Interpreter bsh = this.getBshInterpreter(context);
+            for (AltRowStyle altRowStyle : this.altRowStyles) {
+                Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(altRowStyle.useWhen));
+                // retVal should be a Boolean, if not something weird is up...
+                if (retVal instanceof Boolean) {
+                    Boolean boolVal = (Boolean) retVal;
+                    if (boolVal.booleanValue()) {
+                        styles += altRowStyle.style;
+                    }
+                } else {
+                    throw new IllegalArgumentException("Return value from style condition eval was not a Boolean: "
+                            + retVal.getClass().getName() + " [" + retVal + "] of form " + getName());
+                }
+            }
+        } catch (EvalError e) {
+            String errmsg = "Error evaluating BeanShell style conditions on form " + getName();
+            Debug.logError(e, errmsg, module);
+            throw new IllegalArgumentException(errmsg);
+        }
+        return styles;
+    }
+
+    public String getTarget() {
+        return target.getOriginal();
+    }
+
+    /** iterate through altTargets list to see if any should be used, if not return original target
+     * @return The target for this Form
+     */
+    public String getTarget(Map<String, Object> context, String targetType) {
+        Map<String, Object> expanderContext = context;
+        UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+        if (simpleEncoder != null) {
+            expanderContext = UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
+        }
+        try {
+            // use the same Interpreter (ie with the same context setup) for all evals
+            Interpreter bsh = this.getBshInterpreter(context);
+            for (AltTarget altTarget : this.altTargets) {
+                String useWhen = FlexibleStringExpander.expandString(altTarget.useWhen, context);
+                Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhen));
+                boolean condTrue = false;
+                // retVal should be a Boolean, if not something weird is up...
+                if (retVal instanceof Boolean) {
+                    Boolean boolVal = (Boolean) retVal;
+                    condTrue = boolVal.booleanValue();
+                } else {
+                    throw new IllegalArgumentException("Return value from target condition eval was not a Boolean: "
+                            + retVal.getClass().getName() + " [" + retVal + "] of form " + getName());
+                }
+
+                if (condTrue && !targetType.equals("inter-app")) {
+                    return altTarget.targetExdr.expandString(expanderContext);
+                }
+            }
+        } catch (EvalError e) {
+            String errmsg = "Error evaluating BeanShell target conditions on form " + getName();
+            Debug.logError(e, errmsg, module);
+            throw new IllegalArgumentException(errmsg);
+        }
+        return target.expandString(expanderContext);
+    }
+
+    public String getTargetType() {
+        return this.targetType;
+    }
+
+    public String getTargetWindow() {
+        return targetWindowExdr.getOriginal();
+    }
+
+    public String getTargetWindow(Map<String, Object> context) {
+        return this.targetWindowExdr.expandString(context);
+    }
+
+    public String getTitle() {
+        return this.title;
+    }
+
+    public String getTooltip() {
+        return this.tooltip;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public boolean getUseRowSubmit() {
+        return this.useRowSubmit;
+    }
+
+    public Set<String> getUseWhenFields() {
+        return useWhenFields;
+    }
+    public boolean getGroupColumns() {
+        return groupColumns;
+    }
+
+    public boolean isOverridenListSize() {
+        return !this.overrideListSize.isEmpty();
+    }
+
+    public void runFormActions(Map<String, Object> context) {
+        AbstractModelAction.runSubActions(this.actions, context);
+    }
+}

Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreenWidget.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreenWidget.java?rev=1654670&r1=1654669&r2=1654670&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreenWidget.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreenWidget.java Sun Jan 25 17:18:24 2015
@@ -1046,9 +1046,9 @@ public abstract class ModelScreenWidget
                 }
                 UtilGenerics.<MapStack<String>>cast(context).push();
             }
-            ModelForm modelForm = getModelForm(context);
-            FormRenderer renderer = new FormRenderer(modelForm, formStringRenderer);
             try {
+                ModelForm modelForm = getModelForm(context);
+                FormRenderer renderer = new FormRenderer(modelForm, formStringRenderer);
                 renderer.render(writer, context);
             } catch (Exception e) {
                 String errMsg = "Error rendering included form named [" + getName() + "] at location [" + this.getLocation(context) + "]: " + e.toString();
@@ -1061,12 +1061,97 @@ public abstract class ModelScreenWidget
             }
         }
 
+        public ModelForm getModelForm(Map<String, Object> context) throws IOException, SAXException, ParserConfigurationException {
+            String name = this.getName(context);
+            String location = this.getLocation(context);
+            return FormFactory.getFormFromLocation(location, name, getModelScreen().getDelegator(context).getModelReader(),
+                    getModelScreen().getDispatcher(context).getDispatchContext());
+        }
+
+        public String getName(Map<String, Object> context) {
+            return this.nameExdr.expandString(context);
+        }
+
+        public String getLocation() {
+            return locationExdr.getOriginal();
+        }
+
+        public String getLocation(Map<String, Object> context) {
+            return this.locationExdr.expandString(context);
+        }
+
+        public boolean shareScope(Map<String, Object> context) {
+            String shareScopeString = this.shareScopeExdr.expandString(context);
+            // defaults to false, so anything but true is false
+            return "true".equals(shareScopeString);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getNameExdr() {
+            return nameExdr;
+        }
+
+        public FlexibleStringExpander getLocationExdr() {
+            return locationExdr;
+        }
+
+        public FlexibleStringExpander getShareScopeExdr() {
+            return shareScopeExdr;
+        }
+    }
+
+    public static final class Grid extends ModelScreenWidget {
+        public static final String TAG_NAME = "include-grid";
+        private final FlexibleStringExpander nameExdr;
+        private final FlexibleStringExpander locationExdr;
+        private final FlexibleStringExpander shareScopeExdr;
+
+        public Grid(ModelScreen modelScreen, Element formElement) {
+            super(modelScreen, formElement);
+            this.nameExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("name"));
+            this.locationExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("location"));
+            this.shareScopeExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("share-scope"));
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
+            // Output format might not support forms, so make form rendering optional.
+            FormStringRenderer formStringRenderer = (FormStringRenderer) context.get("formStringRenderer");
+            if (formStringRenderer == null) {
+                Debug.logVerbose("FormStringRenderer instance not found in rendering context, form not rendered.", module);
+                return;
+            }
+            boolean protectScope = !shareScope(context);
+            if (protectScope) {
+                if (!(context instanceof MapStack<?>)) {
+                    context = MapStack.create(context);
+                }
+                UtilGenerics.<MapStack<String>>cast(context).push();
+            }
+            ModelForm modelForm = getModelForm(context);
+            FormRenderer renderer = new FormRenderer(modelForm, formStringRenderer);
+            try {
+                renderer.render(writer, context);
+            } catch (Exception e) {
+                String errMsg = "Error rendering included grid named [" + getName() + "] at location [" + this.getLocation(context) + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg + e);
+            }
+            if (protectScope) {
+                UtilGenerics.<MapStack<String>>cast(context).pop();
+            }
+        }
+
         public ModelForm getModelForm(Map<String, Object> context) {
             ModelForm modelForm = null;
             String name = this.getName(context);
             String location = this.getLocation(context);
             try {
-                modelForm = FormFactory.getFormFromLocation(location, name, getModelScreen().getDelegator(context).getModelReader(), getModelScreen().getDispatcher(context).getDispatchContext());
+                modelForm = GridFactory.getGridFromLocation(location, name, getModelScreen().getDelegator(context).getModelReader(), getModelScreen().getDispatcher(context).getDispatchContext());
             } catch (Exception e) {
                 String errMsg = "Error rendering included form named [" + name + "] at location [" + location + "]: ";
                 Debug.logError(e, errMsg, module);
@@ -1109,7 +1194,6 @@ public abstract class ModelScreenWidget
         public FlexibleStringExpander getShareScopeExdr() {
             return shareScopeExdr;
         }
-
     }
 
     public static final class Tree extends ModelScreenWidget {

Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelSingleForm.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelSingleForm.java?rev=1654670&view=auto
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelSingleForm.java (added)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelSingleForm.java Sun Jan 25 17:18:24 2015
@@ -0,0 +1,654 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.widget.model;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.ofbiz.base.util.BshUtil;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.model.ModelReader;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.widget.WidgetWorker;
+import org.w3c.dom.Element;
+
+import bsh.EvalError;
+import bsh.Interpreter;
+
+/**
+ * Models the &lt;form&gt; element.
+ * 
+ * @see <code>widget-form.xsd</code>
+ */
+@SuppressWarnings("serial")
+public class ModelSingleForm extends ModelForm {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     DEVELOPERS PLEASE READ
+     * ----------------------------------------------------------------------- *
+     * 
+     * This model is intended to be a read-only data structure that represents
+     * an XML element. Outside of object construction, the class should not
+     * have any behaviors. All behavior should be contained in model visitors.
+     * 
+     * Instances of this class will be shared by multiple threads - therefore
+     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
+     * 
+     * BE VERY CAREFUL when implementing "extends" - parent form collections
+     * must be added to child collections, not replace them. In other words,
+     * do not assign parent collection fields to child collection fields.
+     * 
+     */
+
+    public static final String module = ModelSingleForm.class.getName();
+
+    /** XML Constructor */
+    public ModelSingleForm(Element formElement, String formLocation, ModelReader entityModelReader, DispatchContext dispatchContext) {
+        super(formElement, formLocation, entityModelReader, dispatchContext);
+    }
+
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
+    }
+    public List<ModelAction> getActions() {
+        return actions;
+    }
+
+    public List<AltRowStyle> getAltRowStyles() {
+        return altRowStyles;
+    }
+
+    public List<AltTarget> getAltTargets() {
+        return altTargets;
+    }
+
+    public List<AutoFieldsEntity> getAutoFieldsEntities() {
+        return autoFieldsEntities;
+    }
+
+    public List<AutoFieldsService> getAutoFieldsServices() {
+        return autoFieldsServices;
+    }
+
+    public Interpreter getBshInterpreter(Map<String, Object> context) throws EvalError {
+        Interpreter bsh = (Interpreter) context.get("bshInterpreter");
+        if (bsh == null) {
+            bsh = BshUtil.makeInterpreter(context);
+            context.put("bshInterpreter", bsh);
+        }
+        return bsh;
+    }
+
+    @Override
+    public String getBoundaryCommentName() {
+        return formLocation + "#" + getName();
+    }
+
+    public boolean getClientAutocompleteFields() {
+        return this.clientAutocompleteFields;
+    }
+
+    public String getContainerId() {
+        // use the name if there is no id
+        if (UtilValidate.isNotEmpty(this.containerId)) {
+            return this.containerId;
+        } else {
+            return this.getName();
+        }
+    }
+
+    public String getContainerStyle() {
+        return this.containerStyle;
+    }
+
+    public String getDefaultEntityName() {
+        return this.defaultEntityName;
+    }
+
+    public FieldGroup getDefaultFieldGroup() {
+        return defaultFieldGroup;
+    }
+
+    public Map<String, ? extends Object> getDefaultMap(Map<String, ? extends Object> context) {
+        return this.defaultMapName.get(context);
+    }
+
+    public String getDefaultMapName() {
+        return this.defaultMapName.getOriginalName();
+    }
+
+    public String getDefaultRequiredFieldStyle() {
+        return this.defaultRequiredFieldStyle;
+    }
+
+    public String getDefaultServiceName() {
+        return this.defaultServiceName;
+    }
+
+    public String getDefaultSortFieldAscStyle() {
+        return this.defaultSortFieldAscStyle;
+    }
+
+    public String getDefaultSortFieldDescStyle() {
+        return this.defaultSortFieldDescStyle;
+    }
+
+    public String getDefaultSortFieldStyle() {
+        return this.defaultSortFieldStyle;
+    }
+
+    public String getDefaultTableStyle() {
+        return this.defaultTableStyle;
+    }
+
+    public String getDefaultTitleAreaStyle() {
+        return this.defaultTitleAreaStyle;
+    }
+
+    public String getDefaultTitleStyle() {
+        return this.defaultTitleStyle;
+    }
+
+    public String getDefaultTooltipStyle() {
+        return this.defaultTooltipStyle;
+    }
+
+    public int getDefaultViewSize() {
+        return defaultViewSize;
+    }
+
+    public String getDefaultWidgetAreaStyle() {
+        return this.defaultWidgetAreaStyle;
+    }
+
+    public String getDefaultWidgetStyle() {
+        return this.defaultWidgetStyle;
+    }
+
+    public String getEvenRowStyle() {
+        return this.evenRowStyle;
+    }
+
+    public List<FieldGroupBase> getFieldGroupList() {
+        return fieldGroupList;
+    }
+
+    public Map<String, FieldGroupBase> getFieldGroupMap() {
+        return fieldGroupMap;
+    }
+
+    public List<ModelFormField> getFieldList() {
+        return fieldList;
+    }
+
+    public String getFocusFieldName() {
+        return focusFieldName;
+    }
+
+    public String getFormLocation() {
+        return this.formLocation;
+    }
+
+    public String getFormTitleAreaStyle() {
+        return this.formTitleAreaStyle;
+    }
+
+    public String getFormWidgetAreaStyle() {
+        return this.formWidgetAreaStyle;
+    }
+
+    public String getHeaderRowStyle() {
+        return this.headerRowStyle;
+    }
+
+    public boolean getHideHeader() {
+        return this.hideHeader;
+    }
+
+    public String getItemIndexSeparator() {
+        if (UtilValidate.isNotEmpty(this.itemIndexSeparator)) {
+            return this.itemIndexSeparator;
+        } else {
+            return "_o_";
+        }
+    }
+
+    public List<String> getLastOrderFields() {
+        return lastOrderFields;
+    }
+
+    public String getListEntryName() {
+        return this.listEntryName;
+    }
+
+    public String getListName() {
+        return this.listName;
+    }
+
+    public String getMultiPaginateIndexField(Map<String, Object> context) {
+        String field = this.paginateIndexField.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = DEFAULT_PAG_INDEX_FIELD;
+        }
+        //  append the paginator number
+        field = field + "_" + WidgetWorker.getPaginatorNumber(context);
+        return field;
+    }
+
+    public String getMultiPaginateSizeField(Map<String, Object> context) {
+        String field = this.paginateSizeField.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = DEFAULT_PAG_SIZE_FIELD;
+        }
+        //  append the paginator number
+        field = field + "_" + WidgetWorker.getPaginatorNumber(context);
+        return field;
+    }
+
+    public List<ModelFormField> getMultiSubmitFields() {
+        return this.multiSubmitFields;
+    }
+
+    public String getOddRowStyle() {
+        return this.oddRowStyle;
+    }
+
+    public List<UpdateArea> getOnPaginateUpdateAreas() {
+        return this.onPaginateUpdateAreas;
+    }
+
+    public List<UpdateArea> getOnSortColumnUpdateAreas() {
+        return this.onSortColumnUpdateAreas;
+    }
+
+    /* Returns the list of ModelForm.UpdateArea objects.
+     */
+    public List<UpdateArea> getOnSubmitUpdateAreas() {
+        return this.onSubmitUpdateAreas;
+    }
+
+    public String getOverrideListSize() {
+        return overrideListSize.getOriginal();
+    }
+
+    public int getOverrideListSize(Map<String, Object> context) {
+        int listSize = 0;
+        if (!this.overrideListSize.isEmpty()) {
+            String size = this.overrideListSize.expandString(context);
+            try {
+                size = size.replaceAll("[^0-9.]", "");
+                listSize = Integer.parseInt(size);
+            } catch (NumberFormatException e) {
+                Debug.logError(e, "Error getting override list size from value " + size, module);
+            }
+        }
+        return listSize;
+    }
+
+    public String getPaginate() {
+        return paginate.getOriginal();
+    }
+
+    public boolean getPaginate(Map<String, Object> context) {
+        String paginate = this.paginate.expandString(context);
+        if (!paginate.isEmpty()) {
+            return Boolean.valueOf(paginate).booleanValue();
+        } else {
+            return true;
+        }
+    }
+
+    public String getPaginateFirstLabel() {
+        return paginateFirstLabel.getOriginal();
+    }
+
+    public String getPaginateFirstLabel(Map<String, Object> context) {
+        Locale locale = (Locale) context.get("locale");
+        String field = this.paginateFirstLabel.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = UtilProperties.getMessage("CommonUiLabels", "CommonFirst", locale);
+        }
+        return field;
+    }
+
+    public String getPaginateFirstStyle() {
+        return DEFAULT_PAG_FIRST_STYLE;
+    }
+
+    public String getPaginateIndexField() {
+        return paginateIndexField.getOriginal();
+    }
+
+    public String getPaginateIndexField(Map<String, Object> context) {
+        String field = this.paginateIndexField.expandString(context);
+        if (field.isEmpty()) {
+            return DEFAULT_PAG_INDEX_FIELD;
+        }
+        return field;
+    }
+
+    public String getPaginateLastLabel() {
+        return paginateLastLabel.getOriginal();
+    }
+
+    public String getPaginateLastLabel(Map<String, Object> context) {
+        Locale locale = (Locale) context.get("locale");
+        String field = this.paginateLastLabel.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = UtilProperties.getMessage("CommonUiLabels", "CommonLast", locale);
+        }
+        return field;
+    }
+
+    public String getPaginateLastStyle() {
+        return DEFAULT_PAG_LAST_STYLE;
+    }
+
+    public String getPaginateNextLabel() {
+        return paginateNextLabel.getOriginal();
+    }
+
+    public String getPaginateNextLabel(Map<String, Object> context) {
+        String field = this.paginateNextLabel.expandString(context);
+        if (field.isEmpty()) {
+            Locale locale = (Locale) context.get("locale");
+            return UtilProperties.getMessage("CommonUiLabels", "CommonNext", locale);
+        }
+        return field;
+    }
+
+    public String getPaginateNextStyle() {
+        return DEFAULT_PAG_NEXT_STYLE;
+    }
+
+    public String getPaginatePreviousLabel() {
+        return paginatePreviousLabel.getOriginal();
+    }
+
+    public String getPaginatePreviousLabel(Map<String, Object> context) {
+        String field = this.paginatePreviousLabel.expandString(context);
+        if (field.isEmpty()) {
+            Locale locale = (Locale) context.get("locale");
+            field = UtilProperties.getMessage("CommonUiLabels", "CommonPrevious", locale);
+        }
+        return field;
+    }
+
+    public String getPaginatePreviousStyle() {
+        return DEFAULT_PAG_PREV_STYLE;
+    }
+
+    public String getPaginateSizeField() {
+        return paginateSizeField.getOriginal();
+    }
+
+    public String getPaginateSizeField(Map<String, Object> context) {
+        String field = this.paginateSizeField.expandString(context);
+        if (field.isEmpty()) {
+            return DEFAULT_PAG_SIZE_FIELD;
+        }
+        return field;
+    }
+
+    public String getPaginateStyle() {
+        return this.paginateStyle;
+    }
+
+    public String getPaginateTarget() {
+        return paginateTarget.getOriginal();
+    }
+
+    public String getPaginateTarget(Map<String, Object> context) {
+        String targ = this.paginateTarget.expandString(context);
+        if (targ.isEmpty()) {
+            Map<String, ?> parameters = UtilGenerics.cast(context.get("parameters"));
+            if (parameters != null && parameters.containsKey("targetRequestUri")) {
+                targ = (String) parameters.get("targetRequestUri");
+            }
+        }
+        return targ;
+    }
+
+    public String getPaginateTargetAnchor() {
+        return this.paginateTargetAnchor;
+    }
+
+    public String getPaginateViewSizeLabel() {
+        return paginateViewSizeLabel.getOriginal();
+    }
+
+    public String getPaginateViewSizeLabel(Map<String, Object> context) {
+        String field = this.paginateViewSizeLabel.expandString(context);
+        if (field.isEmpty()) {
+            Locale locale = (Locale) context.get("locale");
+            return UtilProperties.getMessage("CommonUiLabels", "CommonItemsPerPage", locale);
+        }
+        return field;
+    }
+
+    protected ModelForm getParentModel(Element formElement, ModelReader entityModelReader, DispatchContext dispatchContext) {
+        ModelForm parent = null;
+        String parentResource = formElement.getAttribute("extends-resource");
+        String parentForm = formElement.getAttribute("extends");
+        String formType = formElement.getAttribute("type");
+        if (!parentForm.isEmpty()) {
+            // check if we have a resource name
+            if (!parentResource.isEmpty()) {
+                try {
+                    parent = FormFactory.getFormFromLocation(parentResource, parentForm, entityModelReader, dispatchContext);
+                } 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 parentElement : formElements) {
+                    if (parentElement.getAttribute("name").equals(parentForm) && formType.equals(parentElement.getAttribute("type"))) {
+                        parent = FormFactory.createModelForm(parentElement, entityModelReader, dispatchContext, parentResource,
+                                parentForm);
+                        break;
+                    }
+                }
+                if (parent == null) {
+                    Debug.logError("Failed to find parent form definition '" + parentForm + "' in same document.", module);
+                }
+            } else {
+                Debug.logError("Recursive form definition found for '" + formElement.getAttribute("name") + ".'", module);
+            }
+        }
+        return parent;
+    }
+
+    public String getPassedRowCount(Map<String, Object> context) {
+        return rowCountExdr.expandString(context);
+    }
+
+    public List<ModelAction> getRowActions() {
+        return rowActions;
+    }
+
+    public String getRowCount() {
+        return rowCountExdr.getOriginal();
+    }
+
+    public boolean getSeparateColumns() {
+        return this.separateColumns;
+    }
+
+    public boolean getSkipEnd() {
+        return this.skipEnd;
+    }
+
+    public boolean getSkipStart() {
+        return this.skipStart;
+    }
+
+    public String getSortField(Map<String, Object> context) {
+        String value = null;
+        try {
+            value = (String) context.get(this.sortFieldParameterName);
+            if (value == null) {
+                Map<String, String> parameters = UtilGenerics.cast(context.get("parameters"));
+                if (parameters != null) {
+                    value = parameters.get(this.sortFieldParameterName);
+                }
+            }
+        } catch (Exception e) {
+            Debug.logWarning(e, "Error getting sortField: " + e.toString(), module);
+        }
+        return value;
+    }
+
+    public String getSortFieldParameterName() {
+        return this.sortFieldParameterName;
+    }
+
+    public List<SortField> getSortOrderFields() {
+        return sortOrderFields;
+    }
+
+    /**
+     * iterate through alt-row-styles list to see if should be used, then add style
+     * @return The style for item row
+     */
+    public String getStyleAltRowStyle(Map<String, Object> context) {
+        String styles = "";
+        try {
+            // use the same Interpreter (ie with the same context setup) for all evals
+            Interpreter bsh = this.getBshInterpreter(context);
+            for (AltRowStyle altRowStyle : this.altRowStyles) {
+                Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(altRowStyle.useWhen));
+                // retVal should be a Boolean, if not something weird is up...
+                if (retVal instanceof Boolean) {
+                    Boolean boolVal = (Boolean) retVal;
+                    if (boolVal.booleanValue()) {
+                        styles += altRowStyle.style;
+                    }
+                } else {
+                    throw new IllegalArgumentException("Return value from style condition eval was not a Boolean: "
+                            + retVal.getClass().getName() + " [" + retVal + "] of form " + getName());
+                }
+            }
+        } catch (EvalError e) {
+            String errmsg = "Error evaluating BeanShell style conditions on form " + getName();
+            Debug.logError(e, errmsg, module);
+            throw new IllegalArgumentException(errmsg);
+        }
+        return styles;
+    }
+
+    public String getTarget() {
+        return target.getOriginal();
+    }
+
+    /** iterate through altTargets list to see if any should be used, if not return original target
+     * @return The target for this Form
+     */
+    public String getTarget(Map<String, Object> context, String targetType) {
+        Map<String, Object> expanderContext = context;
+        UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+        if (simpleEncoder != null) {
+            expanderContext = UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
+        }
+        try {
+            // use the same Interpreter (ie with the same context setup) for all evals
+            Interpreter bsh = this.getBshInterpreter(context);
+            for (AltTarget altTarget : this.altTargets) {
+                String useWhen = FlexibleStringExpander.expandString(altTarget.useWhen, context);
+                Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhen));
+                boolean condTrue = false;
+                // retVal should be a Boolean, if not something weird is up...
+                if (retVal instanceof Boolean) {
+                    Boolean boolVal = (Boolean) retVal;
+                    condTrue = boolVal.booleanValue();
+                } else {
+                    throw new IllegalArgumentException("Return value from target condition eval was not a Boolean: "
+                            + retVal.getClass().getName() + " [" + retVal + "] of form " + getName());
+                }
+
+                if (condTrue && !targetType.equals("inter-app")) {
+                    return altTarget.targetExdr.expandString(expanderContext);
+                }
+            }
+        } catch (EvalError e) {
+            String errmsg = "Error evaluating BeanShell target conditions on form " + getName();
+            Debug.logError(e, errmsg, module);
+            throw new IllegalArgumentException(errmsg);
+        }
+        return target.expandString(expanderContext);
+    }
+
+    public String getTargetType() {
+        return this.targetType;
+    }
+
+    public String getTargetWindow() {
+        return targetWindowExdr.getOriginal();
+    }
+
+    public String getTargetWindow(Map<String, Object> context) {
+        return this.targetWindowExdr.expandString(context);
+    }
+
+    public String getTitle() {
+        return this.title;
+    }
+
+    public String getTooltip() {
+        return this.tooltip;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public boolean getUseRowSubmit() {
+        return this.useRowSubmit;
+    }
+
+    public Set<String> getUseWhenFields() {
+        return useWhenFields;
+    }
+    public boolean getGroupColumns() {
+        return groupColumns;
+    }
+
+    public boolean isOverridenListSize() {
+        return !this.overrideListSize.isEmpty();
+    }
+
+    public void runFormActions(Map<String, Object> context) {
+        AbstractModelAction.runSubActions(this.actions, context);
+    }
+}

Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java?rev=1654670&r1=1654669&r2=1654670&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java Sun Jan 25 17:18:24 2015
@@ -57,6 +57,8 @@ public interface ModelWidgetVisitor {
 
     void visit(ModelScreenWidget.Form form) throws Exception;
 
+    void visit(ModelScreenWidget.Grid grid) throws Exception;
+
     void visit(ModelScreenWidget.HorizontalSeparator horizontalSeparator) throws Exception;
 
     void visit(ModelScreenWidget.ScreenImage image) throws Exception;

Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetVisitor.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetVisitor.java?rev=1654670&r1=1654669&r2=1654670&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetVisitor.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetVisitor.java Sun Jan 25 17:18:24 2015
@@ -32,6 +32,7 @@ import org.ofbiz.widget.model.ModelScree
 import org.ofbiz.widget.model.ModelScreenWidget.DecoratorSection;
 import org.ofbiz.widget.model.ModelScreenWidget.DecoratorSectionInclude;
 import org.ofbiz.widget.model.ModelScreenWidget.Form;
+import org.ofbiz.widget.model.ModelScreenWidget.Grid;
 import org.ofbiz.widget.model.ModelScreenWidget.HorizontalSeparator;
 import org.ofbiz.widget.model.ModelScreenWidget.IncludeScreen;
 import org.ofbiz.widget.model.ModelScreenWidget.Label;
@@ -344,6 +345,12 @@ public class XmlWidgetVisitor extends Xm
     }
 
     @Override
+    public void visit(Grid grid) throws Exception {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
     public void visit(ModelMenu modelMenu) throws Exception {
         writer.append("<menu");
         visitModelWidget(modelMenu);

Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java?rev=1654670&r1=1654669&r2=1654670&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java Sun Jan 25 17:18:24 2015
@@ -44,7 +44,7 @@ import org.ofbiz.entity.util.EntityListI
 import org.ofbiz.widget.WidgetWorker;
 import org.ofbiz.widget.model.AbstractModelAction;
 import org.ofbiz.widget.model.FieldInfo;
-import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.*;
 import org.ofbiz.widget.model.ModelForm.FieldGroup;
 import org.ofbiz.widget.model.ModelForm.FieldGroupBase;
 import org.ofbiz.widget.model.ModelFormField;
@@ -214,7 +214,7 @@ public class FormRenderer {
     }
 
     /**
-     * Renders this form to a String, i.e. in a text format, as defined with the
+     * Renders this form to a writer, as defined with the
      * FormStringRenderer implementation.
      *
      * @param writer The Writer that the form text will be written to
@@ -227,7 +227,7 @@ public class FormRenderer {
     public void render(Appendable writer, Map<String, Object> context)
             throws Exception {
         //  increment the paginator, only for list and multi forms
-        if ("list".equals(modelForm.getType()) || "multi".equals(modelForm.getType())) {
+        if (modelForm instanceof ModelGrid) {
             WidgetWorker.incrementPaginatorNumber(context);
         }
 
@@ -237,8 +237,8 @@ public class FormRenderer {
 
         modelForm.runFormActions(context);
 
-        // if this is a list form, don't useRequestParameters
-        if ("list".equals(modelForm.getType()) || "multi".equals(modelForm.getType())) {
+        // if this is a list form, don't use Request Parameters
+        if (modelForm instanceof ModelGrid) {
             context.put("useRequestParameters", Boolean.FALSE);
         }
 

Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java?rev=1654670&r1=1654669&r2=1654670&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java Sun Jan 25 17:18:24 2015
@@ -25,7 +25,7 @@ import org.ofbiz.widget.model.ModelForm;
 import org.ofbiz.widget.model.ModelFormField;
 
 /**
- * Widget Library - Form String Renderer interface.
+ * Widget Library - Form/Grid renderer.
  */
 public interface FormStringRenderer {
     public void renderDisplayField(Appendable writer, Map<String, Object> context, ModelFormField.DisplayField displayField) throws IOException;

Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java?rev=1654670&r1=1654669&r2=1654670&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java Sun Jan 25 17:18:24 2015
@@ -81,6 +81,7 @@ import org.ofbiz.widget.model.ModelFormF
 import org.ofbiz.widget.model.ModelFormField.TextareaField;
 import org.ofbiz.widget.model.ModelFormFieldBuilder;
 import org.ofbiz.widget.model.ModelScreenWidget;
+import org.ofbiz.widget.model.ModelSingleForm;
 import org.ofbiz.widget.model.ModelWidget;
 import org.ofbiz.widget.renderer.FormRenderer;
 import org.ofbiz.widget.renderer.FormStringRenderer;
@@ -157,12 +158,6 @@ public final class MacroFormRenderer imp
         return environment;
     }
 
-    private void appendWhitespace(Appendable writer) throws IOException {
-        // appending line ends for now, but this could be replaced with a simple space or something
-        writer.append("\r\n");
-        //writer.append(' ');
-    }
-
     private String encode(String value, ModelFormField modelFormField, Map<String, Object> context) {
         if (UtilValidate.isEmpty(value)) {
             return value;
@@ -1303,7 +1298,11 @@ public final class MacroFormRenderer imp
 
     public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
         this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-        renderBeginningBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+        if (modelForm instanceof ModelSingleForm) {
+            renderBeginningBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+        } else {
+            renderBeginningBoundaryComment(writer, "Grid Widget - Grid Element", modelForm);
+        }
         String targetType = modelForm.getTargetType();
         String targ = modelForm.getTarget(context, targetType);
         StringBuilder linkUrl = new StringBuilder();
@@ -1378,7 +1377,11 @@ public final class MacroFormRenderer imp
         sr.append(hasRequiredField);
         sr.append("\" />");
         executeMacro(writer, sr.toString());
-        renderEndingBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+        if (modelForm instanceof ModelSingleForm) {
+            renderEndingBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+        } else {
+            renderEndingBoundaryComment(writer, "Grid Widget - Grid Element", modelForm);
+        }
     }
 
     public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
@@ -1408,9 +1411,12 @@ public final class MacroFormRenderer imp
         Appendable postMultiFormWriter = wholeFormContext != null ? (Appendable) wholeFormContext.get("postMultiFormWriter") : null;
         if (postMultiFormWriter != null) {
             writer.append(postMultiFormWriter.toString());
-            appendWhitespace(writer);
         }
-        renderEndingBoundaryComment(writer, "Form Widget - Form Element (Multi)", modelForm);
+        if (modelForm instanceof ModelSingleForm) {
+            renderEndingBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+        } else {
+            renderEndingBoundaryComment(writer, "Grid Widget - Grid Element", modelForm);
+        }
     }
 
     public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
@@ -1424,7 +1430,11 @@ public final class MacroFormRenderer imp
         }
         String queryString = UtilHttp.urlEncodeArgs(inputFields);
         context.put("_QBESTRING_", queryString);
-        renderBeginningBoundaryComment(writer, "Form Widget", modelForm);
+        if (modelForm instanceof ModelSingleForm) {
+            renderBeginningBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+        } else {
+            renderBeginningBoundaryComment(writer, "Grid Widget - Grid Element", modelForm);
+        }
         if (this.renderPagination) {
             this.renderNextPrev(writer, context, modelForm);
         }
@@ -1477,7 +1487,11 @@ public final class MacroFormRenderer imp
         if (this.renderPagination) {
             this.renderNextPrev(writer, context, modelForm);
         }
-        renderEndingBoundaryComment(writer, "Form Widget - Formal List Wrapper", modelForm);
+        if (modelForm instanceof ModelSingleForm) {
+            renderEndingBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+        } else {
+            renderEndingBoundaryComment(writer, "Grid Widget - Grid Element", modelForm);
+        }
     }
 
     public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {