You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ofbiz.apache.org by Adrian Crum <ad...@yahoo.com> on 2010/07/02 08:45:10 UTC

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Thanks! That duplication always bothered me.

-Adrian

--- On Thu, 7/1/10, lektran@apache.org <le...@apache.org> wrote:

> From: lektran@apache.org <le...@apache.org>
> Subject: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> To: commits@ofbiz.apache.org
> Date: Thursday, July 1, 2010, 11:38 PM
> Author: lektran
> Date: Fri Jul  2 06:38:52 2010
> New Revision: 959875
> 
> URL: http://svn.apache.org/viewvc?rev=959875&view=rev
> Log:
> Added a new class ModelWidgetAction which will serve to
> replace the duplicate classes ModelScreenAction,
> ModelFormAction and ModelMenuAction.  This class is
> virtually a direct copy of ModelScreenAction and its
> subclasses.  I'll work over the weekend to switch the
> existing classes to extend from ModelWidgetAction, remove
> their methods and then deprecate the shells that are left
> behind.
> 
> Added:
>    
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java   (with
> props)
> 
> Added:
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java?rev=959875&view=auto
> ==============================================================================
> ---
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> (added)
> +++
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> Fri Jul  2 06:38:52 2010
> @@ -0,0 +1,700 @@
> +/*******************************************************************************
> + * 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;
> +
> +import java.io.Serializable;
> +import java.text.MessageFormat;
> +import java.util.ArrayList;
> +import java.util.List;
> +import java.util.Locale;
> +import java.util.Map;
> +import java.util.TimeZone;
> +import java.util.regex.PatternSyntaxException;
> +
> +import javax.servlet.ServletContext;
> +import javax.servlet.http.HttpSession;
> +
> +import javolution.util.FastList;
> +import javolution.util.FastMap;
> +
> +import org.w3c.dom.Element;
> +import org.codehaus.groovy.runtime.InvokerHelper;
> +import org.ofbiz.base.util.BshUtil;
> +import org.ofbiz.base.util.Debug;
> +import org.ofbiz.base.util.GeneralException;
> +import org.ofbiz.base.util.GroovyUtil;
> +import org.ofbiz.base.util.ObjectType;
> +import org.ofbiz.base.util.StringUtil;
> +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.collections.FlexibleMapAccessor;
> +import
> org.ofbiz.base.util.collections.ResourceBundleMapWrapper;
> +import org.ofbiz.base.util.string.FlexibleStringExpander;
> +import org.ofbiz.entity.GenericEntityException;
> +import org.ofbiz.entity.GenericValue;
> +import org.ofbiz.entity.finder.ByAndFinder;
> +import org.ofbiz.entity.finder.ByConditionFinder;
> +import org.ofbiz.entity.finder.EntityFinderUtil;
> +import org.ofbiz.entity.finder.PrimaryKeyFinder;
> +import org.ofbiz.minilang.MiniLangException;
> +import org.ofbiz.minilang.SimpleMethod;
> +import org.ofbiz.minilang.method.MethodContext;
> +import org.ofbiz.service.DispatchContext;
> +import org.ofbiz.service.GenericServiceException;
> +import org.ofbiz.service.ModelService;
> +
> +@SuppressWarnings("serial")
> +public abstract class ModelWidgetAction implements
> Serializable {
> +    public static final String module =
> ModelWidgetAction.class.getName();
> +
> +    protected ModelWidget modelWidget;
> +
> +    protected ModelWidgetAction() {}
> +
> +    public ModelWidgetAction(ModelWidget
> modelWidget, Element actionElement) {
> +        this.modelWidget =
> modelWidget;
> +        if (Debug.verboseOn())
> Debug.logVerbose("Reading widget action with name: " +
> actionElement.getNodeName(), module);
> +    }
> +
> +    public abstract void
> runAction(Map<String, Object> context) throws
> GeneralException;
> +
> +    public static List<ModelWidgetAction>
> readSubActions(ModelWidget modelWidget, Element
> parentElement) {
> +        List<ModelWidgetAction>
> actions = FastList.newInstance();
> +
> +        List<? extends Element>
> actionElementList =
> UtilXml.childElementList(parentElement);
> +        for (Element actionElement:
> actionElementList) {
> +            if
> ("set".equals(actionElement.getNodeName())) {
> +               
> actions.add(new SetField(modelWidget, actionElement));
> +            } else if
> ("property-map".equals(actionElement.getNodeName())) {
> +               
> actions.add(new PropertyMap(modelWidget, actionElement));
> +            } else if
> ("property-to-field".equals(actionElement.getNodeName())) {
> +               
> actions.add(new PropertyToField(modelWidget,
> actionElement));
> +            } else if
> ("script".equals(actionElement.getNodeName())) {
> +               
> actions.add(new Script(modelWidget, actionElement));
> +            } else if
> ("service".equals(actionElement.getNodeName())) {
> +               
> actions.add(new Service(modelWidget, actionElement));
> +            } else if
> ("entity-one".equals(actionElement.getNodeName())) {
> +               
> actions.add(new EntityOne(modelWidget, actionElement));
> +            } else if
> ("entity-and".equals(actionElement.getNodeName())) {
> +               
> actions.add(new EntityAnd(modelWidget, actionElement));
> +            } else if
> ("entity-condition".equals(actionElement.getNodeName())) {
> +               
> actions.add(new EntityCondition(modelWidget,
> actionElement));
> +            } else if
> ("get-related-one".equals(actionElement.getNodeName())) {
> +               
> actions.add(new GetRelatedOne(modelWidget, actionElement));
> +            } else if
> ("get-related".equals(actionElement.getNodeName())) {
> +               
> actions.add(new GetRelated(modelWidget, actionElement));
> +            } else {
> +               
> throw new IllegalArgumentException("Action element not
> supported with name: " + actionElement.getNodeName());
> +            }
> +        }
> +
> +        return actions;
> +    }
> +
> +    public static void
> runSubActions(List<ModelWidgetAction> actions,
> Map<String, Object> context) throws GeneralException
> {
> +        if (actions == null) return;
> +
> +        for (ModelWidgetAction action:
> actions) {
> +            if
> (Debug.verboseOn()) Debug.logVerbose("Running widget action
> " + action.getClass().getName(), module);
> +           
> action.runAction(context);
> +        }
> +    }
> +
> +    public static class SetField extends
> ModelWidgetAction {
> +        protected
> FlexibleMapAccessor<Object> field;
> +        protected
> FlexibleMapAccessor<Object> fromField;
> +        protected
> FlexibleStringExpander valueExdr;
> +        protected
> FlexibleStringExpander defaultExdr;
> +        protected
> FlexibleStringExpander globalExdr;
> +        protected String type;
> +        protected String toScope;
> +        protected String fromScope;
> +
> +        public SetField(ModelWidget
> modelWidget, Element setElement) {
> +            super
> (modelWidget, setElement);
> +            this.field =
> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
> +            this.fromField =
> FlexibleMapAccessor.getInstance(setElement.getAttribute("from-field"));
> +            this.valueExdr =
> FlexibleStringExpander.getInstance(setElement.getAttribute("value"));
> +            this.defaultExdr
> =
> FlexibleStringExpander.getInstance(setElement.getAttribute("default-value"));
> +            this.globalExdr
> =
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> +            this.type =
> setElement.getAttribute("type");
> +            this.toScope =
> setElement.getAttribute("to-scope");
> +            this.fromScope =
> setElement.getAttribute("from-scope");
> +            if
> (!this.fromField.isEmpty() &&
> !this.valueExdr.isEmpty()) {
> +               
> throw new IllegalArgumentException("Cannot specify a
> from-field [" + setElement.getAttribute("from-field") + "]
> and a value [" + setElement.getAttribute("value") + "] on
> the set action in a widget");
> +            }
> +        }
> +
> +        @Override
> +        public void
> runAction(Map<String, Object> context) {
> +            String globalStr
> = this.globalExdr.expandString(context);
> +            // default to
> false
> +            boolean global =
> "true".equals(globalStr);
> +
> +            Object newValue
> = null;
> +            if
> (this.fromScope != null &&
> this.fromScope.equals("user")) {
> +                if
> (!this.fromField.isEmpty()) {
> +               
>     HttpSession session = (HttpSession)
> context.get("session");
> +               
>     newValue =
> getInMemoryPersistedFromField(session, context);
> +               
>     if (Debug.verboseOn()) Debug.logVerbose("In
> user getting value for field from [" +
> this.fromField.getOriginalName() + "]: " + newValue,
> module);
> +                }
> else if (!this.valueExdr.isEmpty()) {
> +               
>     newValue = this.valueExdr.expand(context);
> +                }
> +            } else if
> (this.fromScope != null &&
> this.fromScope.equals("application")) {
> +                if
> (!this.fromField.isEmpty()) {
> +               
>     ServletContext servletContext =
> (ServletContext) context.get("application");
> +               
>     newValue =
> getInMemoryPersistedFromField(servletContext, context);
> +               
>     if (Debug.verboseOn()) Debug.logVerbose("In
> application getting value for field from [" +
> this.fromField.getOriginalName() + "]: " + newValue,
> module);
> +                }
> else if (!this.valueExdr.isEmpty()) {
> +               
>     newValue =
> this.valueExdr.expandString(context);
> +                }
> +            } else {
> +                if
> (!this.fromField.isEmpty()) {
> +               
>     newValue = this.fromField.get(context);
> +               
>     if (Debug.verboseOn())
> Debug.logVerbose("Getting value for field from [" +
> this.fromField.getOriginalName() + "]: " + newValue,
> module);
> +                }
> else if (!this.valueExdr.isEmpty()) {
> +               
>     newValue = this.valueExdr.expand(context);
> +                }
> +            }
> +
> +            // If newValue
> is still empty, use the default value
> +            if
> (ObjectType.isEmpty(newValue) &&
> !this.defaultExdr.isEmpty()) {
> +               
> newValue = this.defaultExdr.expand(context);
> +            }
> +
> +            if
> (UtilValidate.isNotEmpty(this.type)) {
> +                if
> ("NewMap".equals(this.type)) {
> +               
>     newValue = FastMap.newInstance();
> +                }
> else if ("NewList".equals(this.type)) {
> +               
>     newValue = FastList.newInstance();
> +                }
> else {
> +               
>     try {
> +               
>         newValue =
> ObjectType.simpleTypeConvert(newValue, this.type, null,
> (TimeZone) context.get("timeZone"), (Locale)
> context.get("locale"), true);
> +               
>     } catch (GeneralException e) {
> +               
>         String errMsg = "Could not
> convert field value for the field: [" +
> this.field.getOriginalName() + "] to the [" + this.type + "]
> type for the value [" + newValue + "]: " + e.toString();
> +               
>         Debug.logError(e, errMsg,
> module);
> +               
>         throw new
> IllegalArgumentException(errMsg);
> +               
>     }
> +                }
> +            }
> +
> +            if (this.toScope
> != null && this.toScope.equals("user")) {
> +               
> String originalName = this.field.getOriginalName();
> +               
> List<String> currentWidgetTrail =
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> +               
> String newKey = "";
> +                if
> (currentWidgetTrail != null) {
> +               
>     newKey = StringUtil.join(currentWidgetTrail,
> "|");
> +                }
> +                if
> (UtilValidate.isNotEmpty(newKey)) {
> +               
>     newKey += "|";
> +                }
> +               
> newKey += originalName;
> +               
> HttpSession session = (HttpSession)context.get("session");
> +               
> session.setAttribute(newKey, newValue);
> +                if
> (Debug.verboseOn()) Debug.logVerbose("In user setting value
> for field from [" + this.field.getOriginalName() + "]: " +
> newValue, module);
> +            } else if
> (this.toScope != null &&
> this.toScope.equals("application")) {
> +               
> String originalName = this.field.getOriginalName();
> +               
> List<String> currentWidgetTrail =
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> +               
> String newKey = "";
> +                if
> (currentWidgetTrail != null) {
> +               
>     newKey = StringUtil.join(currentWidgetTrail,
> "|");
> +                }
> +                if
> (UtilValidate.isNotEmpty(newKey)) {
> +               
>     newKey += "|";
> +                }
> +               
> newKey += originalName;
> +               
> ServletContext servletContext =
> (ServletContext)context.get("application");
> +               
> servletContext.setAttribute(newKey, newValue);
> +                if
> (Debug.verboseOn()) Debug.logVerbose("In application setting
> value for field from [" + this.field.getOriginalName() + "]:
> " + newValue, module);
> +            } else {
> +                //
> only do this if it is not global, if global ONLY put it in
> the global context
> +                if
> (!global) {
> +               
>     if (Debug.verboseOn())
> Debug.logVerbose("Setting field [" +
> this.field.getOriginalName() + "] to value: " + newValue,
> module);
> +               
>     this.field.put(context, newValue);
> +                }
> +            }
> +
> +            if (global) {
> +               
> Map<String, Object> globalCtx =
> UtilGenerics.checkMap(context.get("globalContext"));
> +                if
> (globalCtx != null) {
> +               
>     this.field.put(globalCtx, newValue);
> +                }
> else {
> +               
>     this.field.put(context, newValue);
> +                }
> +            }
> +
> +            // this is a
> hack for backward compatibility with the JPublish page
> object
> +            Map<String,
> Object> page =
> UtilGenerics.checkMap(context.get("page"));
> +            if (page !=
> null) {
> +               
> this.field.put(page, newValue);
> +            }
> +        }
> +
> +        public Object
> getInMemoryPersistedFromField(Object storeAgent,
> Map<String, Object> context) {
> +            Object newValue
> = null;
> +            String
> originalName = this.fromField.getOriginalName();
> +           
> List<String> currentWidgetTrail =
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> +           
> List<String> trailList = new
> ArrayList<String>();
> +            if
> (currentWidgetTrail != null) {
> +               
> trailList.addAll(currentWidgetTrail);
> +            }
> +
> +            for (int
> i=trailList.size(); i >= 0; i--) {
> +               
> List<String> subTrail = trailList.subList(0,i);
> +               
> String newKey = null;
> +                if
> (subTrail.size() > 0)
> +               
>     newKey = StringUtil.join(subTrail, "|") + "|"
> + originalName;
> +               
> else
> +               
>     newKey = originalName;
> +
> +                if
> (storeAgent instanceof ServletContext) {
> +               
>     newValue =
> ((ServletContext)storeAgent).getAttribute(newKey);
> +                }
> else if (storeAgent instanceof HttpSession) {
> +               
>     newValue =
> ((HttpSession)storeAgent).getAttribute(newKey);
> +                }
> +                if
> (newValue != null) {
> +               
>     break;
> +                }
> +            }
> +            return
> newValue;
> +        }
> +    }
> +
> +    public static class PropertyMap extends
> ModelWidgetAction {
> +        protected
> FlexibleStringExpander resourceExdr;
> +        protected
> FlexibleMapAccessor<ResourceBundleMapWrapper>
> mapNameAcsr;
> +        protected
> FlexibleStringExpander globalExdr;
> +
> +        public PropertyMap(ModelWidget
> modelWidget, Element setElement) {
> +            super
> (modelWidget, setElement);
> +           
> this.resourceExdr =
> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
> +            this.mapNameAcsr
> =
> FlexibleMapAccessor.getInstance(setElement.getAttribute("map-name"));
> +            this.globalExdr
> =
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> +        }
> +
> +        @Override
> +        public void
> runAction(Map<String, Object> context) {
> +            String globalStr
> = this.globalExdr.expandString(context);
> +            // default to
> false
> +            boolean global =
> "true".equals(globalStr);
> +
> +            Locale locale =
> (Locale) context.get("locale");
> +            String resource
> = this.resourceExdr.expandString(context, locale);
> +
> +           
> ResourceBundleMapWrapper existingPropMap =
> this.mapNameAcsr.get(context);
> +            if
> (existingPropMap == null) {
> +               
> this.mapNameAcsr.put(context,
> UtilProperties.getResourceBundleMap(resource, locale,
> context));
> +            } else {
> +               
> try {
> +               
>    
> existingPropMap.addBottomResourceBundle(resource);
> +                }
> catch (IllegalArgumentException e) {
> +               
>     // log the error, but don't let it kill
> everything just for a typo or bad char in an l10n file
> +               
>     Debug.logError(e, "Error adding resource
> bundle [" + resource + "]: " + e.toString(), module);
> +                }
> +            }
> +
> +            if (global) {
> +               
> Map<String, Object> globalCtx =
> UtilGenerics.checkMap(context.get("globalContext"));
> +                if
> (globalCtx != null) {
> +               
>     ResourceBundleMapWrapper globalExistingPropMap
> = this.mapNameAcsr.get(globalCtx);
> +               
>     if (globalExistingPropMap == null) {
> +               
>         this.mapNameAcsr.put(globalCtx,
> UtilProperties.getResourceBundleMap(resource, locale,
> context));
> +               
>     } else {
> +               
>         // is it the same object? if not
> add it in here too...
> +               
>         if (existingPropMap !=
> globalExistingPropMap) {
> +               
>             try {
> +               
>                
> globalExistingPropMap.addBottomResourceBundle(resource);
> +               
>             } catch
> (IllegalArgumentException e) {
> +               
>                 //
> log the error, but don't let it kill everything just for a
> typo or bad char in an l10n file
> +               
>                
> Debug.logError(e, "Error adding resource bundle [" +
> resource + "]: " + e.toString(), module);
> +               
>             }
> +               
>         }
> +               
>     }
> +                }
> +            }
> +        }
> +    }
> +
> +    public static class PropertyToField extends
> ModelWidgetAction {
> +
> +        protected
> FlexibleStringExpander resourceExdr;
> +        protected
> FlexibleStringExpander propertyExdr;
> +        protected
> FlexibleMapAccessor<Object> fieldAcsr;
> +        protected
> FlexibleStringExpander defaultExdr;
> +        protected boolean noLocale;
> +        protected
> FlexibleMapAccessor<List<? extends Object>>
> argListAcsr;
> +        protected
> FlexibleStringExpander globalExdr;
> +
> +        public
> PropertyToField(ModelWidget modelWidget, Element setElement)
> {
> +            super
> (modelWidget, setElement);
> +           
> this.resourceExdr =
> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
> +           
> this.propertyExdr =
> FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
> +            this.fieldAcsr =
> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
> +            this.defaultExdr
> =
> FlexibleStringExpander.getInstance(setElement.getAttribute("default"));
> +            this.noLocale =
> "true".equals(setElement.getAttribute("no-locale"));
> +            this.argListAcsr
> =
> FlexibleMapAccessor.getInstance(setElement.getAttribute("arg-list-name"));
> +            this.globalExdr
> =
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> +        }
> +
> +        @Override
> +        public void
> runAction(Map<String, Object> context) {
> +            //String
> globalStr = this.globalExdr.expandString(context);
> +            // default to
> false
> +            //boolean global
> = "true".equals(globalStr);
> +
> +            Locale locale =
> (Locale) context.get("locale");
> +            String resource
> = this.resourceExdr.expandString(context, locale);
> +            String property
> = this.propertyExdr.expandString(context, locale);
> +
> +            String value =
> null;
> +            if (noLocale) {
> +               
> value = UtilProperties.getPropertyValue(resource,
> property);
> +            } else {
> +               
> value = UtilProperties.getMessage(resource, property,
> locale);
> +            }
> +            if
> (UtilValidate.isEmpty(value)) {
> +               
> value = this.defaultExdr.expandString(context);
> +            }
> +
> +            // note that
> expanding the value string here will handle defaultValue and
> the string from
> +            //  the
> properties file; if we decide later that we don't want the
> string from the properties
> +            //  file to
> be expanded we should just expand the defaultValue at the
> beginning of this method.
> +            value =
> FlexibleStringExpander.expandString(value, context);
> +
> +            if
> (!argListAcsr.isEmpty()) {
> +               
> List<? extends Object> argList =
> argListAcsr.get(context);
> +                if
> (UtilValidate.isNotEmpty(argList)) {
> +               
>     value = MessageFormat.format(value,
> argList.toArray());
> +                }
> +            }
> +           
> fieldAcsr.put(context, value);
> +        }
> +    }
> +
> +    public static class Script extends
> ModelWidgetAction {
> +        protected static final
> Object[] EMPTY_ARGS = {};
> +        protected String location;
> +        protected String method;
> +
> +        public Script(ModelWidget
> modelWidget, Element scriptElement) {
> +            super
> (modelWidget, scriptElement);
> +            String
> scriptLocation = scriptElement.getAttribute("location");
> +            this.location =
> WidgetWorker.getScriptLocation(scriptLocation);
> +            this.method =
> WidgetWorker.getScriptMethodName(scriptLocation);
> +        }
> +
> +        @Override
> +        public void
> runAction(Map<String, Object> context) throws
> GeneralException {
> +            if
> (location.endsWith(".bsh")) {
> +               
> try {
> +               
>     BshUtil.runBshAtLocation(location, context);
> +                }
> catch (GeneralException e) {
> +               
>     throw new GeneralException("Error running BSH
> script at location [" + location + "]", e);
> +                }
> +            } else if
> (location.endsWith(".groovy")) {
> +               
> try {
> +               
>     groovy.lang.Script script =
> InvokerHelper.createScript(GroovyUtil.getScriptClassFromLocation(location),
> GroovyUtil.getBinding(context));
> +               
>     if (UtilValidate.isEmpty(method)) {
> +               
>         script.run();
> +               
>     } else {
> +               
>         script.invokeMethod(method,
> EMPTY_ARGS);
> +               
>     }
> +                }
> catch (GeneralException e) {
> +               
>     throw new GeneralException("Error running
> Groovy script at location [" + location + "]", e);
> +                }
> +            } else if
> (location.endsWith(".xml")) {
> +               
> Map<String, Object> localContext =
> FastMap.newInstance();
> +               
> localContext.putAll(context);
> +               
> DispatchContext ctx =
> WidgetWorker.getDispatcher(context).getDispatchContext();
> +               
> MethodContext methodContext = new MethodContext(ctx,
> localContext, null);
> +               
> try {
> +               
>     SimpleMethod.runSimpleMethod(location, method,
> methodContext);
> +               
>     context.putAll(methodContext.getResults());
> +                }
> catch (MiniLangException e) {
> +               
>     throw new GeneralException("Error running
> simple method at location [" + location + "]", e);
> +                }
> +            } else {
> +               
> throw new GeneralException("For widget script actions the
> script type is not yet supported for location: [" + location
> + "]");
> +            }
> +        }
> +    }
> +
> +    public static class Service extends
> ModelWidgetAction {
> +        protected
> FlexibleStringExpander serviceNameExdr;
> +        protected
> FlexibleMapAccessor<Map<String, Object>>
> resultMapNameAcsr;
> +        protected
> FlexibleStringExpander autoFieldMapExdr;
> +        protected
> Map<FlexibleMapAccessor<Object>, Object>
> fieldMap;
> +
> +        public Service(ModelWidget
> modelWidget, Element serviceElement) {
> +            super
> (modelWidget, serviceElement);
> +           
> this.serviceNameExdr =
> FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
> +           
> this.resultMapNameAcsr =
> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
> +            if
> (this.resultMapNameAcsr.isEmpty()) this.resultMapNameAcsr =
> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
> +           
> this.autoFieldMapExdr =
> FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
> +            this.fieldMap =
> EntityFinderUtil.makeFieldMap(serviceElement);
> +        }
> +
> +        @Override
> +        public void
> runAction(Map<String, Object> context) {
> +            String
> serviceNameExpanded =
> this.serviceNameExdr.expandString(context);
> +            if
> (UtilValidate.isEmpty(serviceNameExpanded)) {
> +               
> throw new IllegalArgumentException("Service name was empty,
> expanded from: " + this.serviceNameExdr.getOriginal());
> +            }
> +
> +            String
> autoFieldMapString =
> this.autoFieldMapExdr.expandString(context);
> +
> +            try {
> +               
> Map<String, Object> serviceContext = null;
> +                if
> ("true".equals(autoFieldMapString)) {
> +               
>     DispatchContext dc =
> WidgetWorker.getDispatcher(context).getDispatchContext();
> +               
>     // try a map called "parameters", try it first
> so values from here are overriden by values in the main
> context
> +               
>     Map<String, Object> combinedMap =
> FastMap.newInstance();
> +               
>     Map<String, Object> parametersObj =
> UtilGenerics.toMap(context.get("parameters"));
> +               
>     if (parametersObj != null) {
> +               
>        
> combinedMap.putAll(parametersObj);
> +               
>     }
> +               
>     combinedMap.putAll(context);
> +               
>     serviceContext =
> dc.makeValidContext(serviceNameExpanded,
> ModelService.IN_PARAM, combinedMap);
> +                }
> else if (UtilValidate.isNotEmpty(autoFieldMapString)
> && !"false".equals(autoFieldMapString)) {
> +               
>     FlexibleMapAccessor<Object> fieldFma =
> FlexibleMapAccessor.getInstance(autoFieldMapString);
> +               
>     Map<String, Object> autoFieldMap =
> UtilGenerics.toMap(fieldFma.get(context));
> +               
>     if (autoFieldMap != null) {
> +               
>         serviceContext =
> WidgetWorker.getDispatcher(context).getDispatchContext().makeValidContext(serviceNameExpanded,
> ModelService.IN_PARAM, autoFieldMap);
> +               
>     }
> +                }
> +                if
> (serviceContext == null) {
> +               
>     serviceContext = FastMap.newInstance();
> +                }
> +
> +                if
> (this.fieldMap != null) {
> +               
>    
> EntityFinderUtil.expandFieldMapToContext(this.fieldMap,
> context, serviceContext);
> +                }
> +
> +               
> Map<String, Object> result =
> WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded,
> serviceContext);
> +
> +                if
> (!this.resultMapNameAcsr.isEmpty()) {
> +               
>     this.resultMapNameAcsr.put(context, result);
> +               
>     String queryString =
> (String)result.get("queryString");
> +               
>     context.put("queryString", queryString);
> +               
>     context.put("queryStringMap",
> result.get("queryStringMap"));
> +               
>     if (UtilValidate.isNotEmpty(queryString)) {
> +               
>         try {
> +               
>             String
> queryStringEncoded = queryString.replaceAll("&",
> "%26");
> +               
>            
> context.put("queryStringEncoded", queryStringEncoded);
> +               
>         } catch (PatternSyntaxException
> e) {
> +
> +               
>         }
> +               
>     }
> +                }
> else {
> +               
>     context.putAll(result);
> +                }
> +            } catch
> (GenericServiceException e) {
> +               
> String errMsg = "Error calling service with name " +
> serviceNameExpanded + ": " + e.toString();
> +               
> Debug.logError(e, errMsg, module);
> +               
> throw new IllegalArgumentException(errMsg);
> +            }
> +        }
> +
> +        public FlexibleStringExpander
> getServiceNameExdr() {
> +            return
> this.serviceNameExdr;
> +        }
> +    }
> +
> +    public static class EntityOne extends
> ModelWidgetAction {
> +        protected PrimaryKeyFinder
> finder;
> +
> +        public EntityOne(ModelWidget
> modelWidget, Element entityOneElement) {
> +            super
> (modelWidget, entityOneElement);
> +            finder = new
> PrimaryKeyFinder(entityOneElement);
> +        }
> +
> +        @Override
> +        public void
> runAction(Map<String, Object> context) {
> +            try {
> +               
> finder.runFind(context,
> WidgetWorker.getDelegator(context));
> +            } catch
> (GeneralException e) {
> +               
> String errMsg = "Error doing entity query by condition: " +
> e.toString();
> +               
> Debug.logError(e, errMsg, module);
> +               
> throw new IllegalArgumentException(errMsg);
> +            }
> +        }
> +
> +        public PrimaryKeyFinder
> getFinder() {
> +            return
> this.finder;
> +        }
> +    }
> +
> +    public static class EntityAnd extends
> ModelWidgetAction {
> +        protected ByAndFinder finder;
> +
> +        public EntityAnd(ModelWidget
> modelWidget, Element entityAndElement) {
> +            super
> (modelWidget, entityAndElement);
> +            finder = new
> ByAndFinder(entityAndElement);
> +        }
> +
> +        @Override
> +        public void
> runAction(Map<String, Object> context) {
> +            try {
> +               
> finder.runFind(context,
> WidgetWorker.getDelegator(context));
> +            } catch
> (GeneralException e) {
> +               
> String errMsg = "Error doing entity query by condition: " +
> e.toString();
> +               
> Debug.logError(e, errMsg, module);
> +               
> throw new IllegalArgumentException(errMsg);
> +            }
> +        }
> +
> +        public ByAndFinder getFinder()
> {
> +            return
> this.finder;
> +        }
> +    }
> +
> +    public static class EntityCondition extends
> ModelWidgetAction {
> +        ByConditionFinder finder;
> +
> +        public
> EntityCondition(ModelWidget modelWidget, Element
> entityConditionElement) {
> +            super
> (modelWidget, entityConditionElement);
> +            finder = new
> ByConditionFinder(entityConditionElement);
> +        }
> +
> +        @Override
> +        public void
> runAction(Map<String, Object> context) {
> +            try {
> +               
> finder.runFind(context,
> WidgetWorker.getDelegator(context));
> +            } catch
> (GeneralException e) {
> +               
> String errMsg = "Error doing entity query by condition: " +
> e.toString();
> +               
> Debug.logError(e, errMsg, module);
> +               
> throw new IllegalArgumentException(errMsg);
> +            }
> +        }
> +
> +        public ByConditionFinder
> getFinder() {
> +            return
> this.finder;
> +        }
> +    }
> +
> +    public static class GetRelatedOne extends
> ModelWidgetAction {
> +        protected
> FlexibleMapAccessor<Object> valueNameAcsr;
> +        protected
> FlexibleMapAccessor<Object> toValueNameAcsr;
> +        protected String
> relationName;
> +        protected boolean useCache;
> +
> +        public
> GetRelatedOne(ModelWidget modelWidget, Element
> getRelatedOneElement) {
> +            super
> (modelWidget, getRelatedOneElement);
> +           
> this.valueNameAcsr =
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
> +            if
> (this.valueNameAcsr.isEmpty()) this.valueNameAcsr =
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-name"));
> +           
> this.toValueNameAcsr =
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
> +            if
> (this.toValueNameAcsr.isEmpty()) this.toValueNameAcsr =
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-name"));
> +           
> this.relationName =
> getRelatedOneElement.getAttribute("relation-name");
> +            this.useCache =
> "true".equals(getRelatedOneElement.getAttribute("use-cache"));
> +        }
> +
> +        @Override
> +        public void
> runAction(Map<String, Object> context) {
> +            Object
> valueObject = valueNameAcsr.get(context);
> +            if (valueObject
> == null) {
> +               
> Debug.logVerbose("Value not found with name: " +
> valueNameAcsr + ", not getting related...", module);
> +               
> return;
> +            }
> +            if
> (!(valueObject instanceof GenericValue)) {
> +               
> String errMsg = "Env variable for value-name " +
> valueNameAcsr.toString() + " is not a GenericValue object;
> for the relation-name: " + relationName + "]";
> +               
> Debug.logError(errMsg, module);
> +               
> throw new IllegalArgumentException(errMsg);
> +            }
> +            GenericValue
> value = (GenericValue) valueObject;
> +            try {
> +                if
> (useCache) {
> +               
>     toValueNameAcsr.put(context,
> value.getRelatedOneCache(relationName));
> +                }
> else {
> +               
>     toValueNameAcsr.put(context,
> value.getRelatedOne(relationName));
> +                }
> +            } catch
> (GenericEntityException e) {
> +               
> String errMsg = "Problem getting related one from entity
> with name " + value.getEntityName() + " for the
> relation-name: " + relationName + ": " + e.getMessage();
> +               
> Debug.logError(e, errMsg, module);
> +               
> throw new IllegalArgumentException(errMsg);
> +            }
> +        }
> +
> +        public String
> getRelationName() {
> +            return
> this.relationName;
> +        }
> +    }
> +
> +    public static class GetRelated extends
> ModelWidgetAction {
> +        protected
> FlexibleMapAccessor<Object> valueNameAcsr;
> +        protected
> FlexibleMapAccessor<List<GenericValue>>
> listNameAcsr;
> +        protected
> FlexibleMapAccessor<Map<String, Object>>
> mapAcsr;
> +        protected
> FlexibleMapAccessor<List<String>>
> orderByListAcsr;
> +        protected String
> relationName;
> +        protected boolean useCache;
> +
> +        public GetRelated(ModelWidget
> modelWidget, Element getRelatedElement) {
> +            super
> (modelWidget, getRelatedElement);
> +           
> this.valueNameAcsr =
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
> +            if
> (this.valueNameAcsr.isEmpty()) this.valueNameAcsr =
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-name"));
> +           
> this.listNameAcsr =
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
> +            if
> (this.listNameAcsr.isEmpty()) this.listNameAcsr =
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list-name"));
> +           
> this.relationName =
> getRelatedElement.getAttribute("relation-name");
> +            this.mapAcsr =
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
> +            if
> (this.mapAcsr.isEmpty()) this.mapAcsr =
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map-name"));
> +           
> this.orderByListAcsr =
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
> +            if
> (this.orderByListAcsr.isEmpty()) this.orderByListAcsr =
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list-name"));
> +            this.useCache =
> "true".equals(getRelatedElement.getAttribute("use-cache"));
> +        }
> +
> +        @Override
> +        public void
> runAction(Map<String, Object> context) {
> +            Object
> valueObject = valueNameAcsr.get(context);
> +            if (valueObject
> == null) {
> +               
> Debug.logVerbose("Value not found with name: " +
> valueNameAcsr + ", not getting related...", module);
> +               
> return;
> +            }
> +            if
> (!(valueObject instanceof GenericValue)) {
> +               
> String errMsg = "Env variable for value-name " +
> valueNameAcsr.toString() + " is not a GenericValue object;
> for the relation-name: " + relationName + "]";
> +               
> Debug.logError(errMsg, module);
> +               
> throw new IllegalArgumentException(errMsg);
> +            }
> +            GenericValue
> value = (GenericValue) valueObject;
> +           
> List<String> orderByNames = null;
> +            if
> (!orderByListAcsr.isEmpty()) {
> +               
> orderByNames = orderByListAcsr.get(context);
> +            }
> +            Map<String,
> Object> constraintMap = null;
> +            if
> (!mapAcsr.isEmpty()) {
> +               
> constraintMap = mapAcsr.get(context);
> +            }
> +            try {
> +                if
> (useCache) {
> +               
>     listNameAcsr.put(context,
> value.getRelatedCache(relationName, constraintMap,
> orderByNames));
> +                }
> else {
> +               
>     listNameAcsr.put(context,
> value.getRelated(relationName, constraintMap,
> orderByNames));
> +                }
> +            } catch
> (GenericEntityException e) {
> +               
> String errMsg = "Problem getting related from entity with
> name " + value.getEntityName() + " for the relation-name: "
> + relationName + ": " + e.getMessage();
> +               
> Debug.logError(e, errMsg, module);
> +               
> throw new IllegalArgumentException(errMsg);
> +            }
> +        }
> +
> +        public String
> getRelationName() {
> +            return
> this.relationName;
> +        }
> +    }
> +}
> 
> Propchange:
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange:
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> ------------------------------------------------------------------------------
>     svn:keywords = "Date Rev Author URL Id"
> 
> Propchange:
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> ------------------------------------------------------------------------------
>     svn:mime-type = text/plain
> 
> 
> 


      

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Scott Gray <sc...@hotwaxmedia.com>.
I'm sure I'll get regret my decision shortly, but in the meantime I'll feel good about doing the right thing.

Regards
Scott

On 2/07/2010, at 7:18 PM, Adrian Crum wrote:

> My new mantra: Just say no to copy and paste.
> 
> I'm questioning nearly all of the code I come across.
> 
> -Adrian
> 
> 
> --- On Thu, 7/1/10, Scott Gray <sc...@hotwaxmedia.com> wrote:
> 
>> From: Scott Gray <sc...@hotwaxmedia.com>
>> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> To: dev@ofbiz.apache.org
>> Date: Thursday, July 1, 2010, 11:58 PM
>> Yeah no worries.  I'd never
>> really thought about it before until yesterday when I came
>> across a problem in the ModelMenuAction.PropertyMap action,
>> it replaces the existing uiLabelMap instead of adding to it
>> like the ModelScreenAction version does.  Option was to
>> either just copy and paste the screen version or take the
>> plunge and sort it all out.
>> 
>> Regards
>> Scott
>> 
>> On 2/07/2010, at 6:45 PM, Adrian Crum wrote:
>> 
>>> Thanks! That duplication always bothered me.
>>> 
>>> -Adrian
>>> 
>>> --- On Thu, 7/1/10, lektran@apache.org
>> <le...@apache.org>
>> wrote:
>>> 
>>>> From: lektran@apache.org
>> <le...@apache.org>
>>>> Subject: svn commit: r959875 -
>> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> To: commits@ofbiz.apache.org
>>>> Date: Thursday, July 1, 2010, 11:38 PM
>>>> Author: lektran
>>>> Date: Fri Jul  2 06:38:52 2010
>>>> New Revision: 959875
>>>> 
>>>> URL: http://svn.apache.org/viewvc?rev=959875&view=rev
>>>> Log:
>>>> Added a new class ModelWidgetAction which will
>> serve to
>>>> replace the duplicate classes ModelScreenAction,
>>>> ModelFormAction and ModelMenuAction.  This
>> class is
>>>> virtually a direct copy of ModelScreenAction and
>> its
>>>> subclasses.  I'll work over the weekend to
>> switch the
>>>> existing classes to extend from ModelWidgetAction,
>> remove
>>>> their methods and then deprecate the shells that
>> are left
>>>> behind.
>>>> 
>>>> Added:
>>>>     
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java   (with
>>>> props)
>>>> 
>>>> Added:
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java?rev=959875&view=auto
>>>> 
>> ==============================================================================
>>>> ---
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> (added)
>>>> +++
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> Fri Jul  2 06:38:52 2010
>>>> @@ -0,0 +1,700 @@
>>>> 
>> +/*******************************************************************************
>>>> + * 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;
>>>> +
>>>> +import java.io.Serializable;
>>>> +import java.text.MessageFormat;
>>>> +import java.util.ArrayList;
>>>> +import java.util.List;
>>>> +import java.util.Locale;
>>>> +import java.util.Map;
>>>> +import java.util.TimeZone;
>>>> +import java.util.regex.PatternSyntaxException;
>>>> +
>>>> +import javax.servlet.ServletContext;
>>>> +import javax.servlet.http.HttpSession;
>>>> +
>>>> +import javolution.util.FastList;
>>>> +import javolution.util.FastMap;
>>>> +
>>>> +import org.w3c.dom.Element;
>>>> +import
>> org.codehaus.groovy.runtime.InvokerHelper;
>>>> +import org.ofbiz.base.util.BshUtil;
>>>> +import org.ofbiz.base.util.Debug;
>>>> +import org.ofbiz.base.util.GeneralException;
>>>> +import org.ofbiz.base.util.GroovyUtil;
>>>> +import org.ofbiz.base.util.ObjectType;
>>>> +import org.ofbiz.base.util.StringUtil;
>>>> +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.collections.FlexibleMapAccessor;
>>>> +import
>>>> 
>> org.ofbiz.base.util.collections.ResourceBundleMapWrapper;
>>>> +import
>> org.ofbiz.base.util.string.FlexibleStringExpander;
>>>> +import org.ofbiz.entity.GenericEntityException;
>>>> +import org.ofbiz.entity.GenericValue;
>>>> +import org.ofbiz.entity.finder.ByAndFinder;
>>>> +import
>> org.ofbiz.entity.finder.ByConditionFinder;
>>>> +import org.ofbiz.entity.finder.EntityFinderUtil;
>>>> +import org.ofbiz.entity.finder.PrimaryKeyFinder;
>>>> +import org.ofbiz.minilang.MiniLangException;
>>>> +import org.ofbiz.minilang.SimpleMethod;
>>>> +import org.ofbiz.minilang.method.MethodContext;
>>>> +import org.ofbiz.service.DispatchContext;
>>>> +import
>> org.ofbiz.service.GenericServiceException;
>>>> +import org.ofbiz.service.ModelService;
>>>> +
>>>> +@SuppressWarnings("serial")
>>>> +public abstract class ModelWidgetAction
>> implements
>>>> Serializable {
>>>> +    public static final String module
>> =
>>>> ModelWidgetAction.class.getName();
>>>> +
>>>> +    protected ModelWidget modelWidget;
>>>> +
>>>> +    protected ModelWidgetAction() {}
>>>> +
>>>> +    public
>> ModelWidgetAction(ModelWidget
>>>> modelWidget, Element actionElement) {
>>>> +        this.modelWidget =
>>>> modelWidget;
>>>> +        if
>> (Debug.verboseOn())
>>>> Debug.logVerbose("Reading widget action with name:
>> " +
>>>> actionElement.getNodeName(), module);
>>>> +    }
>>>> +
>>>> +    public abstract void
>>>> runAction(Map<String, Object> context)
>> throws
>>>> GeneralException;
>>>> +
>>>> +    public static
>> List<ModelWidgetAction>
>>>> readSubActions(ModelWidget modelWidget, Element
>>>> parentElement) {
>>>> +       
>> List<ModelWidgetAction>
>>>> actions = FastList.newInstance();
>>>> +
>>>> +        List<? extends
>> Element>
>>>> actionElementList =
>>>> UtilXml.childElementList(parentElement);
>>>> +        for (Element
>> actionElement:
>>>> actionElementList) {
>>>> +            if
>>>> ("set".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new SetField(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> 
>> ("property-map".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new PropertyMap(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> 
>> ("property-to-field".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new PropertyToField(modelWidget,
>>>> actionElement));
>>>> +            } else
>> if
>>>> ("script".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new Script(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> ("service".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new Service(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> ("entity-one".equals(actionElement.getNodeName()))
>> {
>>>> +           
>>    
>>>> actions.add(new EntityOne(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> ("entity-and".equals(actionElement.getNodeName()))
>> {
>>>> +           
>>    
>>>> actions.add(new EntityAnd(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> 
>> ("entity-condition".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new EntityCondition(modelWidget,
>>>> actionElement));
>>>> +            } else
>> if
>>>> 
>> ("get-related-one".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new GetRelatedOne(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> 
>> ("get-related".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new GetRelated(modelWidget,
>> actionElement));
>>>> +            } else
>> {
>>>> +           
>>    
>>>> throw new IllegalArgumentException("Action element
>> not
>>>> supported with name: " +
>> actionElement.getNodeName());
>>>> +            }
>>>> +        }
>>>> +
>>>> +        return actions;
>>>> +    }
>>>> +
>>>> +    public static void
>>>> runSubActions(List<ModelWidgetAction>
>> actions,
>>>> Map<String, Object> context) throws
>> GeneralException
>>>> {
>>>> +        if (actions == null)
>> return;
>>>> +
>>>> +        for
>> (ModelWidgetAction action:
>>>> actions) {
>>>> +            if
>>>> (Debug.verboseOn()) Debug.logVerbose("Running
>> widget action
>>>> " + action.getClass().getName(), module);
>>>> +           
>>>> action.runAction(context);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class SetField
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>>>> FlexibleMapAccessor<Object> field;
>>>> +        protected
>>>> FlexibleMapAccessor<Object> fromField;
>>>> +        protected
>>>> FlexibleStringExpander valueExdr;
>>>> +        protected
>>>> FlexibleStringExpander defaultExdr;
>>>> +        protected
>>>> FlexibleStringExpander globalExdr;
>>>> +        protected String
>> type;
>>>> +        protected String
>> toScope;
>>>> +        protected String
>> fromScope;
>>>> +
>>>> +        public
>> SetField(ModelWidget
>>>> modelWidget, Element setElement) {
>>>> +            super
>>>> (modelWidget, setElement);
>>>> +           
>> this.field =
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
>>>> +           
>> this.fromField =
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("from-field"));
>>>> +           
>> this.valueExdr =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("value"));
>>>> +           
>> this.defaultExdr
>>>> =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("default-value"));
>>>> +           
>> this.globalExdr
>>>> =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>>>> +           
>> this.type =
>>>> setElement.getAttribute("type");
>>>> +           
>> this.toScope =
>>>> setElement.getAttribute("to-scope");
>>>> +           
>> this.fromScope =
>>>> setElement.getAttribute("from-scope");
>>>> +            if
>>>> (!this.fromField.isEmpty() &&
>>>> !this.valueExdr.isEmpty()) {
>>>> +           
>>    
>>>> throw new IllegalArgumentException("Cannot specify
>> a
>>>> from-field [" +
>> setElement.getAttribute("from-field") + "]
>>>> and a value [" + setElement.getAttribute("value")
>> + "] on
>>>> the set action in a widget");
>>>> +            }
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            String
>> globalStr
>>>> = this.globalExdr.expandString(context);
>>>> +            //
>> default to
>>>> false
>>>> +            boolean
>> global =
>>>> "true".equals(globalStr);
>>>> +
>>>> +            Object
>> newValue
>>>> = null;
>>>> +            if
>>>> (this.fromScope != null &&
>>>> this.fromScope.equals("user")) {
>>>> +             
>>   if
>>>> (!this.fromField.isEmpty()) {
>>>> +           
>>    
>>>>      HttpSession session =
>> (HttpSession)
>>>> context.get("session");
>>>> +           
>>    
>>>>      newValue =
>>>> getInMemoryPersistedFromField(session, context);
>>>> +           
>>    
>>>>      if (Debug.verboseOn())
>> Debug.logVerbose("In
>>>> user getting value for field from [" +
>>>> this.fromField.getOriginalName() + "]: " +
>> newValue,
>>>> module);
>>>> +             
>>   }
>>>> else if (!this.valueExdr.isEmpty()) {
>>>> +           
>>    
>>>>      newValue =
>> this.valueExdr.expand(context);
>>>> +             
>>   }
>>>> +            } else
>> if
>>>> (this.fromScope != null &&
>>>> this.fromScope.equals("application")) {
>>>> +             
>>   if
>>>> (!this.fromField.isEmpty()) {
>>>> +           
>>    
>>>>      ServletContext
>> servletContext =
>>>> (ServletContext) context.get("application");
>>>> +           
>>    
>>>>      newValue =
>>>> getInMemoryPersistedFromField(servletContext,
>> context);
>>>> +           
>>    
>>>>      if (Debug.verboseOn())
>> Debug.logVerbose("In
>>>> application getting value for field from [" +
>>>> this.fromField.getOriginalName() + "]: " +
>> newValue,
>>>> module);
>>>> +             
>>   }
>>>> else if (!this.valueExdr.isEmpty()) {
>>>> +           
>>    
>>>>      newValue =
>>>> this.valueExdr.expandString(context);
>>>> +             
>>   }
>>>> +            } else
>> {
>>>> +             
>>   if
>>>> (!this.fromField.isEmpty()) {
>>>> +           
>>    
>>>>      newValue =
>> this.fromField.get(context);
>>>> +           
>>    
>>>>      if (Debug.verboseOn())
>>>> Debug.logVerbose("Getting value for field from ["
>> +
>>>> this.fromField.getOriginalName() + "]: " +
>> newValue,
>>>> module);
>>>> +             
>>   }
>>>> else if (!this.valueExdr.isEmpty()) {
>>>> +           
>>    
>>>>      newValue =
>> this.valueExdr.expand(context);
>>>> +             
>>   }
>>>> +            }
>>>> +
>>>> +            // If
>> newValue
>>>> is still empty, use the default value
>>>> +            if
>>>> (ObjectType.isEmpty(newValue) &&
>>>> !this.defaultExdr.isEmpty()) {
>>>> +           
>>    
>>>> newValue = this.defaultExdr.expand(context);
>>>> +            }
>>>> +
>>>> +            if
>>>> (UtilValidate.isNotEmpty(this.type)) {
>>>> +             
>>   if
>>>> ("NewMap".equals(this.type)) {
>>>> +           
>>    
>>>>      newValue =
>> FastMap.newInstance();
>>>> +             
>>   }
>>>> else if ("NewList".equals(this.type)) {
>>>> +           
>>    
>>>>      newValue =
>> FastList.newInstance();
>>>> +             
>>   }
>>>> else {
>>>> +           
>>    
>>>>      try {
>>>> +           
>>    
>>>>          newValue =
>>>> ObjectType.simpleTypeConvert(newValue, this.type,
>> null,
>>>> (TimeZone) context.get("timeZone"), (Locale)
>>>> context.get("locale"), true);
>>>> +           
>>    
>>>>      } catch (GeneralException
>> e) {
>>>> +           
>>    
>>>>          String
>> errMsg = "Could not
>>>> convert field value for the field: [" +
>>>> this.field.getOriginalName() + "] to the [" +
>> this.type + "]
>>>> type for the value [" + newValue + "]: " +
>> e.toString();
>>>> +           
>>    
>>>>      
>>    Debug.logError(e, errMsg,
>>>> module);
>>>> +           
>>    
>>>>          throw new
>>>> IllegalArgumentException(errMsg);
>>>> +           
>>    
>>>>      }
>>>> +             
>>   }
>>>> +            }
>>>> +
>>>> +            if
>> (this.toScope
>>>> != null && this.toScope.equals("user")) {
>>>> +           
>>    
>>>> String originalName =
>> this.field.getOriginalName();
>>>> +           
>>    
>>>> List<String> currentWidgetTrail =
>>>> 
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>>>> +           
>>    
>>>> String newKey = "";
>>>> +             
>>   if
>>>> (currentWidgetTrail != null) {
>>>> +           
>>    
>>>>      newKey =
>> StringUtil.join(currentWidgetTrail,
>>>> "|");
>>>> +             
>>   }
>>>> +             
>>   if
>>>> (UtilValidate.isNotEmpty(newKey)) {
>>>> +           
>>    
>>>>      newKey += "|";
>>>> +             
>>   }
>>>> +           
>>    
>>>> newKey += originalName;
>>>> +           
>>    
>>>> HttpSession session =
>> (HttpSession)context.get("session");
>>>> +           
>>    
>>>> session.setAttribute(newKey, newValue);
>>>> +             
>>   if
>>>> (Debug.verboseOn()) Debug.logVerbose("In user
>> setting value
>>>> for field from [" + this.field.getOriginalName() +
>> "]: " +
>>>> newValue, module);
>>>> +            } else
>> if
>>>> (this.toScope != null &&
>>>> this.toScope.equals("application")) {
>>>> +           
>>    
>>>> String originalName =
>> this.field.getOriginalName();
>>>> +           
>>    
>>>> List<String> currentWidgetTrail =
>>>> 
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>>>> +           
>>    
>>>> String newKey = "";
>>>> +             
>>   if
>>>> (currentWidgetTrail != null) {
>>>> +           
>>    
>>>>      newKey =
>> StringUtil.join(currentWidgetTrail,
>>>> "|");
>>>> +             
>>   }
>>>> +             
>>   if
>>>> (UtilValidate.isNotEmpty(newKey)) {
>>>> +           
>>    
>>>>      newKey += "|";
>>>> +             
>>   }
>>>> +           
>>    
>>>> newKey += originalName;
>>>> +           
>>    
>>>> ServletContext servletContext =
>>>> (ServletContext)context.get("application");
>>>> +           
>>    
>>>> servletContext.setAttribute(newKey, newValue);
>>>> +             
>>   if
>>>> (Debug.verboseOn()) Debug.logVerbose("In
>> application setting
>>>> value for field from [" +
>> this.field.getOriginalName() + "]:
>>>> " + newValue, module);
>>>> +            } else
>> {
>>>> +             
>>   //
>>>> only do this if it is not global, if global ONLY
>> put it in
>>>> the global context
>>>> +             
>>   if
>>>> (!global) {
>>>> +           
>>    
>>>>      if (Debug.verboseOn())
>>>> Debug.logVerbose("Setting field [" +
>>>> this.field.getOriginalName() + "] to value: " +
>> newValue,
>>>> module);
>>>> +           
>>    
>>>>      this.field.put(context,
>> newValue);
>>>> +             
>>   }
>>>> +            }
>>>> +
>>>> +            if
>> (global) {
>>>> +           
>>    
>>>> Map<String, Object> globalCtx =
>>>> 
>> UtilGenerics.checkMap(context.get("globalContext"));
>>>> +             
>>   if
>>>> (globalCtx != null) {
>>>> +           
>>    
>>>>      this.field.put(globalCtx,
>> newValue);
>>>> +             
>>   }
>>>> else {
>>>> +           
>>    
>>>>      this.field.put(context,
>> newValue);
>>>> +             
>>   }
>>>> +            }
>>>> +
>>>> +            // this
>> is a
>>>> hack for backward compatibility with the JPublish
>> page
>>>> object
>>>> +           
>> Map<String,
>>>> Object> page =
>>>> UtilGenerics.checkMap(context.get("page"));
>>>> +            if
>> (page !=
>>>> null) {
>>>> +           
>>    
>>>> this.field.put(page, newValue);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public Object
>>>> getInMemoryPersistedFromField(Object storeAgent,
>>>> Map<String, Object> context) {
>>>> +            Object
>> newValue
>>>> = null;
>>>> +            String
>>>> originalName = this.fromField.getOriginalName();
>>>> +           
>>>> List<String> currentWidgetTrail =
>>>> 
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>>>> +           
>>>> List<String> trailList = new
>>>> ArrayList<String>();
>>>> +            if
>>>> (currentWidgetTrail != null) {
>>>> +           
>>    
>>>> trailList.addAll(currentWidgetTrail);
>>>> +            }
>>>> +
>>>> +            for
>> (int
>>>> i=trailList.size(); i >= 0; i--) {
>>>> +           
>>    
>>>> List<String> subTrail =
>> trailList.subList(0,i);
>>>> +           
>>    
>>>> String newKey = null;
>>>> +             
>>   if
>>>> (subTrail.size() > 0)
>>>> +           
>>    
>>>>      newKey =
>> StringUtil.join(subTrail, "|") + "|"
>>>> + originalName;
>>>> +           
>>    
>>>> else
>>>> +           
>>    
>>>>      newKey = originalName;
>>>> +
>>>> +             
>>   if
>>>> (storeAgent instanceof ServletContext) {
>>>> +           
>>    
>>>>      newValue =
>>>> 
>> ((ServletContext)storeAgent).getAttribute(newKey);
>>>> +             
>>   }
>>>> else if (storeAgent instanceof HttpSession) {
>>>> +           
>>    
>>>>      newValue =
>>>> ((HttpSession)storeAgent).getAttribute(newKey);
>>>> +             
>>   }
>>>> +             
>>   if
>>>> (newValue != null) {
>>>> +           
>>    
>>>>      break;
>>>> +             
>>   }
>>>> +            }
>>>> +            return
>>>> newValue;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class PropertyMap
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>>>> FlexibleStringExpander resourceExdr;
>>>> +        protected
>>>> 
>> FlexibleMapAccessor<ResourceBundleMapWrapper>
>>>> mapNameAcsr;
>>>> +        protected
>>>> FlexibleStringExpander globalExdr;
>>>> +
>>>> +        public
>> PropertyMap(ModelWidget
>>>> modelWidget, Element setElement) {
>>>> +            super
>>>> (modelWidget, setElement);
>>>> +           
>>>> this.resourceExdr =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
>>>> +           
>> this.mapNameAcsr
>>>> =
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("map-name"));
>>>> +           
>> this.globalExdr
>>>> =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            String
>> globalStr
>>>> = this.globalExdr.expandString(context);
>>>> +            //
>> default to
>>>> false
>>>> +            boolean
>> global =
>>>> "true".equals(globalStr);
>>>> +
>>>> +            Locale
>> locale =
>>>> (Locale) context.get("locale");
>>>> +            String
>> resource
>>>> = this.resourceExdr.expandString(context,
>> locale);
>>>> +
>>>> +           
>>>> ResourceBundleMapWrapper existingPropMap =
>>>> this.mapNameAcsr.get(context);
>>>> +            if
>>>> (existingPropMap == null) {
>>>> +           
>>    
>>>> this.mapNameAcsr.put(context,
>>>> UtilProperties.getResourceBundleMap(resource,
>> locale,
>>>> context));
>>>> +            } else
>> {
>>>> +           
>>    
>>>> try {
>>>> +           
>>    
>>>>     
>>>> 
>> existingPropMap.addBottomResourceBundle(resource);
>>>> +             
>>   }
>>>> catch (IllegalArgumentException e) {
>>>> +           
>>    
>>>>      // log the error, but
>> don't let it kill
>>>> everything just for a typo or bad char in an l10n
>> file
>>>> +           
>>    
>>>>      Debug.logError(e, "Error
>> adding resource
>>>> bundle [" + resource + "]: " + e.toString(),
>> module);
>>>> +             
>>   }
>>>> +            }
>>>> +
>>>> +            if
>> (global) {
>>>> +           
>>    
>>>> Map<String, Object> globalCtx =
>>>> 
>> UtilGenerics.checkMap(context.get("globalContext"));
>>>> +             
>>   if
>>>> (globalCtx != null) {
>>>> +           
>>    
>>>>      ResourceBundleMapWrapper
>> globalExistingPropMap
>>>> = this.mapNameAcsr.get(globalCtx);
>>>> +           
>>    
>>>>      if (globalExistingPropMap
>> == null) {
>>>> +           
>>    
>>>>      
>>    this.mapNameAcsr.put(globalCtx,
>>>> UtilProperties.getResourceBundleMap(resource,
>> locale,
>>>> context));
>>>> +           
>>    
>>>>      } else {
>>>> +           
>>    
>>>>          // is it the
>> same object? if not
>>>> add it in here too...
>>>> +           
>>    
>>>>          if
>> (existingPropMap !=
>>>> globalExistingPropMap) {
>>>> +           
>>    
>>>>          
>>    try {
>>>> +           
>>    
>>>>              
>>   
>>>> 
>> globalExistingPropMap.addBottomResourceBundle(resource);
>>>> +           
>>    
>>>>          
>>    } catch
>>>> (IllegalArgumentException e) {
>>>> +           
>>    
>>>>              
>>    //
>>>> log the error, but don't let it kill everything
>> just for a
>>>> typo or bad char in an l10n file
>>>> +           
>>    
>>>>              
>>   
>>>> Debug.logError(e, "Error adding resource bundle ["
>> +
>>>> resource + "]: " + e.toString(), module);
>>>> +           
>>    
>>>>          
>>    }
>>>> +           
>>    
>>>>          }
>>>> +           
>>    
>>>>      }
>>>> +             
>>   }
>>>> +            }
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class PropertyToField
>> extends
>>>> ModelWidgetAction {
>>>> +
>>>> +        protected
>>>> FlexibleStringExpander resourceExdr;
>>>> +        protected
>>>> FlexibleStringExpander propertyExdr;
>>>> +        protected
>>>> FlexibleMapAccessor<Object> fieldAcsr;
>>>> +        protected
>>>> FlexibleStringExpander defaultExdr;
>>>> +        protected boolean
>> noLocale;
>>>> +        protected
>>>> FlexibleMapAccessor<List<? extends
>> Object>>
>>>> argListAcsr;
>>>> +        protected
>>>> FlexibleStringExpander globalExdr;
>>>> +
>>>> +        public
>>>> PropertyToField(ModelWidget modelWidget, Element
>> setElement)
>>>> {
>>>> +            super
>>>> (modelWidget, setElement);
>>>> +           
>>>> this.resourceExdr =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
>>>> +           
>>>> this.propertyExdr =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
>>>> +           
>> this.fieldAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
>>>> +           
>> this.defaultExdr
>>>> =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("default"));
>>>> +           
>> this.noLocale =
>>>> 
>> "true".equals(setElement.getAttribute("no-locale"));
>>>> +           
>> this.argListAcsr
>>>> =
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("arg-list-name"));
>>>> +           
>> this.globalExdr
>>>> =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +           
>> //String
>>>> globalStr =
>> this.globalExdr.expandString(context);
>>>> +            //
>> default to
>>>> false
>>>> +           
>> //boolean global
>>>> = "true".equals(globalStr);
>>>> +
>>>> +            Locale
>> locale =
>>>> (Locale) context.get("locale");
>>>> +            String
>> resource
>>>> = this.resourceExdr.expandString(context,
>> locale);
>>>> +            String
>> property
>>>> = this.propertyExdr.expandString(context,
>> locale);
>>>> +
>>>> +            String
>> value =
>>>> null;
>>>> +            if
>> (noLocale) {
>>>> +           
>>    
>>>> value = UtilProperties.getPropertyValue(resource,
>>>> property);
>>>> +            } else
>> {
>>>> +           
>>    
>>>> value = UtilProperties.getMessage(resource,
>> property,
>>>> locale);
>>>> +            }
>>>> +            if
>>>> (UtilValidate.isEmpty(value)) {
>>>> +           
>>    
>>>> value = this.defaultExdr.expandString(context);
>>>> +            }
>>>> +
>>>> +            // note
>> that
>>>> expanding the value string here will handle
>> defaultValue and
>>>> the string from
>>>> +           
>> //  the
>>>> properties file; if we decide later that we don't
>> want the
>>>> string from the properties
>>>> +           
>> //  file to
>>>> be expanded we should just expand the defaultValue
>> at the
>>>> beginning of this method.
>>>> +            value
>> =
>>>> FlexibleStringExpander.expandString(value,
>> context);
>>>> +
>>>> +            if
>>>> (!argListAcsr.isEmpty()) {
>>>> +           
>>    
>>>> List<? extends Object> argList =
>>>> argListAcsr.get(context);
>>>> +             
>>   if
>>>> (UtilValidate.isNotEmpty(argList)) {
>>>> +           
>>    
>>>>      value =
>> MessageFormat.format(value,
>>>> argList.toArray());
>>>> +             
>>   }
>>>> +            }
>>>> +           
>>>> fieldAcsr.put(context, value);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class Script extends
>>>> ModelWidgetAction {
>>>> +        protected static
>> final
>>>> Object[] EMPTY_ARGS = {};
>>>> +        protected String
>> location;
>>>> +        protected String
>> method;
>>>> +
>>>> +        public
>> Script(ModelWidget
>>>> modelWidget, Element scriptElement) {
>>>> +            super
>>>> (modelWidget, scriptElement);
>>>> +            String
>>>> scriptLocation =
>> scriptElement.getAttribute("location");
>>>> +           
>> this.location =
>>>> WidgetWorker.getScriptLocation(scriptLocation);
>>>> +           
>> this.method =
>>>> WidgetWorker.getScriptMethodName(scriptLocation);
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context)
>> throws
>>>> GeneralException {
>>>> +            if
>>>> (location.endsWith(".bsh")) {
>>>> +           
>>    
>>>> try {
>>>> +           
>>    
>>>>  
>>    BshUtil.runBshAtLocation(location,
>> context);
>>>> +             
>>   }
>>>> catch (GeneralException e) {
>>>> +           
>>    
>>>>      throw new
>> GeneralException("Error running BSH
>>>> script at location [" + location + "]", e);
>>>> +             
>>   }
>>>> +            } else
>> if
>>>> (location.endsWith(".groovy")) {
>>>> +           
>>    
>>>> try {
>>>> +           
>>    
>>>>      groovy.lang.Script script
>> =
>>>> 
>> InvokerHelper.createScript(GroovyUtil.getScriptClassFromLocation(location),
>>>> GroovyUtil.getBinding(context));
>>>> +           
>>    
>>>>      if
>> (UtilValidate.isEmpty(method)) {
>>>> +           
>>    
>>>>      
>>    script.run();
>>>> +           
>>    
>>>>      } else {
>>>> +           
>>    
>>>>      
>>    script.invokeMethod(method,
>>>> EMPTY_ARGS);
>>>> +           
>>    
>>>>      }
>>>> +             
>>   }
>>>> catch (GeneralException e) {
>>>> +           
>>    
>>>>      throw new
>> GeneralException("Error running
>>>> Groovy script at location [" + location + "]",
>> e);
>>>> +             
>>   }
>>>> +            } else
>> if
>>>> (location.endsWith(".xml")) {
>>>> +           
>>    
>>>> Map<String, Object> localContext =
>>>> FastMap.newInstance();
>>>> +           
>>    
>>>> localContext.putAll(context);
>>>> +           
>>    
>>>> DispatchContext ctx =
>>>> 
>> WidgetWorker.getDispatcher(context).getDispatchContext();
>>>> +           
>>    
>>>> MethodContext methodContext = new
>> MethodContext(ctx,
>>>> localContext, null);
>>>> +           
>>    
>>>> try {
>>>> +           
>>    
>>>>  
>>    SimpleMethod.runSimpleMethod(location,
>> method,
>>>> methodContext);
>>>> +           
>>    
>>>>  
>>    context.putAll(methodContext.getResults());
>>>> +             
>>   }
>>>> catch (MiniLangException e) {
>>>> +           
>>    
>>>>      throw new
>> GeneralException("Error running
>>>> simple method at location [" + location + "]",
>> e);
>>>> +             
>>   }
>>>> +            } else
>> {
>>>> +           
>>    
>>>> throw new GeneralException("For widget script
>> actions the
>>>> script type is not yet supported for location: ["
>> + location
>>>> + "]");
>>>> +            }
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class Service
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>>>> FlexibleStringExpander serviceNameExdr;
>>>> +        protected
>>>> FlexibleMapAccessor<Map<String,
>> Object>>
>>>> resultMapNameAcsr;
>>>> +        protected
>>>> FlexibleStringExpander autoFieldMapExdr;
>>>> +        protected
>>>> Map<FlexibleMapAccessor<Object>,
>> Object>
>>>> fieldMap;
>>>> +
>>>> +        public
>> Service(ModelWidget
>>>> modelWidget, Element serviceElement) {
>>>> +            super
>>>> (modelWidget, serviceElement);
>>>> +           
>>>> this.serviceNameExdr =
>>>> 
>> FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
>>>> +           
>>>> this.resultMapNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
>>>> +            if
>>>> (this.resultMapNameAcsr.isEmpty())
>> this.resultMapNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
>>>> +           
>>>> this.autoFieldMapExdr =
>>>> 
>> FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
>>>> +           
>> this.fieldMap =
>>>> EntityFinderUtil.makeFieldMap(serviceElement);
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            String
>>>> serviceNameExpanded =
>>>> this.serviceNameExdr.expandString(context);
>>>> +            if
>>>> (UtilValidate.isEmpty(serviceNameExpanded)) {
>>>> +           
>>    
>>>> throw new IllegalArgumentException("Service name
>> was empty,
>>>> expanded from: " +
>> this.serviceNameExdr.getOriginal());
>>>> +            }
>>>> +
>>>> +            String
>>>> autoFieldMapString =
>>>> this.autoFieldMapExdr.expandString(context);
>>>> +
>>>> +            try {
>>>> +           
>>    
>>>> Map<String, Object> serviceContext = null;
>>>> +             
>>   if
>>>> ("true".equals(autoFieldMapString)) {
>>>> +           
>>    
>>>>      DispatchContext dc =
>>>> 
>> WidgetWorker.getDispatcher(context).getDispatchContext();
>>>> +           
>>    
>>>>      // try a map called
>> "parameters", try it first
>>>> so values from here are overriden by values in the
>> main
>>>> context
>>>> +           
>>    
>>>>      Map<String, Object>
>> combinedMap =
>>>> FastMap.newInstance();
>>>> +           
>>    
>>>>      Map<String, Object>
>> parametersObj =
>>>> UtilGenerics.toMap(context.get("parameters"));
>>>> +           
>>    
>>>>      if (parametersObj != null)
>> {
>>>> +           
>>    
>>>>         
>>>> combinedMap.putAll(parametersObj);
>>>> +           
>>    
>>>>      }
>>>> +           
>>    
>>>>  
>>    combinedMap.putAll(context);
>>>> +           
>>    
>>>>      serviceContext =
>>>> dc.makeValidContext(serviceNameExpanded,
>>>> ModelService.IN_PARAM, combinedMap);
>>>> +             
>>   }
>>>> else if
>> (UtilValidate.isNotEmpty(autoFieldMapString)
>>>> && !"false".equals(autoFieldMapString)) {
>>>> +           
>>    
>>>>  
>>    FlexibleMapAccessor<Object> fieldFma
>> =
>>>> 
>> FlexibleMapAccessor.getInstance(autoFieldMapString);
>>>> +           
>>    
>>>>      Map<String, Object>
>> autoFieldMap =
>>>> UtilGenerics.toMap(fieldFma.get(context));
>>>> +           
>>    
>>>>      if (autoFieldMap != null)
>> {
>>>> +           
>>    
>>>>      
>>    serviceContext =
>>>> 
>> WidgetWorker.getDispatcher(context).getDispatchContext().makeValidContext(serviceNameExpanded,
>>>> ModelService.IN_PARAM, autoFieldMap);
>>>> +           
>>    
>>>>      }
>>>> +             
>>   }
>>>> +             
>>   if
>>>> (serviceContext == null) {
>>>> +           
>>    
>>>>      serviceContext =
>> FastMap.newInstance();
>>>> +             
>>   }
>>>> +
>>>> +             
>>   if
>>>> (this.fieldMap != null) {
>>>> +           
>>    
>>>>     
>>>> 
>> EntityFinderUtil.expandFieldMapToContext(this.fieldMap,
>>>> context, serviceContext);
>>>> +             
>>   }
>>>> +
>>>> +           
>>    
>>>> Map<String, Object> result =
>>>> 
>> WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded,
>>>> serviceContext);
>>>> +
>>>> +             
>>   if
>>>> (!this.resultMapNameAcsr.isEmpty()) {
>>>> +           
>>    
>>>>  
>>    this.resultMapNameAcsr.put(context,
>> result);
>>>> +           
>>    
>>>>      String queryString =
>>>> (String)result.get("queryString");
>>>> +           
>>    
>>>>      context.put("queryString",
>> queryString);
>>>> +           
>>    
>>>>  
>>    context.put("queryStringMap",
>>>> result.get("queryStringMap"));
>>>> +           
>>    
>>>>      if
>> (UtilValidate.isNotEmpty(queryString)) {
>>>> +           
>>    
>>>>          try {
>>>> +           
>>    
>>>>          
>>    String
>>>> queryStringEncoded =
>> queryString.replaceAll("&",
>>>> "%26");
>>>> +           
>>    
>>>>             
>>>> context.put("queryStringEncoded",
>> queryStringEncoded);
>>>> +           
>>    
>>>>          } catch
>> (PatternSyntaxException
>>>> e) {
>>>> +
>>>> +           
>>    
>>>>          }
>>>> +           
>>    
>>>>      }
>>>> +             
>>   }
>>>> else {
>>>> +           
>>    
>>>>      context.putAll(result);
>>>> +             
>>   }
>>>> +            }
>> catch
>>>> (GenericServiceException e) {
>>>> +           
>>    
>>>> String errMsg = "Error calling service with name "
>> +
>>>> serviceNameExpanded + ": " + e.toString();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public
>> FlexibleStringExpander
>>>> getServiceNameExdr() {
>>>> +            return
>>>> this.serviceNameExdr;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class EntityOne
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>> PrimaryKeyFinder
>>>> finder;
>>>> +
>>>> +        public
>> EntityOne(ModelWidget
>>>> modelWidget, Element entityOneElement) {
>>>> +            super
>>>> (modelWidget, entityOneElement);
>>>> +            finder
>> = new
>>>> PrimaryKeyFinder(entityOneElement);
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            try {
>>>> +           
>>    
>>>> finder.runFind(context,
>>>> WidgetWorker.getDelegator(context));
>>>> +            }
>> catch
>>>> (GeneralException e) {
>>>> +           
>>    
>>>> String errMsg = "Error doing entity query by
>> condition: " +
>>>> e.toString();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public
>> PrimaryKeyFinder
>>>> getFinder() {
>>>> +            return
>>>> this.finder;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class EntityAnd
>> extends
>>>> ModelWidgetAction {
>>>> +        protected ByAndFinder
>> finder;
>>>> +
>>>> +        public
>> EntityAnd(ModelWidget
>>>> modelWidget, Element entityAndElement) {
>>>> +            super
>>>> (modelWidget, entityAndElement);
>>>> +            finder
>> = new
>>>> ByAndFinder(entityAndElement);
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            try {
>>>> +           
>>    
>>>> finder.runFind(context,
>>>> WidgetWorker.getDelegator(context));
>>>> +            }
>> catch
>>>> (GeneralException e) {
>>>> +           
>>    
>>>> String errMsg = "Error doing entity query by
>> condition: " +
>>>> e.toString();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public ByAndFinder
>> getFinder()
>>>> {
>>>> +            return
>>>> this.finder;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class EntityCondition
>> extends
>>>> ModelWidgetAction {
>>>> +        ByConditionFinder
>> finder;
>>>> +
>>>> +        public
>>>> EntityCondition(ModelWidget modelWidget, Element
>>>> entityConditionElement) {
>>>> +            super
>>>> (modelWidget, entityConditionElement);
>>>> +            finder
>> = new
>>>> ByConditionFinder(entityConditionElement);
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            try {
>>>> +           
>>    
>>>> finder.runFind(context,
>>>> WidgetWorker.getDelegator(context));
>>>> +            }
>> catch
>>>> (GeneralException e) {
>>>> +           
>>    
>>>> String errMsg = "Error doing entity query by
>> condition: " +
>>>> e.toString();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public
>> ByConditionFinder
>>>> getFinder() {
>>>> +            return
>>>> this.finder;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class GetRelatedOne
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>>>> FlexibleMapAccessor<Object> valueNameAcsr;
>>>> +        protected
>>>> FlexibleMapAccessor<Object>
>> toValueNameAcsr;
>>>> +        protected String
>>>> relationName;
>>>> +        protected boolean
>> useCache;
>>>> +
>>>> +        public
>>>> GetRelatedOne(ModelWidget modelWidget, Element
>>>> getRelatedOneElement) {
>>>> +            super
>>>> (modelWidget, getRelatedOneElement);
>>>> +           
>>>> this.valueNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
>>>> +            if
>>>> (this.valueNameAcsr.isEmpty()) this.valueNameAcsr
>> =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-name"));
>>>> +           
>>>> this.toValueNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
>>>> +            if
>>>> (this.toValueNameAcsr.isEmpty())
>> this.toValueNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-name"));
>>>> +           
>>>> this.relationName =
>>>> 
>> getRelatedOneElement.getAttribute("relation-name");
>>>> +           
>> this.useCache =
>>>> 
>> "true".equals(getRelatedOneElement.getAttribute("use-cache"));
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            Object
>>>> valueObject = valueNameAcsr.get(context);
>>>> +            if
>> (valueObject
>>>> == null) {
>>>> +           
>>    
>>>> Debug.logVerbose("Value not found with name: " +
>>>> valueNameAcsr + ", not getting related...",
>> module);
>>>> +           
>>    
>>>> return;
>>>> +            }
>>>> +            if
>>>> (!(valueObject instanceof GenericValue)) {
>>>> +           
>>    
>>>> String errMsg = "Env variable for value-name " +
>>>> valueNameAcsr.toString() + " is not a GenericValue
>> object;
>>>> for the relation-name: " + relationName + "]";
>>>> +           
>>    
>>>> Debug.logError(errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +           
>> GenericValue
>>>> value = (GenericValue) valueObject;
>>>> +            try {
>>>> +             
>>   if
>>>> (useCache) {
>>>> +           
>>    
>>>>  
>>    toValueNameAcsr.put(context,
>>>> value.getRelatedOneCache(relationName));
>>>> +             
>>   }
>>>> else {
>>>> +           
>>    
>>>>  
>>    toValueNameAcsr.put(context,
>>>> value.getRelatedOne(relationName));
>>>> +             
>>   }
>>>> +            }
>> catch
>>>> (GenericEntityException e) {
>>>> +           
>>    
>>>> String errMsg = "Problem getting related one from
>> entity
>>>> with name " + value.getEntityName() + " for the
>>>> relation-name: " + relationName + ": " +
>> e.getMessage();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public String
>>>> getRelationName() {
>>>> +            return
>>>> this.relationName;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class GetRelated
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>>>> FlexibleMapAccessor<Object> valueNameAcsr;
>>>> +        protected
>>>> 
>> FlexibleMapAccessor<List<GenericValue>>
>>>> listNameAcsr;
>>>> +        protected
>>>> FlexibleMapAccessor<Map<String,
>> Object>>
>>>> mapAcsr;
>>>> +        protected
>>>> FlexibleMapAccessor<List<String>>
>>>> orderByListAcsr;
>>>> +        protected String
>>>> relationName;
>>>> +        protected boolean
>> useCache;
>>>> +
>>>> +        public
>> GetRelated(ModelWidget
>>>> modelWidget, Element getRelatedElement) {
>>>> +            super
>>>> (modelWidget, getRelatedElement);
>>>> +           
>>>> this.valueNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
>>>> +            if
>>>> (this.valueNameAcsr.isEmpty()) this.valueNameAcsr
>> =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-name"));
>>>> +           
>>>> this.listNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
>>>> +            if
>>>> (this.listNameAcsr.isEmpty()) this.listNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list-name"));
>>>> +           
>>>> this.relationName =
>>>> getRelatedElement.getAttribute("relation-name");
>>>> +           
>> this.mapAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
>>>> +            if
>>>> (this.mapAcsr.isEmpty()) this.mapAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map-name"));
>>>> +           
>>>> this.orderByListAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
>>>> +            if
>>>> (this.orderByListAcsr.isEmpty())
>> this.orderByListAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list-name"));
>>>> +           
>> this.useCache =
>>>> 
>> "true".equals(getRelatedElement.getAttribute("use-cache"));
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            Object
>>>> valueObject = valueNameAcsr.get(context);
>>>> +            if
>> (valueObject
>>>> == null) {
>>>> +           
>>    
>>>> Debug.logVerbose("Value not found with name: " +
>>>> valueNameAcsr + ", not getting related...",
>> module);
>>>> +           
>>    
>>>> return;
>>>> +            }
>>>> +            if
>>>> (!(valueObject instanceof GenericValue)) {
>>>> +           
>>    
>>>> String errMsg = "Env variable for value-name " +
>>>> valueNameAcsr.toString() + " is not a GenericValue
>> object;
>>>> for the relation-name: " + relationName + "]";
>>>> +           
>>    
>>>> Debug.logError(errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +           
>> GenericValue
>>>> value = (GenericValue) valueObject;
>>>> +           
>>>> List<String> orderByNames = null;
>>>> +            if
>>>> (!orderByListAcsr.isEmpty()) {
>>>> +           
>>    
>>>> orderByNames = orderByListAcsr.get(context);
>>>> +            }
>>>> +           
>> Map<String,
>>>> Object> constraintMap = null;
>>>> +            if
>>>> (!mapAcsr.isEmpty()) {
>>>> +           
>>    
>>>> constraintMap = mapAcsr.get(context);
>>>> +            }
>>>> +            try {
>>>> +             
>>   if
>>>> (useCache) {
>>>> +           
>>    
>>>>      listNameAcsr.put(context,
>>>> value.getRelatedCache(relationName,
>> constraintMap,
>>>> orderByNames));
>>>> +             
>>   }
>>>> else {
>>>> +           
>>    
>>>>      listNameAcsr.put(context,
>>>> value.getRelated(relationName, constraintMap,
>>>> orderByNames));
>>>> +             
>>   }
>>>> +            }
>> catch
>>>> (GenericEntityException e) {
>>>> +           
>>    
>>>> String errMsg = "Problem getting related from
>> entity with
>>>> name " + value.getEntityName() + " for the
>> relation-name: "
>>>> + relationName + ": " + e.getMessage();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public String
>>>> getRelationName() {
>>>> +            return
>>>> this.relationName;
>>>> +        }
>>>> +    }
>>>> +}
>>>> 
>>>> Propchange:
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> 
>> ------------------------------------------------------------------------------
>>>>      svn:eol-style = native
>>>> 
>>>> Propchange:
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> 
>> ------------------------------------------------------------------------------
>>>>      svn:keywords = "Date Rev
>> Author URL Id"
>>>> 
>>>> Propchange:
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> 
>> ------------------------------------------------------------------------------
>>>>      svn:mime-type =
>> text/plain
>>>> 
>>>> 
>>>> 
>>> 
>>> 
>>> 
>> 
>> 
> 
> 
> 


Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Adam Heath <do...@brainfood.com>.
The reason ofbiz hasn't seen these bugs that often, is because most
DCL uses are done at startup.  But that doesn't mean they can't happen
at all, and that DCL is ok to use for startup code.

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Adam Heath <do...@brainfood.com>.
Scott Gray wrote:
> That's fine, I'll take your word and stand corrected.  I actually don't need a nightstand because I'm able to build one out of the stack of great books that are still in queue to be read.
> The book would have done well to use a more complicated example of why DCL shouldn't be used though.  This article seems to do a better better job of it: http://www.ibm.com/developerworks/java/library/j-dcl.html

That's a good article, and does explain it well.  At least I
understand it.

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Jacques Le Roux <ja...@les7arts.com>.
From: "Adam Heath" <do...@brainfood.com>
> Jacques Le Roux wrote:
>> Very good article indeed. What do we learn more in the book about DCL?
>> If there is nothing more in the book, I suppose we prefer to use the
>> static variable solution in OFBiz?
> 
> That is only good enough for certain situations.  Not for map-based
> lookups.

Ha ok!
 
> The article could be better in explaining *why* the static variable is
> better/different.  The book does.

Yes, I think I will buy the book, it's time to refresh my knowledge...

Jacques
 
> 
>> From: "Adrian Crum" <ad...@yahoo.com>
>>> --- On Fri, 7/2/10, Scott Gray <sc...@hotwaxmedia.com> wrote:
>>>> The book would have done well to use a more complicated
>>>> example of why DCL shouldn't be used though. This
>>>> article seems to do a better better job of it:
>>>> http://www.ibm.com/developerworks/java/library/j-dcl.html
>>>
>>> That was the article I found a while back - before I got the book.
>> 
>


Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Adam Heath <do...@brainfood.com>.
Jacques Le Roux wrote:
> Very good article indeed. What do we learn more in the book about DCL?
> If there is nothing more in the book, I suppose we prefer to use the
> static variable solution in OFBiz?

That is only good enough for certain situations.  Not for map-based
lookups.

The article could be better in explaining *why* the static variable is
better/different.  The book does.


> From: "Adrian Crum" <ad...@yahoo.com>
>> --- On Fri, 7/2/10, Scott Gray <sc...@hotwaxmedia.com> wrote:
>>> The book would have done well to use a more complicated
>>> example of why DCL shouldn't be used though. This
>>> article seems to do a better better job of it:
>>> http://www.ibm.com/developerworks/java/library/j-dcl.html
>>
>> That was the article I found a while back - before I got the book.
> 


Re: Double-checked locking antipattern

Posted by Adrian Crum <ad...@yahoo.com>.
--- On Sat, 7/3/10, Adam Heath <do...@brainfood.com> wrote:
> Adrian Crum wrote:
> > As the article and the book (Java Concurrency In
> Practice) both point out - the motivation for using DCL (to
> overcome slow speed) is less of an issue (or a non-issue)
> with newer JVMs.
> > 
> > I am not a Java expert. But enough Java experts have
> stressed the need to eliminate this anti-pattern that I am
> willing to take their word for it. I said that in
> preparation for repeating what Adam said earlier - there are
> enough potential problems with DCL that it should not be
> used. I agree that there might be some DCL code in OFBiz
> that hasn't caused any problems so far, and it might be
> tempting to think "if it isn't broke, don't fix it" - but
> personally, I prefer to remove the potential problem.
> > 
> > I have seen DCL used in two circumstances in OFBiz: to
> lazy load a static field (singleton), and to get elements
> from a Map.
> 
> I'd like to to state it now.  Do not start removing
> these things.  I
> am already working towards that goal.  But to do it
> properly, requires
> sufficient multi-threaded testing, and that is going to
> take me a bit.
> 
> I currently have 15 separate commits that remove
> synchronization(some
> of those are DCL).

Understood. I don't think anyone is suggesting that we go around with a DCL hatchet and start chopping out code. From my perspective, we're just discussing why it shouldn't be used.

> 
> > 
> > 1. Lazy load a static field
> > ---------------------------
> >
> > // This is bad, don't do this
> > public class MyClass {
> >   private static Resource resource;
> > 
> >   public static Resource getInstance()
> {
> >     if (resource == null {
> >       synchronized
> (MyClass.class) {
> >         if (resource ==
> null) {
> >           resource
> = new Resource();
> >         }
> >       }
> >     }
> >     return resource;
> >   }
> > }
> > 
> > The easiest fix in this example is to make
> getInstance() synchronized:
> > 
> > public synchronized static Resource getInstance() {
> >   if (resource == null {
> >     resource = new Resource();
> >   }
> >   return resource;
> > }
> > 
> > The lazy load has been preserved, but at a cost of
> synchronizing every call to getInstance().
> > 
> > It would be better to eliminate the lazy load
> altogether:
> > 
> > public class MyClass {
> >   private static Resource resource =
> new Resource();
> > 
> >   public static Resource getInstance()
> {
> >     return resource;
> >   }
> 
> You don't need need the accessor here, if you make resource
> final.
> 
> > }
> 
> This is not the best approach.  Now the item is always
> loaded whenever
> MyClass is referenced.

Keep in mind my reply was to Jacques - who wanted to know what the book had to say on the subject. So, I gave him two examples of safe initialization taken from the book (section 16.2.3).

> 
> class MyClass {
>   public static final Resource alwaysNeeded = new
> Resource();
>   private static volatile
> AtomicReference<Resource> sometimesNeeded =
> new AtomicReference<Resource>();
>   private static volatile
> AtomicReference<Resource> seldomNeeded = new
> AtomicReference<Resource>();
> 
>   public static Resource getSometimesNeeded() {
>     Resource resource = sometimesNeeded.get();
>     if (resource != null) return resource;
>     resource = new Resource();
>     sometimesNeeded.compareAndSet(null,
> resource);
>     // second get needed incase 2 threads got
> past the null check
>     return sometimesNeeded.get();
>   }
> }
> 
> 
> 
> > 2. Get elements from a Map
> > --------------------------
> > 
> > // This is bad, don't do this
> > public class MyClass {
> >   private static Map<String,
> Resource> resourceMap = FastMap.newInstance();
> > 
> >   public static Resource
> getResource(String resourceName) {
> >     Resource resource =
> resourceMap.get(resourceName);
> >     if (resource == null {
> >       synchronized
> (MyClass.class) {
> >         resource =
> resourceMap.get(resourceName);
> >         if (resource ==
> null) {
> >           resource
> = new Resource();
> >       
>    resourceMap.put(resourceName, resource);
> >         }
> >       }
> >     }
> >     return resource;
> >   }
> > }
> > 
> > Again, the easiest fix is to make the getResource
> method synchronized:
> > 
> > public synchronized static Resource getResource(String
> resourceName) {
> >   Resource resource =
> resourceMap.get(resourceName);
> >   if (resource == null {
> >     resource = new Resource();
> >     resourceMap.put(resourceName,
> resource);
> >   }
> >   return resource;
> > }
> > 
> > This fix comes at a cost of synchronizing every call
> to getResource. If the cost of creating a new instance of
> Resource is low, we can skip synchronization altogether:
> > 
> > public static Resource getResource(String
> resourceName) {
> >   Resource resource =
> resourceMap.get(resourceName);
> >   if (resource == null {
> >     resource = new Resource();
> >     resourceMap.put(resourceName,
> resource);
> >     resource =
> resourceMap.get(resourceName);
> >   }
> >   return resource;
> > }
> 
> This is buggy.  Multiple threads could try for the
> same resource,
> create multiple entries, and both call put.  The map
> can then become
> corrupted.  I've seen it happen.  Do not do
> this.
> 
> > 
> > Using this method, there is a chance that more than
> one thread will create a Resource instance, but we are not
> concerned about that - we just do a second
> resourceMap.get(resourceName) method call to make sure we
> have the Resource instance that "won."
> 
> ConcurrentMap map = new ConcurrentHashMap();
> 
> map.putIfAbsent(resourceName, resource);
> resource = resourceMap.get(resourceName);
> 
> These lines will fix the problem I mentioned.
> 
> 
> 
> 


      

Re: Double-checked locking antipattern

Posted by Adam Heath <do...@brainfood.com>.
Adrian Crum wrote:
> As the article and the book (Java Concurrency In Practice) both point out - the motivation for using DCL (to overcome slow speed) is less of an issue (or a non-issue) with newer JVMs.
> 
> I am not a Java expert. But enough Java experts have stressed the need to eliminate this anti-pattern that I am willing to take their word for it. I said that in preparation for repeating what Adam said earlier - there are enough potential problems with DCL that it should not be used. I agree that there might be some DCL code in OFBiz that hasn't caused any problems so far, and it might be tempting to think "if it isn't broke, don't fix it" - but personally, I prefer to remove the potential problem.
> 
> I have seen DCL used in two circumstances in OFBiz: to lazy load a static field (singleton), and to get elements from a Map.

I'd like to to state it now.  Do not start removing these things.  I
am already working towards that goal.  But to do it properly, requires
sufficient multi-threaded testing, and that is going to take me a bit.

I currently have 15 separate commits that remove synchronization(some
of those are DCL).

> 
> 1. Lazy load a static field
> ---------------------------
>
> // This is bad, don't do this
> public class MyClass {
>   private static Resource resource;
> 
>   public static Resource getInstance() {
>     if (resource == null {
>       synchronized (MyClass.class) {
>         if (resource == null) {
>           resource = new Resource();
>         }
>       }
>     }
>     return resource;
>   }
> }
> 
> The easiest fix in this example is to make getInstance() synchronized:
> 
> public synchronized static Resource getInstance() {
>   if (resource == null {
>     resource = new Resource();
>   }
>   return resource;
> }
> 
> The lazy load has been preserved, but at a cost of synchronizing every call to getInstance().
> 
> It would be better to eliminate the lazy load altogether:
> 
> public class MyClass {
>   private static Resource resource = new Resource();
> 
>   public static Resource getInstance() {
>     return resource;
>   }

You don't need need the accessor here, if you make resource final.

> }

This is not the best approach.  Now the item is always loaded whenever
MyClass is referenced.

class MyClass {
  public static final Resource alwaysNeeded = new Resource();
  private static volatile AtomicReference<Resource> sometimesNeeded =
new AtomicReference<Resource>();
  private static volatile AtomicReference<Resource> seldomNeeded = new
AtomicReference<Resource>();

  public static Resource getSometimesNeeded() {
    Resource resource = sometimesNeeded.get();
    if (resource != null) return resource;
    resource = new Resource();
    sometimesNeeded.compareAndSet(null, resource);
    // second get needed incase 2 threads got past the null check
    return sometimesNeeded.get();
  }
}



> 2. Get elements from a Map
> --------------------------
> 
> // This is bad, don't do this
> public class MyClass {
>   private static Map<String, Resource> resourceMap = FastMap.newInstance();
> 
>   public static Resource getResource(String resourceName) {
>     Resource resource = resourceMap.get(resourceName);
>     if (resource == null {
>       synchronized (MyClass.class) {
>         resource = resourceMap.get(resourceName);
>         if (resource == null) {
>           resource = new Resource();
>           resourceMap.put(resourceName, resource);
>         }
>       }
>     }
>     return resource;
>   }
> }
> 
> Again, the easiest fix is to make the getResource method synchronized:
> 
> public synchronized static Resource getResource(String resourceName) {
>   Resource resource = resourceMap.get(resourceName);
>   if (resource == null {
>     resource = new Resource();
>     resourceMap.put(resourceName, resource);
>   }
>   return resource;
> }
> 
> This fix comes at a cost of synchronizing every call to getResource. If the cost of creating a new instance of Resource is low, we can skip synchronization altogether:
> 
> public static Resource getResource(String resourceName) {
>   Resource resource = resourceMap.get(resourceName);
>   if (resource == null {
>     resource = new Resource();
>     resourceMap.put(resourceName, resource);
>     resource = resourceMap.get(resourceName);
>   }
>   return resource;
> }

This is buggy.  Multiple threads could try for the same resource,
create multiple entries, and both call put.  The map can then become
corrupted.  I've seen it happen.  Do not do this.

> 
> Using this method, there is a chance that more than one thread will create a Resource instance, but we are not concerned about that - we just do a second resourceMap.get(resourceName) method call to make sure we have the Resource instance that "won."

ConcurrentMap map = new ConcurrentHashMap();

map.putIfAbsent(resourceName, resource);
resource = resourceMap.get(resourceName);

These lines will fix the problem I mentioned.




Re: Double-checked locking antipattern (was: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java)

Posted by Adrian Crum <ad...@yahoo.com>.
The static field example is from the book.

-Adrian

--- On Sat, 7/3/10, Jacques Le Roux <ja...@les7arts.com> wrote:
> Thanks Adrian,
> 
> Are they examples from the books or your own?
> 
> Jacques
> 
> From: "Adrian Crum" <ad...@yahoo.com>
> > As the article and the book (Java Concurrency In
> Practice) both point out - the motivation for using DCL (to
> overcome slow speed) 
> > is less of an issue (or a non-issue) with newer JVMs.
> >
> > I am not a Java expert. But enough Java experts have
> stressed the need to eliminate this anti-pattern that I am
> willing to take 
> > their word for it. I said that in preparation for
> repeating what Adam said earlier - there are enough
> potential problems with DCL 
> > that it should not be used. I agree that there might
> be some DCL code in OFBiz that hasn't caused any problems so
> far, and it 
> > might be tempting to think "if it isn't broke, don't
> fix it" - but personally, I prefer to remove the potential
> problem.
> >
> > I have seen DCL used in two circumstances in OFBiz: to
> lazy load a static field (singleton), and to get elements
> from a Map.
> >
> > 1. Lazy load a static field
> > ---------------------------
> >
> > // This is bad, don't do this
> > public class MyClass {
> >  private static Resource resource;
> >
> >  public static Resource getInstance() {
> >    if (resource == null {
> >      synchronized (MyClass.class) {
> >        if (resource == null) {
> >          resource = new
> Resource();
> >        }
> >      }
> >    }
> >    return resource;
> >  }
> > }
> >
> > The easiest fix in this example is to make
> getInstance() synchronized:
> >
> > public synchronized static Resource getInstance() {
> >  if (resource == null {
> >    resource = new Resource();
> >  }
> >  return resource;
> > }
> >
> > The lazy load has been preserved, but at a cost of
> synchronizing every call to getInstance().
> >
> > It would be better to eliminate the lazy load
> altogether:
> >
> > public class MyClass {
> >  private static Resource resource = new
> Resource();
> >
> >  public static Resource getInstance() {
> >    return resource;
> >  }
> > }
> >
> > 2. Get elements from a Map
> > --------------------------
> >
> > // This is bad, don't do this
> > public class MyClass {
> >  private static Map<String, Resource>
> resourceMap = FastMap.newInstance();
> >
> >  public static Resource getResource(String
> resourceName) {
> >    Resource resource =
> resourceMap.get(resourceName);
> >    if (resource == null {
> >      synchronized (MyClass.class) {
> >        resource =
> resourceMap.get(resourceName);
> >        if (resource == null) {
> >          resource = new
> Resource();
> >         
> resourceMap.put(resourceName, resource);
> >        }
> >      }
> >    }
> >    return resource;
> >  }
> > }
> >
> > Again, the easiest fix is to make the getResource
> method synchronized:
> >
> > public synchronized static Resource getResource(String
> resourceName) {
> >  Resource resource =
> resourceMap.get(resourceName);
> >  if (resource == null {
> >    resource = new Resource();
> >    resourceMap.put(resourceName, resource);
> >  }
> >  return resource;
> > }
> >
> > This fix comes at a cost of synchronizing every call
> to getResource. If the cost of creating a new instance of
> Resource is low, we 
> > can skip synchronization altogether:
> >
> > public static Resource getResource(String
> resourceName) {
> >  Resource resource =
> resourceMap.get(resourceName);
> >  if (resource == null {
> >    resource = new Resource();
> >    resourceMap.put(resourceName, resource);
> >    resource =
> resourceMap.get(resourceName);
> >  }
> >  return resource;
> > }
> >
> > Using this method, there is a chance that more than
> one thread will create a Resource instance, but we are not
> concerned about 
> > that - we just do a second
> resourceMap.get(resourceName) method call to make sure we
> have the Resource instance that "won."
> >
> > -Adrian
> >
> > --- On Sat, 7/3/10, Jacques Le Roux <ja...@les7arts.com>
> wrote:
> >
> >> From: Jacques Le Roux <ja...@les7arts.com>
> >> Subject: Re: svn commit: r959875 -
> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >> To: dev@ofbiz.apache.org
> >> Date: Saturday, July 3, 2010, 4:41 AM
> >> Very good article indeed. What do we
> >> learn more in the book about DCL?
> >> If there is nothing more in the book, I suppose we
> prefer
> >> to use the static variable solution in OFBiz?
> >>
> >> Thanks
> >>
> >> Jacques
> >>
> >> From: "Adrian Crum" <ad...@yahoo.com>
> >> > --- On Fri, 7/2/10, Scott Gray <sc...@hotwaxmedia.com>
> >> wrote:
> >> >> The book would have done well to use a
> more
> >> complicated
> >> >> example of why DCL shouldn't be used
> though. This
> >> >> article seems to do a better better job
> of it: http://www.ibm.com/developerworks/java/library/j-dcl.html
> >> >
> >> > That was the article I found a while back -
> before I
> >> got the book.
> >>
> >>
> >
> >
> >
> > 
> 
> 
> 


      

Re: Double-checked locking antipattern (was: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java)

Posted by Jacques Le Roux <ja...@les7arts.com>.
Thanks Adrian,

Are they examples from the books or your own?

Jacques

From: "Adrian Crum" <ad...@yahoo.com>
> As the article and the book (Java Concurrency In Practice) both point out - the motivation for using DCL (to overcome slow speed) 
> is less of an issue (or a non-issue) with newer JVMs.
>
> I am not a Java expert. But enough Java experts have stressed the need to eliminate this anti-pattern that I am willing to take 
> their word for it. I said that in preparation for repeating what Adam said earlier - there are enough potential problems with DCL 
> that it should not be used. I agree that there might be some DCL code in OFBiz that hasn't caused any problems so far, and it 
> might be tempting to think "if it isn't broke, don't fix it" - but personally, I prefer to remove the potential problem.
>
> I have seen DCL used in two circumstances in OFBiz: to lazy load a static field (singleton), and to get elements from a Map.
>
> 1. Lazy load a static field
> ---------------------------
>
> // This is bad, don't do this
> public class MyClass {
>  private static Resource resource;
>
>  public static Resource getInstance() {
>    if (resource == null {
>      synchronized (MyClass.class) {
>        if (resource == null) {
>          resource = new Resource();
>        }
>      }
>    }
>    return resource;
>  }
> }
>
> The easiest fix in this example is to make getInstance() synchronized:
>
> public synchronized static Resource getInstance() {
>  if (resource == null {
>    resource = new Resource();
>  }
>  return resource;
> }
>
> The lazy load has been preserved, but at a cost of synchronizing every call to getInstance().
>
> It would be better to eliminate the lazy load altogether:
>
> public class MyClass {
>  private static Resource resource = new Resource();
>
>  public static Resource getInstance() {
>    return resource;
>  }
> }
>
> 2. Get elements from a Map
> --------------------------
>
> // This is bad, don't do this
> public class MyClass {
>  private static Map<String, Resource> resourceMap = FastMap.newInstance();
>
>  public static Resource getResource(String resourceName) {
>    Resource resource = resourceMap.get(resourceName);
>    if (resource == null {
>      synchronized (MyClass.class) {
>        resource = resourceMap.get(resourceName);
>        if (resource == null) {
>          resource = new Resource();
>          resourceMap.put(resourceName, resource);
>        }
>      }
>    }
>    return resource;
>  }
> }
>
> Again, the easiest fix is to make the getResource method synchronized:
>
> public synchronized static Resource getResource(String resourceName) {
>  Resource resource = resourceMap.get(resourceName);
>  if (resource == null {
>    resource = new Resource();
>    resourceMap.put(resourceName, resource);
>  }
>  return resource;
> }
>
> This fix comes at a cost of synchronizing every call to getResource. If the cost of creating a new instance of Resource is low, we 
> can skip synchronization altogether:
>
> public static Resource getResource(String resourceName) {
>  Resource resource = resourceMap.get(resourceName);
>  if (resource == null {
>    resource = new Resource();
>    resourceMap.put(resourceName, resource);
>    resource = resourceMap.get(resourceName);
>  }
>  return resource;
> }
>
> Using this method, there is a chance that more than one thread will create a Resource instance, but we are not concerned about 
> that - we just do a second resourceMap.get(resourceName) method call to make sure we have the Resource instance that "won."
>
> -Adrian
>
> --- On Sat, 7/3/10, Jacques Le Roux <ja...@les7arts.com> wrote:
>
>> From: Jacques Le Roux <ja...@les7arts.com>
>> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> To: dev@ofbiz.apache.org
>> Date: Saturday, July 3, 2010, 4:41 AM
>> Very good article indeed. What do we
>> learn more in the book about DCL?
>> If there is nothing more in the book, I suppose we prefer
>> to use the static variable solution in OFBiz?
>>
>> Thanks
>>
>> Jacques
>>
>> From: "Adrian Crum" <ad...@yahoo.com>
>> > --- On Fri, 7/2/10, Scott Gray <sc...@hotwaxmedia.com>
>> wrote:
>> >> The book would have done well to use a more
>> complicated
>> >> example of why DCL shouldn't be used though. This
>> >> article seems to do a better better job of it: http://www.ibm.com/developerworks/java/library/j-dcl.html
>> >
>> > That was the article I found a while back - before I
>> got the book.
>>
>>
>
>
>
> 



Double-checked locking antipattern (was: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java)

Posted by Adrian Crum <ad...@yahoo.com>.
As the article and the book (Java Concurrency In Practice) both point out - the motivation for using DCL (to overcome slow speed) is less of an issue (or a non-issue) with newer JVMs.

I am not a Java expert. But enough Java experts have stressed the need to eliminate this anti-pattern that I am willing to take their word for it. I said that in preparation for repeating what Adam said earlier - there are enough potential problems with DCL that it should not be used. I agree that there might be some DCL code in OFBiz that hasn't caused any problems so far, and it might be tempting to think "if it isn't broke, don't fix it" - but personally, I prefer to remove the potential problem.

I have seen DCL used in two circumstances in OFBiz: to lazy load a static field (singleton), and to get elements from a Map.

1. Lazy load a static field
---------------------------

// This is bad, don't do this
public class MyClass {
  private static Resource resource;

  public static Resource getInstance() {
    if (resource == null {
      synchronized (MyClass.class) {
        if (resource == null) {
          resource = new Resource();
        }
      }
    }
    return resource;
  }
}

The easiest fix in this example is to make getInstance() synchronized:

public synchronized static Resource getInstance() {
  if (resource == null {
    resource = new Resource();
  }
  return resource;
}

The lazy load has been preserved, but at a cost of synchronizing every call to getInstance().

It would be better to eliminate the lazy load altogether:

public class MyClass {
  private static Resource resource = new Resource();

  public static Resource getInstance() {
    return resource;
  }
}

2. Get elements from a Map
--------------------------

// This is bad, don't do this
public class MyClass {
  private static Map<String, Resource> resourceMap = FastMap.newInstance();

  public static Resource getResource(String resourceName) {
    Resource resource = resourceMap.get(resourceName);
    if (resource == null {
      synchronized (MyClass.class) {
        resource = resourceMap.get(resourceName);
        if (resource == null) {
          resource = new Resource();
          resourceMap.put(resourceName, resource);
        }
      }
    }
    return resource;
  }
}

Again, the easiest fix is to make the getResource method synchronized:

public synchronized static Resource getResource(String resourceName) {
  Resource resource = resourceMap.get(resourceName);
  if (resource == null {
    resource = new Resource();
    resourceMap.put(resourceName, resource);
  }
  return resource;
}

This fix comes at a cost of synchronizing every call to getResource. If the cost of creating a new instance of Resource is low, we can skip synchronization altogether:

public static Resource getResource(String resourceName) {
  Resource resource = resourceMap.get(resourceName);
  if (resource == null {
    resource = new Resource();
    resourceMap.put(resourceName, resource);
    resource = resourceMap.get(resourceName);
  }
  return resource;
}

Using this method, there is a chance that more than one thread will create a Resource instance, but we are not concerned about that - we just do a second resourceMap.get(resourceName) method call to make sure we have the Resource instance that "won."

-Adrian

--- On Sat, 7/3/10, Jacques Le Roux <ja...@les7arts.com> wrote:

> From: Jacques Le Roux <ja...@les7arts.com>
> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> To: dev@ofbiz.apache.org
> Date: Saturday, July 3, 2010, 4:41 AM
> Very good article indeed. What do we
> learn more in the book about DCL?
> If there is nothing more in the book, I suppose we prefer
> to use the static variable solution in OFBiz?
> 
> Thanks
> 
> Jacques
> 
> From: "Adrian Crum" <ad...@yahoo.com>
> > --- On Fri, 7/2/10, Scott Gray <sc...@hotwaxmedia.com>
> wrote:
> >> The book would have done well to use a more
> complicated
> >> example of why DCL shouldn't be used though. This
> >> article seems to do a better better job of it: http://www.ibm.com/developerworks/java/library/j-dcl.html
> > 
> > That was the article I found a while back - before I
> got the book.
> 
> 


      

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Jacques Le Roux <ja...@les7arts.com>.
Very good article indeed. What do we learn more in the book about DCL?
If there is nothing more in the book, I suppose we prefer to use the static variable solution in OFBiz?

Thanks

Jacques

From: "Adrian Crum" <ad...@yahoo.com>
> --- On Fri, 7/2/10, Scott Gray <sc...@hotwaxmedia.com> wrote:
>> The book would have done well to use a more complicated
>> example of why DCL shouldn't be used though. This
>> article seems to do a better better job of it: http://www.ibm.com/developerworks/java/library/j-dcl.html
> 
> That was the article I found a while back - before I got the book.


Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Adrian Crum <ad...@yahoo.com>.
--- On Fri, 7/2/10, Scott Gray <sc...@hotwaxmedia.com> wrote:
> The book would have done well to use a more complicated
> example of why DCL shouldn't be used though.  This
> article seems to do a better better job of it: http://www.ibm.com/developerworks/java/library/j-dcl.html

That was the article I found a while back - before I got the book.




      

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Scott Gray <sc...@hotwaxmedia.com>.
On 3/07/2010, at 3:54 PM, Adam Heath wrote:

> Scott Gray wrote:
>> On 3/07/2010, at 3:03 PM, Adam Heath wrote:
>> 
>>> Scott Gray wrote:
>>>> On 3/07/2010, at 2:13 PM, Adrian Crum wrote:
>>>> 
>>>>> --- On Fri, 7/2/10, David E Jones <de...@me.com> wrote:
>>>>>> On Jul 2, 2010, at 7:11 PM, Adrian Crum wrote:
>>>>>> 
>>>>>>> Because I've done it myself. ;-)
>>>>>> Wait, do you mean that in this case you did the actual
>>>>>> copying and pasting? Well... I guess that would be one way
>>>>>> to know for sure!
>>>>> Btw, I'm not implying the code Scott is working on was copy-and-paste code - I was just making a generalized statement about where my head is at lately.
>>>>> 
>>>>> When I first got involved with Java, I would copy and paste double-checked-locking code blocks because I assumed they were necessary. I didn't bother to research why they were there. If I had, I would have learned that they don't work and there are better ways to do synchronization. That is only one example of my uninformed copy-and-paste code development - there are more.
>>>> This has always bothered me, as far as I can tell double-checked locking DOES work just fine, the only time it doesn't is when you do the following:
>>>> private static Object object;
>>>> 
>>>> public static Object getObject() {
>>>> if (object == null) {
>>>>   synchronized (Some.class) {
>>>>     if (object == null) {
>>>>       object = new Object();
>>>>     }
>>>>   }
>>>> }
>>>> // potentially not fully initialized!!
>>>> return object;
>>>> }
>>>> 
>>>> But we very rarely use the pattern in that manner.  What we do usually is initialize the object and then in an additional statement we assign it to the variable being checked.  The potential for returning partially initialized objects is the concurrency book's biggest argument against the pattern I don't often see that potential in the ways that OFBiz uses it.
>>>> 
>>>> Regards
>>>> Scott 
>>> ==
>>> if (object = null) {
>>> synchronized(lock) {
>>>   if (object == null) {
>>>      Object foo = getFoo();
>>>      Object bar = getBar();
>>>      object = new Result(foo, bar);
>>>   }
>>> }
>>> }
>>> return object;
>>> 
>>> class Result {
>>> Object foo, bar;
>>> Result(Object foo, Object bar) {
>>>   this.foo = foo;
>>>   this.bar = bar;
>>> }
>>> }
>>> ==
>> 
>> Your example is no different than the one I posted.
>> 
>> Are you trying to say that this won't work:
>> private static Map cache;
>> 
>> public static Object getObject(String key) {
>> if (cache.containsKey(key)) {
>>   synchronized (cache) {
>>     if (cache.containsKey(key) {
>>       Object object = new Object();
>>       cache.put(key, object);
>>     }
>>   }
>> }
>> return object;
>> }
> 
> Object result = cache.get(key);
> if (result == null) {
> 
> If you do a separate containsKey/get, then the cache might have the
> object removed between the two calls.  But that bug has nothing to do
> with DCL.
> 
>> I'm not saying you're wrong, I just want to get an example up of what I assumed would work.  Btw I never said I had read the book, just pieces.
> 
> Yes, that won't work.
> 
> When the new item is being put into the cache, the map may need to get
> resized.  This will cause an internal iteration to occur, while the
> entries are copied into a new set of buckets.  The map will allocate a
> new list of buckets, start walking the old version, putting new
> objects into the right location.  Then, it'll eventually assign the
> new bucket list to the active bucket list.
> 
> The vm is free to reorder the memory assignments, so that the
> allocated bucket array is assigned to the internal list, before the
> items of the array themselves are set.  Then another thread will try
> to access the map, see the newly allocated bucket list, but not find
> any items, because the first thread hasn't copied any yet.
> 
> The only way to protect against this bug is to protect the outer get
> call with a synchronized.
> 
> I suggest you go actually read the book.  It's very deep stuff.

That's fine, I'll take your word and stand corrected.  I actually don't need a nightstand because I'm able to build one out of the stack of great books that are still in queue to be read.
The book would have done well to use a more complicated example of why DCL shouldn't be used though.  This article seems to do a better better job of it: http://www.ibm.com/developerworks/java/library/j-dcl.html

> And yes, I have had to debug problems like this.  I've had to rewrite
> almost all of commons-vfs, because it didn't have proper locking on
> map access, and I had threads enter into a never ending loop.  One
> thread was doing a get while another did a put, and the looping thread
> was stuck inside an  interation(kill -QUIT, and a line number, was
> enough to verify this bug; the fix was more complex of course).


Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Adam Heath <do...@brainfood.com>.
Scott Gray wrote:
> On 3/07/2010, at 3:03 PM, Adam Heath wrote:
> 
>> Scott Gray wrote:
>>> On 3/07/2010, at 2:13 PM, Adrian Crum wrote:
>>>
>>>> --- On Fri, 7/2/10, David E Jones <de...@me.com> wrote:
>>>>> On Jul 2, 2010, at 7:11 PM, Adrian Crum wrote:
>>>>>
>>>>>> Because I've done it myself. ;-)
>>>>> Wait, do you mean that in this case you did the actual
>>>>> copying and pasting? Well... I guess that would be one way
>>>>> to know for sure!
>>>> Btw, I'm not implying the code Scott is working on was copy-and-paste code - I was just making a generalized statement about where my head is at lately.
>>>>
>>>> When I first got involved with Java, I would copy and paste double-checked-locking code blocks because I assumed they were necessary. I didn't bother to research why they were there. If I had, I would have learned that they don't work and there are better ways to do synchronization. That is only one example of my uninformed copy-and-paste code development - there are more.
>>> This has always bothered me, as far as I can tell double-checked locking DOES work just fine, the only time it doesn't is when you do the following:
>>> private static Object object;
>>>
>>> public static Object getObject() {
>>>  if (object == null) {
>>>    synchronized (Some.class) {
>>>      if (object == null) {
>>>        object = new Object();
>>>      }
>>>    }
>>>  }
>>>  // potentially not fully initialized!!
>>>  return object;
>>> }
>>>
>>> But we very rarely use the pattern in that manner.  What we do usually is initialize the object and then in an additional statement we assign it to the variable being checked.  The potential for returning partially initialized objects is the concurrency book's biggest argument against the pattern I don't often see that potential in the ways that OFBiz uses it.
>>>
>>> Regards
>>> Scott 
>> ==
>> if (object = null) {
>>  synchronized(lock) {
>>    if (object == null) {
>>       Object foo = getFoo();
>>       Object bar = getBar();
>>       object = new Result(foo, bar);
>>    }
>>  }
>> }
>> return object;
>>
>> class Result {
>>  Object foo, bar;
>>  Result(Object foo, Object bar) {
>>    this.foo = foo;
>>    this.bar = bar;
>>  }
>> }
>> ==
> 
> Your example is no different than the one I posted.
> 
> Are you trying to say that this won't work:
> private static Map cache;
> 
> public static Object getObject(String key) {
>  if (cache.containsKey(key)) {
>    synchronized (cache) {
>      if (cache.containsKey(key) {
>        Object object = new Object();
>        cache.put(key, object);
>      }
>    }
>  }
>  return object;
> }

Object result = cache.get(key);
if (result == null) {

If you do a separate containsKey/get, then the cache might have the
object removed between the two calls.  But that bug has nothing to do
with DCL.

> I'm not saying you're wrong, I just want to get an example up of what I assumed would work.  Btw I never said I had read the book, just pieces.

Yes, that won't work.

When the new item is being put into the cache, the map may need to get
resized.  This will cause an internal iteration to occur, while the
entries are copied into a new set of buckets.  The map will allocate a
new list of buckets, start walking the old version, putting new
objects into the right location.  Then, it'll eventually assign the
new bucket list to the active bucket list.

The vm is free to reorder the memory assignments, so that the
allocated bucket array is assigned to the internal list, before the
items of the array themselves are set.  Then another thread will try
to access the map, see the newly allocated bucket list, but not find
any items, because the first thread hasn't copied any yet.

The only way to protect against this bug is to protect the outer get
call with a synchronized.

I suggest you go actually read the book.  It's very deep stuff.

And yes, I have had to debug problems like this.  I've had to rewrite
almost all of commons-vfs, because it didn't have proper locking on
map access, and I had threads enter into a never ending loop.  One
thread was doing a get while another did a put, and the looping thread
was stuck inside an  interation(kill -QUIT, and a line number, was
enough to verify this bug; the fix was more complex of course).

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Scott Gray <sc...@hotwaxmedia.com>.
On 3/07/2010, at 3:03 PM, Adam Heath wrote:

> Scott Gray wrote:
>> On 3/07/2010, at 2:13 PM, Adrian Crum wrote:
>> 
>>> --- On Fri, 7/2/10, David E Jones <de...@me.com> wrote:
>>>> On Jul 2, 2010, at 7:11 PM, Adrian Crum wrote:
>>>> 
>>>>> Because I've done it myself. ;-)
>>>> Wait, do you mean that in this case you did the actual
>>>> copying and pasting? Well... I guess that would be one way
>>>> to know for sure!
>>> Btw, I'm not implying the code Scott is working on was copy-and-paste code - I was just making a generalized statement about where my head is at lately.
>>> 
>>> When I first got involved with Java, I would copy and paste double-checked-locking code blocks because I assumed they were necessary. I didn't bother to research why they were there. If I had, I would have learned that they don't work and there are better ways to do synchronization. That is only one example of my uninformed copy-and-paste code development - there are more.
>> 
>> This has always bothered me, as far as I can tell double-checked locking DOES work just fine, the only time it doesn't is when you do the following:
>> private static Object object;
>> 
>> public static Object getObject() {
>>  if (object == null) {
>>    synchronized (Some.class) {
>>      if (object == null) {
>>        object = new Object();
>>      }
>>    }
>>  }
>>  // potentially not fully initialized!!
>>  return object;
>> }
>> 
>> But we very rarely use the pattern in that manner.  What we do usually is initialize the object and then in an additional statement we assign it to the variable being checked.  The potential for returning partially initialized objects is the concurrency book's biggest argument against the pattern I don't often see that potential in the ways that OFBiz uses it.
>> 
>> Regards
>> Scott 
> 
> ==
> if (object = null) {
>  synchronized(lock) {
>    if (object == null) {
>       Object foo = getFoo();
>       Object bar = getBar();
>       object = new Result(foo, bar);
>    }
>  }
> }
> return object;
> 
> class Result {
>  Object foo, bar;
>  Result(Object foo, Object bar) {
>    this.foo = foo;
>    this.bar = bar;
>  }
> }
> ==

Your example is no different than the one I posted.

Are you trying to say that this won't work:
private static Map cache;

public static Object getObject(String key) {
 if (cache.containsKey(key)) {
   synchronized (cache) {
     if (cache.containsKey(key) {
       Object object = new Object();
       cache.put(key, object);
     }
   }
 }
 return object;
}

I'm not saying you're wrong, I just want to get an example up of what I assumed would work.  Btw I never said I had read the book, just pieces.

> 
> This is buggy too, and is a much more common pattern.  In fact, this
> is the only argument needed to remove all DCL patterns.
> 
> When a new object is created, a memory block is allocated.  The
> address of that block is then stored in object.  The memory block is
> then initialized.  The block is not fully initialized until the
> constructor is returned from.
> 
> After the address of the block is stored in the object, then the outer
> conditional thinks the object is no longer null.  This is true.  But
> != null does not mean the object has been initialized yet.
> 
> If you try to assign the new object to a tmp first, then assign to the
> final output, it won't help, because the memory assignment could still
> be reordered.  All memory read/writes that occur inside a synchronized
> block can be reordered in any fashion.  One of those memory accesses
> is the storage of the allocated objects memory address into the
> unprotected object.  If the memory access can be reordered, then it's
> possible that the instances variable assignments could happen after
> the object assignment, which then means the returning of a non-null,
> uninitialized object.
> 
> Yes, it's complex.  If you don't understand my ramblings(the larger
> paragraph), then you need to go back and re-read the concurrency book.
> 


Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Adam Heath <do...@brainfood.com>.
Scott Gray wrote:
> On 3/07/2010, at 2:13 PM, Adrian Crum wrote:
> 
>> --- On Fri, 7/2/10, David E Jones <de...@me.com> wrote:
>>> On Jul 2, 2010, at 7:11 PM, Adrian Crum wrote:
>>>
>>>> Because I've done it myself. ;-)
>>> Wait, do you mean that in this case you did the actual
>>> copying and pasting? Well... I guess that would be one way
>>> to know for sure!
>> Btw, I'm not implying the code Scott is working on was copy-and-paste code - I was just making a generalized statement about where my head is at lately.
>>
>> When I first got involved with Java, I would copy and paste double-checked-locking code blocks because I assumed they were necessary. I didn't bother to research why they were there. If I had, I would have learned that they don't work and there are better ways to do synchronization. That is only one example of my uninformed copy-and-paste code development - there are more.
> 
> This has always bothered me, as far as I can tell double-checked locking DOES work just fine, the only time it doesn't is when you do the following:
> private static Object object;
> 
> public static Object getObject() {
>   if (object == null) {
>     synchronized (Some.class) {
>       if (object == null) {
>         object = new Object();
>       }
>     }
>   }
>   // potentially not fully initialized!!
>   return object;
> }
> 
> But we very rarely use the pattern in that manner.  What we do usually is initialize the object and then in an additional statement we assign it to the variable being checked.  The potential for returning partially initialized objects is the concurrency book's biggest argument against the pattern I don't often see that potential in the ways that OFBiz uses it.
> 
> Regards
> Scott 

==
if (object = null) {
  synchronized(lock) {
    if (object == null) {
       Object foo = getFoo();
       Object bar = getBar();
       object = new Result(foo, bar);
    }
  }
}
return object;

class Result {
  Object foo, bar;
  Result(Object foo, Object bar) {
    this.foo = foo;
    this.bar = bar;
  }
}
==

This is buggy too, and is a much more common pattern.  In fact, this
is the only argument needed to remove all DCL patterns.

When a new object is created, a memory block is allocated.  The
address of that block is then stored in object.  The memory block is
then initialized.  The block is not fully initialized until the
constructor is returned from.

After the address of the block is stored in the object, then the outer
conditional thinks the object is no longer null.  This is true.  But
!= null does not mean the object has been initialized yet.

If you try to assign the new object to a tmp first, then assign to the
final output, it won't help, because the memory assignment could still
be reordered.  All memory read/writes that occur inside a synchronized
block can be reordered in any fashion.  One of those memory accesses
is the storage of the allocated objects memory address into the
unprotected object.  If the memory access can be reordered, then it's
possible that the instances variable assignments could happen after
the object assignment, which then means the returning of a non-null,
uninitialized object.

Yes, it's complex.  If you don't understand my ramblings(the larger
paragraph), then you need to go back and re-read the concurrency book.


Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Scott Gray <sc...@hotwaxmedia.com>.
On 3/07/2010, at 2:13 PM, Adrian Crum wrote:

> --- On Fri, 7/2/10, David E Jones <de...@me.com> wrote:
>> On Jul 2, 2010, at 7:11 PM, Adrian Crum wrote:
>> 
>>> Because I've done it myself. ;-)
>> 
>> Wait, do you mean that in this case you did the actual
>> copying and pasting? Well... I guess that would be one way
>> to know for sure!
> 
> Btw, I'm not implying the code Scott is working on was copy-and-paste code - I was just making a generalized statement about where my head is at lately.
> 
> When I first got involved with Java, I would copy and paste double-checked-locking code blocks because I assumed they were necessary. I didn't bother to research why they were there. If I had, I would have learned that they don't work and there are better ways to do synchronization. That is only one example of my uninformed copy-and-paste code development - there are more.

This has always bothered me, as far as I can tell double-checked locking DOES work just fine, the only time it doesn't is when you do the following:
private static Object object;

public static Object getObject() {
  if (object == null) {
    synchronized (Some.class) {
      if (object == null) {
        object = new Object();
      }
    }
  }
  // potentially not fully initialized!!
  return object;
}

But we very rarely use the pattern in that manner.  What we do usually is initialize the object and then in an additional statement we assign it to the variable being checked.  The potential for returning partially initialized objects is the concurrency book's biggest argument against the pattern I don't often see that potential in the ways that OFBiz uses it.

Regards
Scott 

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Adrian Crum <ad...@yahoo.com>.
--- On Fri, 7/2/10, David E Jones <de...@me.com> wrote:
> On Jul 2, 2010, at 7:11 PM, Adrian Crum wrote:
> 
> > Because I've done it myself. ;-)
> 
> Wait, do you mean that in this case you did the actual
> copying and pasting? Well... I guess that would be one way
> to know for sure!

Btw, I'm not implying the code Scott is working on was copy-and-paste code - I was just making a generalized statement about where my head is at lately.

When I first got involved with Java, I would copy and paste double-checked-locking code blocks because I assumed they were necessary. I didn't bother to research why they were there. If I had, I would have learned that they don't work and there are better ways to do synchronization. That is only one example of my uninformed copy-and-paste code development - there are more.

So, based on my own experience I tend to look at code with a bit of skepticism. Did the author really intend to use this algorithm/class/pattern, or was it just copied from somewhere else without considering if it is the most appropriate way to do things?

> > I agree that code can look redundant and not be copy
> and paste. The obvious ones are easy to spot because...
> well... they're *obvious*.
> 
> It's a great effort to refactor code and reduce it's size
> and redundancy. IMO that sort of effort is even more bang
> for the buck than automated testing for reducing bugs, and
> both developer and user experience with the stuff.

Plus, it makes code easier to maintain. If a code snippet that has been copied-and-pasted contains a bug, then you have to fix that bug in multiple places. The same is true with adding a feature to the code snippet.

> On the other hand, there is such a thing as too much
> parameterization that results in code that is more
> complicated and difficult to maintain than an alternative
> that might seem more redundant. I heard this put a funny way
> once, something like: if you start getting a nagging feeling
> that you are creating an alternative to a programming
> language in order to handle a specific business case then
> you've already crossed the line. ;)

Personally, I haven't experienced that nagging feeling.

I have run into a situation where eliminating redundancy became a problem later on. If I see a set of related classes that all contain the same methods, I will create a base class that contains those methods and make the related classes subclasses of the base class. Not only have I reduced code, but now I can add features to a whole set of classes just by adding them to the base class. As time goes on though, some of the subclasses start suffering from limitations imposed by the base class.

So, there are trade-offs.


> -David
> 
> > --- On Fri, 7/2/10, David E Jones <de...@me.com>
> wrote:
> > 
> >> From: David E Jones <de...@me.com>
> >> Subject: Re: svn commit: r959875 -
> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >> To: dev@ofbiz.apache.org
> >> Date: Friday, July 2, 2010, 5:44 PM
> >> 
> >> How do you know it was copy and paste?
> >> 
> >> It could very well have been different code
> written by
> >> different people and at different times, possibly
> even with
> >> no reference to the other code. Redundant similar
> code is
> >> annoying and nice to eliminate, but it's existence
> does not
> >> imply copy/paste, or even necessarily awareness of
> the other
> >> code.
> >> 
> >> -David
> >> 
> >> 
> >> On Jul 2, 2010, at 1:18 AM, Adrian Crum wrote:
> >> 
> >>> My new mantra: Just say no to copy and paste.
> >>> 
> >>> I'm questioning nearly all of the code I come
> across.
> >>> 
> >>> -Adrian
> >>> 
> >>> 
> >>> --- On Thu, 7/1/10, Scott Gray <sc...@hotwaxmedia.com>
> >> wrote:
> >>> 
> >>>> From: Scott Gray <sc...@hotwaxmedia.com>
> >>>> Subject: Re: svn commit: r959875 -
> >>
> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>> To: dev@ofbiz.apache.org
> >>>> Date: Thursday, July 1, 2010, 11:58 PM
> >>>> Yeah no worries.  I'd never
> >>>> really thought about it before until
> yesterday
> >> when I came
> >>>> across a problem in the
> >> ModelMenuAction.PropertyMap action,
> >>>> it replaces the existing uiLabelMap
> instead of
> >> adding to it
> >>>> like the ModelScreenAction version does. 
> >> Option was to
> >>>> either just copy and paste the screen
> version or
> >> take the
> >>>> plunge and sort it all out.
> >>>> 
> >>>> Regards
> >>>> Scott
> >>>> 
> >>>> On 2/07/2010, at 6:45 PM, Adrian Crum
> wrote:
> >>>> 
> >>>>> Thanks! That duplication always
> bothered me.
> >>>>> 
> >>>>> -Adrian
> >>>>> 
> >>>>> --- On Thu, 7/1/10, lektran@apache.org
> >>>> <le...@apache.org>
> >>>> wrote:
> >>>>> 
> >>>>>> From: lektran@apache.org
> >>>> <le...@apache.org>
> >>>>>> Subject: svn commit: r959875 -
> >>>> 
> >>
> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>>>> To: commits@ofbiz.apache.org
> >>>>>> Date: Thursday, July 1, 2010,
> 11:38 PM
> >>>>>> Author: lektran
> >>>>>> Date: Fri Jul  2 06:38:52
> 2010
> >>>>>> New Revision: 959875
> >>>>>> 
> >>>>>> URL: http://svn.apache.org/viewvc?rev=959875&view=rev
> >>>>>> Log:
> >>>>>> Added a new class
> ModelWidgetAction which
> >> will
> >>>> serve to
> >>>>>> replace the duplicate classes
> >> ModelScreenAction,
> >>>>>> ModelFormAction and
> ModelMenuAction. 
> >> This
> >>>> class is
> >>>>>> virtually a direct copy of
> >> ModelScreenAction and
> >>>> its
> >>>>>> subclasses.  I'll work over
> the
> >> weekend to
> >>>> switch the
> >>>>>> existing classes to extend from
> >> ModelWidgetAction,
> >>>> remove
> >>>>>> their methods and then deprecate
> the
> >> shells that
> >>>> are left
> >>>>>> behind.
> >>>>>> 
> >>>>>> Added:
> >>>>>>      
> >>>>>> 
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java   (with
> >>>>>> props)
> >>>>>> 
> >>>>>> Added:
> >>>>>> 
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java?rev=959875&view=auto
> >>>>>> 
> >>>> 
> >>
> ==============================================================================
> >>>>>> ---
> >>>>>> 
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>>>> (added)
> >>>>>> +++
> >>>>>> 
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>>>> Fri Jul  2 06:38:52 2010
> >>>>>> @@ -0,0 +1,700 @@
> >>>>>> 
> >>>> 
> >>
> +/*******************************************************************************
> >>>>>> + * 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;
> >>>>>> +
> >>>>>> +import java.io.Serializable;
> >>>>>> +import java.text.MessageFormat;
> >>>>>> +import java.util.ArrayList;
> >>>>>> +import java.util.List;
> >>>>>> +import java.util.Locale;
> >>>>>> +import java.util.Map;
> >>>>>> +import java.util.TimeZone;
> >>>>>> +import
> >> java.util.regex.PatternSyntaxException;
> >>>>>> +
> >>>>>> +import
> javax.servlet.ServletContext;
> >>>>>> +import
> javax.servlet.http.HttpSession;
> >>>>>> +
> >>>>>> +import javolution.util.FastList;
> >>>>>> +import javolution.util.FastMap;
> >>>>>> +
> >>>>>> +import org.w3c.dom.Element;
> >>>>>> +import
> >>>>
> org.codehaus.groovy.runtime.InvokerHelper;
> >>>>>> +import
> org.ofbiz.base.util.BshUtil;
> >>>>>> +import
> org.ofbiz.base.util.Debug;
> >>>>>> +import
> >> org.ofbiz.base.util.GeneralException;
> >>>>>> +import
> org.ofbiz.base.util.GroovyUtil;
> >>>>>> +import
> org.ofbiz.base.util.ObjectType;
> >>>>>> +import
> org.ofbiz.base.util.StringUtil;
> >>>>>> +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.collections.FlexibleMapAccessor;
> >>>>>> +import
> >>>>>> 
> >>>> 
> >>
> org.ofbiz.base.util.collections.ResourceBundleMapWrapper;
> >>>>>> +import
> >>>> 
> >>
> org.ofbiz.base.util.string.FlexibleStringExpander;
> >>>>>> +import
> >> org.ofbiz.entity.GenericEntityException;
> >>>>>> +import
> org.ofbiz.entity.GenericValue;
> >>>>>> +import
> >> org.ofbiz.entity.finder.ByAndFinder;
> >>>>>> +import
> >>>>
> org.ofbiz.entity.finder.ByConditionFinder;
> >>>>>> +import
> >> org.ofbiz.entity.finder.EntityFinderUtil;
> >>>>>> +import
> >> org.ofbiz.entity.finder.PrimaryKeyFinder;
> >>>>>> +import
> >> org.ofbiz.minilang.MiniLangException;
> >>>>>> +import
> org.ofbiz.minilang.SimpleMethod;
> >>>>>> +import
> >> org.ofbiz.minilang.method.MethodContext;
> >>>>>> +import
> >> org.ofbiz.service.DispatchContext;
> >>>>>> +import
> >>>>
> org.ofbiz.service.GenericServiceException;
> >>>>>> +import
> org.ofbiz.service.ModelService;
> >>>>>> +
> >>>>>> +@SuppressWarnings("serial")
> >>>>>> +public abstract class
> ModelWidgetAction
> >>>> implements
> >>>>>> Serializable {
> >>>>>> +    public static final
> String
> >> module
> >>>> =
> >>>>>>
> ModelWidgetAction.class.getName();
> >>>>>> +
> >>>>>> +    protected
> ModelWidget
> >> modelWidget;
> >>>>>> +
> >>>>>> +    protected
> >> ModelWidgetAction() {}
> >>>>>> +
> >>>>>> +    public
> >>>> ModelWidgetAction(ModelWidget
> >>>>>> modelWidget, Element
> actionElement) {
> >>>>>> +       
> >> this.modelWidget =
> >>>>>> modelWidget;
> >>>>>> +        if
> >>>> (Debug.verboseOn())
> >>>>>> Debug.logVerbose("Reading widget
> action
> >> with name:
> >>>> " +
> >>>>>> actionElement.getNodeName(),
> module);
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public abstract
> void
> >>>>>> runAction(Map<String,
> Object>
> >> context)
> >>>> throws
> >>>>>> GeneralException;
> >>>>>> +
> >>>>>> +    public static
> >>>> List<ModelWidgetAction>
> >>>>>> readSubActions(ModelWidget
> modelWidget,
> >> Element
> >>>>>> parentElement) {
> >>>>>> +       
> >>>> List<ModelWidgetAction>
> >>>>>> actions = FastList.newInstance();
> >>>>>> +
> >>>>>> +       
> List<?
> >> extends
> >>>> Element>
> >>>>>> actionElementList =
> >>>>>>
> UtilXml.childElementList(parentElement);
> >>>>>> +        for
> (Element
> >>>> actionElement:
> >>>>>> actionElementList) {
> >>>>>> +       
>    
> >> if
> >>>>>> 
> >> ("set".equals(actionElement.getNodeName())) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> actions.add(new
> SetField(modelWidget,
> >>>> actionElement));
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> 
> >>>> 
> >>
> ("property-map".equals(actionElement.getNodeName())) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> actions.add(new
> PropertyMap(modelWidget,
> >>>> actionElement));
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> 
> >>>> 
> >>
> ("property-to-field".equals(actionElement.getNodeName())) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> actions.add(new
> >> PropertyToField(modelWidget,
> >>>>>> actionElement));
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> 
> >> ("script".equals(actionElement.getNodeName())) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> actions.add(new
> Script(modelWidget,
> >>>> actionElement));
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> 
> >> ("service".equals(actionElement.getNodeName())) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> actions.add(new
> Service(modelWidget,
> >>>> actionElement));
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> 
> >>
> ("entity-one".equals(actionElement.getNodeName()))
> >>>> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> actions.add(new
> EntityOne(modelWidget,
> >>>> actionElement));
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> 
> >>
> ("entity-and".equals(actionElement.getNodeName()))
> >>>> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> actions.add(new
> EntityAnd(modelWidget,
> >>>> actionElement));
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> 
> >>>> 
> >>
> ("entity-condition".equals(actionElement.getNodeName())) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> actions.add(new
> >> EntityCondition(modelWidget,
> >>>>>> actionElement));
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> 
> >>>> 
> >>
> ("get-related-one".equals(actionElement.getNodeName())) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> actions.add(new
> >> GetRelatedOne(modelWidget,
> >>>> actionElement));
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> 
> >>>> 
> >>
> ("get-related".equals(actionElement.getNodeName())) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> actions.add(new
> GetRelated(modelWidget,
> >>>> actionElement));
> >>>>>> +       
>    
> >> } else
> >>>> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> IllegalArgumentException("Action
> >> element
> >>>> not
> >>>>>> supported with name: " +
> >>>> actionElement.getNodeName());
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> return
> >> actions;
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static void
> >>>>>> 
> >> runSubActions(List<ModelWidgetAction>
> >>>> actions,
> >>>>>> Map<String, Object> context)
> throws
> >>>> GeneralException
> >>>>>> {
> >>>>>> +        if
> (actions
> >> == null)
> >>>> return;
> >>>>>> +
> >>>>>> +        for
> >>>> (ModelWidgetAction action:
> >>>>>> actions) {
> >>>>>> +       
>    
> >> if
> >>>>>> (Debug.verboseOn())
> >> Debug.logVerbose("Running
> >>>> widget action
> >>>>>> " + action.getClass().getName(),
> module);
> >>>>>> +       
> >>    
> >>>>>> action.runAction(context);
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static
> class
> >> SetField
> >>>> extends
> >>>>>> ModelWidgetAction {
> >>>>>> +       
> protected
> >>>>>> FlexibleMapAccessor<Object>
> field;
> >>>>>> +       
> protected
> >>>>>> FlexibleMapAccessor<Object>
> >> fromField;
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander valueExdr;
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander
> defaultExdr;
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander
> globalExdr;
> >>>>>> +       
> protected
> >> String
> >>>> type;
> >>>>>> +       
> protected
> >> String
> >>>> toScope;
> >>>>>> +       
> protected
> >> String
> >>>> fromScope;
> >>>>>> +
> >>>>>> +       
> public
> >>>> SetField(ModelWidget
> >>>>>> modelWidget, Element setElement)
> {
> >>>>>> +       
>    
> >> super
> >>>>>> (modelWidget, setElement);
> >>>>>> +       
> >>    
> >>>> this.field =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
> >>>>>> +       
> >>    
> >>>> this.fromField =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("from-field"));
> >>>>>> +       
> >>    
> >>>> this.valueExdr =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("value"));
> >>>>>> +       
> >>    
> >>>> this.defaultExdr
> >>>>>> =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("default-value"));
> >>>>>> +       
> >>    
> >>>> this.globalExdr
> >>>>>> =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> >>>>>> +       
> >>    
> >>>> this.type =
> >>>>>> setElement.getAttribute("type");
> >>>>>> +       
> >>    
> >>>> this.toScope =
> >>>>>>
> setElement.getAttribute("to-scope");
> >>>>>> +       
> >>    
> >>>> this.fromScope =
> >>>>>>
> setElement.getAttribute("from-scope");
> >>>>>> +       
>    
> >> if
> >>>>>> (!this.fromField.isEmpty()
> &&
> >>>>>> !this.valueExdr.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> IllegalArgumentException("Cannot
> >> specify
> >>>> a
> >>>>>> from-field [" +
> >>>> setElement.getAttribute("from-field") +
> "]
> >>>>>> and a value [" +
> >> setElement.getAttribute("value")
> >>>> + "] on
> >>>>>> the set action in a widget");
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> @Override
> >>>>>> +       
> public void
> >>>>>> runAction(Map<String,
> Object>
> >> context) {
> >>>>>> +       
>    
> >> String
> >>>> globalStr
> >>>>>> =
> this.globalExdr.expandString(context);
> >>>>>> +       
>    
> >> //
> >>>> default to
> >>>>>> false
> >>>>>> +       
>    
> >> boolean
> >>>> global =
> >>>>>> "true".equals(globalStr);
> >>>>>> +
> >>>>>> +       
>    
> >> Object
> >>>> newValue
> >>>>>> = null;
> >>>>>> +       
>    
> >> if
> >>>>>> (this.fromScope != null
> &&
> >>>>>> this.fromScope.equals("user")) {
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (!this.fromField.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    HttpSession session =
> >>>> (HttpSession)
> >>>>>> context.get("session");
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newValue =
> >>>>>>
> getInMemoryPersistedFromField(session,
> >> context);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       if
> >> (Debug.verboseOn())
> >>>> Debug.logVerbose("In
> >>>>>> user getting value for field from
> [" +
> >>>>>> this.fromField.getOriginalName() +
> "]: "
> >> +
> >>>> newValue,
> >>>>>> module);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else if
> (!this.valueExdr.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newValue =
> >>>> this.valueExdr.expand(context);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> (this.fromScope != null
> &&
> >>>>>>
> this.fromScope.equals("application")) {
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (!this.fromField.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    ServletContext
> >>>> servletContext =
> >>>>>> (ServletContext)
> >> context.get("application");
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newValue =
> >>>>>> 
> >> getInMemoryPersistedFromField(servletContext,
> >>>> context);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       if
> >> (Debug.verboseOn())
> >>>> Debug.logVerbose("In
> >>>>>> application getting value for
> field from
> >> [" +
> >>>>>> this.fromField.getOriginalName() +
> "]: "
> >> +
> >>>> newValue,
> >>>>>> module);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else if
> (!this.valueExdr.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newValue =
> >>>>>>
> this.valueExdr.expandString(context);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> } else
> >>>> {
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (!this.fromField.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newValue =
> >>>> this.fromField.get(context);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       if
> >> (Debug.verboseOn())
> >>>>>> Debug.logVerbose("Getting value
> for field
> >> from ["
> >>>> +
> >>>>>> this.fromField.getOriginalName() +
> "]: "
> >> +
> >>>> newValue,
> >>>>>> module);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else if
> (!this.valueExdr.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newValue =
> >>>> this.valueExdr.expand(context);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>>>> +
> >>>>>> +       
>    
> >> // If
> >>>> newValue
> >>>>>> is still empty, use the default
> value
> >>>>>> +       
>    
> >> if
> >>>>>> (ObjectType.isEmpty(newValue)
> &&
> >>>>>> !this.defaultExdr.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> newValue =
> >> this.defaultExdr.expand(context);
> >>>>>> +       
>    
> >> }
> >>>>>> +
> >>>>>> +       
>    
> >> if
> >>>>>>
> (UtilValidate.isNotEmpty(this.type)) {
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> ("NewMap".equals(this.type)) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newValue =
> >>>> FastMap.newInstance();
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else if
> ("NewList".equals(this.type)) {
> >>>>>> +       
> >>    
> > 
> >>>>     
> >>>>>>   
>    newValue =
> >>>> FastList.newInstance();
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       try
> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    newValue
> >> =
> >>>>>>
> ObjectType.simpleTypeConvert(newValue,
> >> this.type,
> >>>> null,
> >>>>>> (TimeZone)
> context.get("timeZone"),
> >> (Locale)
> >>>>>> context.get("locale"), true);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       }
> catch
> >> (GeneralException
> >>>> e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    String
> >>>> errMsg = "Could not
> >>>>>> convert field value for the field:
> [" +
> >>>>>> this.field.getOriginalName() + "]
> to the
> >> [" +
> >>>> this.type + "]
> >>>>>> type for the value [" + newValue +
> "]: "
> >> +
> >>>> e.toString();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
> >>>>     Debug.logError(e,
> errMsg,
> >>>>>> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    throw
> >> new
> >>>>>> IllegalArgumentException(errMsg);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       }
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>>>> +
> >>>>>> +       
>    
> >> if
> >>>> (this.toScope
> >>>>>> != null &&
> >> this.toScope.equals("user")) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String originalName =
> >>>> this.field.getOriginalName();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> List<String>
> currentWidgetTrail =
> >>>>>> 
> >>>> 
> >>
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String newKey = "";
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (currentWidgetTrail != null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newKey =
> >>>> StringUtil.join(currentWidgetTrail,
> >>>>>> "|");
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (UtilValidate.isNotEmpty(newKey))
> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newKey += "|";
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> newKey += originalName;
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> HttpSession session =
> >>>> (HttpSession)context.get("session");
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> session.setAttribute(newKey,
> newValue);
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (Debug.verboseOn())
> Debug.logVerbose("In
> >> user
> >>>> setting value
> >>>>>> for field from [" +
> >> this.field.getOriginalName() +
> >>>> "]: " +
> >>>>>> newValue, module);
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> (this.toScope != null &&
> >>>>>>
> this.toScope.equals("application")) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String originalName =
> >>>> this.field.getOriginalName();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> List<String>
> currentWidgetTrail =
> >>>>>> 
> >>>> 
> >>
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String newKey = "";
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (currentWidgetTrail != null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newKey =
> >>>> StringUtil.join(currentWidgetTrail,
> >>>>>> "|");
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (UtilValidate.isNotEmpty(newKey))
> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newKey += "|";
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> newKey += originalName;
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> ServletContext servletContext =
> >>>>>> 
> >> (ServletContext)context.get("application");
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>
> servletContext.setAttribute(newKey,
> >> newValue);
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (Debug.verboseOn())
> Debug.logVerbose("In
> >>>> application setting
> >>>>>> value for field from [" +
> >>>> this.field.getOriginalName() + "]:
> >>>>>> " + newValue, module);
> >>>>>> +       
>    
> >> } else
> >>>> {
> >>>>>> +     
>    
> >>    
> >>>>    //
> >>>>>> only do this if it is not global,
> if
> >> global ONLY
> >>>> put it in
> >>>>>> the global context
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (!global) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       if
> >> (Debug.verboseOn())
> >>>>>> Debug.logVerbose("Setting field ["
> +
> >>>>>> this.field.getOriginalName() + "]
> to
> >> value: " +
> >>>> newValue,
> >>>>>> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>      
> >> this.field.put(context,
> >>>> newValue);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>>>> +
> >>>>>> +       
>    
> >> if
> >>>> (global) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Map<String, Object>
> globalCtx =
> >>>>>> 
> >>>> 
> >>
> UtilGenerics.checkMap(context.get("globalContext"));
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (globalCtx != null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>      
> >> this.field.put(globalCtx,
> >>>> newValue);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>      
> >> this.field.put(context,
> >>>> newValue);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>>>> +
> >>>>>> +       
>    
> >> // this
> >>>> is a
> >>>>>> hack for backward compatibility
> with the
> >> JPublish
> >>>> page
> >>>>>> object
> >>>>>> +       
> >>    
> >>>> Map<String,
> >>>>>> Object> page =
> >>>>>> 
> >> UtilGenerics.checkMap(context.get("page"));
> >>>>>> +       
>    
> >> if
> >>>> (page !=
> >>>>>> null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> this.field.put(page, newValue);
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> public
> >> Object
> >>>>>>
> getInMemoryPersistedFromField(Object
> >> storeAgent,
> >>>>>> Map<String, Object> context)
> {
> >>>>>> +       
>    
> >> Object
> >>>> newValue
> >>>>>> = null;
> >>>>>> +       
>    
> >> String
> >>>>>> originalName =
> >> this.fromField.getOriginalName();
> >>>>>> +       
> >>    
> >>>>>> List<String>
> currentWidgetTrail =
> >>>>>> 
> >>>> 
> >>
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> >>>>>> +       
> >>    
> >>>>>> List<String> trailList =
> new
> >>>>>> ArrayList<String>();
> >>>>>> +       
>    
> >> if
> >>>>>> (currentWidgetTrail != null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>
> trailList.addAll(currentWidgetTrail);
> >>>>>> +       
>    
> >> }
> >>>>>> +
> >>>>>> +       
>    
> >> for
> >>>> (int
> >>>>>> i=trailList.size(); i >= 0;
> i--) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> List<String> subTrail =
> >>>> trailList.subList(0,i);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String newKey = null;
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (subTrail.size() > 0)
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newKey =
> >>>> StringUtil.join(subTrail, "|") + "|"
> >>>>>> + originalName;
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> else
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newKey =
> >> originalName;
> >>>>>> +
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (storeAgent instanceof
> ServletContext) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newValue =
> >>>>>> 
> >>>> 
> >>
> ((ServletContext)storeAgent).getAttribute(newKey);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else if (storeAgent instanceof
> >> HttpSession) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    newValue =
> >>>>>> 
> >> ((HttpSession)storeAgent).getAttribute(newKey);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (newValue != null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    break;
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>>>> +       
>    
> >> return
> >>>>>> newValue;
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static
> class
> >> PropertyMap
> >>>> extends
> >>>>>> ModelWidgetAction {
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander
> resourceExdr;
> >>>>>> +       
> protected
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor<ResourceBundleMapWrapper>
> >>>>>> mapNameAcsr;
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander
> globalExdr;
> >>>>>> +
> >>>>>> +       
> public
> >>>> PropertyMap(ModelWidget
> >>>>>> modelWidget, Element setElement)
> {
> >>>>>> +       
>    
> >> super
> >>>>>> (modelWidget, setElement);
> >>>>>> +       
> >>    
> >>>>>> this.resourceExdr =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
> >>>>>> +       
> >>    
> >>>> this.mapNameAcsr
> >>>>>> =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("map-name"));
> >>>>>> +       
> >>    
> >>>> this.globalExdr
> >>>>>> =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> @Override
> >>>>>> +       
> public void
> >>>>>> runAction(Map<String,
> Object>
> >> context) {
> >>>>>> +       
>    
> >> String
> >>>> globalStr
> >>>>>> =
> this.globalExdr.expandString(context);
> >>>>>> +       
>    
> >> //
> >>>> default to
> >>>>>> false
> >>>>>> +       
>    
> >> boolean
> >>>> global =
> >>>>>> "true".equals(globalStr);
> >>>>>> +
> >>>>>> +       
>    
> >> Locale
> >>>> locale =
> >>>>>> (Locale) context.get("locale");
> >>>>>> +       
>    
> >> String
> >>>> resource
> >>>>>> =
> this.resourceExdr.expandString(context,
> >>>> locale);
> >>>>>> +
> >>>>>> +       
> >>    
> >>>>>> ResourceBundleMapWrapper
> existingPropMap
> >> =
> >>>>>> this.mapNameAcsr.get(context);
> >>>>>> +       
>    
> >> if
> >>>>>> (existingPropMap == null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> this.mapNameAcsr.put(context,
> >>>>>> 
> >> UtilProperties.getResourceBundleMap(resource,
> >>>> locale,
> >>>>>> context));
> >>>>>> +       
>    
> >> } else
> >>>> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> try {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>      
> >>>>>> 
> >>>> 
> >>
> existingPropMap.addBottomResourceBundle(resource);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> catch (IllegalArgumentException e)
> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       //
> log the error, but
> >>>> don't let it kill
> >>>>>> everything just for a typo or bad
> char in
> >> an l10n
> >>>> file
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    Debug.logError(e,
> >> "Error
> >>>> adding resource
> >>>>>> bundle [" + resource + "]: " +
> >> e.toString(),
> >>>> module);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>>>> +
> >>>>>> +       
>    
> >> if
> >>>> (global) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Map<String, Object>
> globalCtx =
> >>>>>> 
> >>>> 
> >>
> UtilGenerics.checkMap(context.get("globalContext"));
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (globalCtx != null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>      
> >> ResourceBundleMapWrapper
> >>>> globalExistingPropMap
> >>>>>> =
> this.mapNameAcsr.get(globalCtx);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       if
> >> (globalExistingPropMap
> >>>> == null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
> >>>> 
>    this.mapNameAcsr.put(globalCtx,
> >>>>>> 
> >> UtilProperties.getResourceBundleMap(resource,
> >>>> locale,
> >>>>>> context));
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       }
> else {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    // is it
> >> the
> >>>> same object? if not
> >>>>>> add it in here too...
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    if
> >>>> (existingPropMap !=
> >>>>>> globalExistingPropMap) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    
> >>>>     try {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>         
>   
> >>   
> >>>>    
> >>>>>> 
> >>>> 
> >>
> globalExistingPropMap.addBottomResourceBundle(resource);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    
> >>>>     } catch
> >>>>>> (IllegalArgumentException e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>         
>   
> >>   
> >>>>     //
> >>>>>> log the error, but don't let it
> kill
> >> everything
> >>>> just for a
> >>>>>> typo or bad char in an l10n file
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>         
>   
> >>   
> >>>>    
> >>>>>> Debug.logError(e, "Error adding
> resource
> >> bundle ["
> >>>> +
> >>>>>> resource + "]: " + e.toString(),
> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    
> >>>>     }
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    }
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       }
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static
> class
> >> PropertyToField
> >>>> extends
> >>>>>> ModelWidgetAction {
> >>>>>> +
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander
> resourceExdr;
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander
> propertyExdr;
> >>>>>> +       
> protected
> >>>>>> FlexibleMapAccessor<Object>
> >> fieldAcsr;
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander
> defaultExdr;
> >>>>>> +       
> protected
> >> boolean
> >>>> noLocale;
> >>>>>> +       
> protected
> >>>>>> FlexibleMapAccessor<List<?
> extends
> >>>> Object>>
> >>>>>> argListAcsr;
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander
> globalExdr;
> >>>>>> +
> >>>>>> +       
> public
> >>>>>> PropertyToField(ModelWidget
> modelWidget,
> >> Element
> >>>> setElement)
> >>>>>> {
> >>>>>> +       
>    
> >> super
> >>>>>> (modelWidget, setElement);
> >>>>>> +       
> >>    
> >>>>>> this.resourceExdr =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
> >>>>>> +       
> >>    
> >>>>>> this.propertyExdr =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
> >>>>>> +       
> >>    
> >>>> this.fieldAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
> >>>>>> +       
> >>    
> >>>> this.defaultExdr
> >>>>>> =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("default"));
> >>>>>> +       
> >>    
> >>>> this.noLocale =
> >>>>>> 
> >>>> 
> >>
> "true".equals(setElement.getAttribute("no-locale"));
> >>>>>> +       
> >>    
> >>>> this.argListAcsr
> >>>>>> =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("arg-list-name"));
> >>>>>> +       
> >>    
> >>>> this.globalExdr
> >>>>>> =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> @Override
> >>>>>> +       
> public void
> >>>>>> runAction(Map<String,
> Object>
> >> context) {
> >>>>>> +       
> >>    
> >>>> //String
> >>>>>> globalStr =
> >>>> this.globalExdr.expandString(context);
> >>>>>> +       
>    
> >> //
> >>>> default to
> >>>>>> false
> >>>>>> +       
> >>    
> >>>> //boolean global
> >>>>>> = "true".equals(globalStr);
> >>>>>> +
> >>>>>> +       
>    
> >> Locale
> >>>> locale =
> >>>>>> (Locale) context.get("locale");
> >>>>>> +       
>    
> >> String
> >>>> resource
> >>>>>> =
> this.resourceExdr.expandString(context,
> >>>> locale);
> >>>>>> +       
>    
> >> String
> >>>> property
> >>>>>> =
> this.propertyExdr.expandString(context,
> >>>> locale);
> >>>>>> +
> >>>>>> +       
>    
> >> String
> >>>> value =
> >>>>>> null;
> >>>>>> +       
>    
> >> if
> >>>> (noLocale) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> value =
> >> UtilProperties.getPropertyValue(resource,
> >>>>>> property);
> >>>>>> +       
>    
> >> } else
> >>>> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> value =
> >> UtilProperties.getMessage(resource,
> >>>> property,
> >>>>>> locale);
> >>>>>> +       
>    
> >> }
> >>>>>> +       
>    
> >> if
> >>>>>> (UtilValidate.isEmpty(value)) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> value =
> >> this.defaultExdr.expandString(context);
> >>>>>> +       
>    
> >> }
> >>>>>> +
> >>>>>> +       
>    
> >> // note
> >>>> that
> >>>>>> expanding the value string here
> will
> >> handle
> >>>> defaultValue and
> >>>>>> the string from
> >>>>>> +       
> >>    
> >>>> //  the
> >>>>>> properties file; if we decide
> later that
> >> we don't
> >>>> want the
> >>>>>> string from the properties
> >>>>>> +       
> >>    
> >>>> //  file to
> >>>>>> be expanded we should just expand
> the
> >> defaultValue
> >>>> at the
> >>>>>> beginning of this method.
> >>>>>> +       
>    
> >> value
> >>>> =
> >>>>>> 
> >> FlexibleStringExpander.expandString(value,
> >>>> context);
> >>>>>> +
> >>>>>> +       
>    
> >> if
> >>>>>> (!argListAcsr.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> List<? extends Object>
> argList =
> >>>>>> argListAcsr.get(context);
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (UtilValidate.isNotEmpty(argList))
> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    value =
> >>>> MessageFormat.format(value,
> >>>>>> argList.toArray());
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>>>> +       
> >>    
> >>>>>> fieldAcsr.put(context, value);
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static class
> Script
> >> extends
> >>>>>> ModelWidgetAction {
> >>>>>> +       
> protected
> >> static
> >>>> final
> >>>>>> Object[] EMPTY_ARGS = {};
> >>>>>> +       
> protected
> >> String
> >>>> location;
> >>>>>> +       
> protected
> >> String
> >>>> method;
> >>>>>> +
> >>>>>> +       
> public
> >>>> Script(ModelWidget
> >>>>>> modelWidget, Element
> scriptElement) {
> >>>>>> +       
>    
> >> super
> >>>>>> (modelWidget, scriptElement);
> >>>>>> +       
>    
> >> String
> >>>>>> scriptLocation =
> >>>> scriptElement.getAttribute("location");
> >>>>>> +       
> >>    
> >>>> this.location =
> >>>>>> 
> >> WidgetWorker.getScriptLocation(scriptLocation);
> >>>>>> +       
> >>    
> >>>> this.method =
> >>>>>> 
> >> WidgetWorker.getScriptMethodName(scriptLocation);
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> @Override
> >>>>>> +       
> public void
> >>>>>> runAction(Map<String,
> Object>
> >> context)
> >>>> throws
> >>>>>> GeneralException {
> >>>>>> +       
>    
> >> if
> >>>>>> (location.endsWith(".bsh")) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> try {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
> >>>> 
>    BshUtil.runBshAtLocation(location,
> >>>> context);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> catch (GeneralException e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    throw new
> >>>> GeneralException("Error running BSH
> >>>>>> script at location [" + location +
> "]",
> >> e);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> (location.endsWith(".groovy")) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> try {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    groovy.lang.Script
> >> script
> >>>> =
> >>>>>> 
> >>>> 
> >>
> InvokerHelper.createScript(GroovyUtil.getScriptClassFromLocation(location),
> >>>>>> GroovyUtil.getBinding(context));
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       if
> >>>> (UtilValidate.isEmpty(method)) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
> >>>>     script.run();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       }
> else {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
> >>>> 
>    script.invokeMethod(method,
> >>>>>> EMPTY_ARGS);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       }
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> catch (GeneralException e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    throw new
> >>>> GeneralException("Error running
> >>>>>> Groovy script at location [" +
> location +
> >> "]",
> >>>> e);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> } else
> >>>> if
> >>>>>> (location.endsWith(".xml")) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Map<String, Object>
> localContext =
> >>>>>> FastMap.newInstance();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> localContext.putAll(context);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> DispatchContext ctx =
> >>>>>> 
> >>>> 
> >>
> WidgetWorker.getDispatcher(context).getDispatchContext();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> MethodContext methodContext = new
> >>>> MethodContext(ctx,
> >>>>>> localContext, null);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> try {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
> >>>>    
> >> SimpleMethod.runSimpleMethod(location,
> >>>> method,
> >>>>>> methodContext);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
> >>>>    
> >> context.putAll(methodContext.getResults());
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> catch (MiniLangException e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    throw new
> >>>> GeneralException("Error running
> >>>>>> simple method at location [" +
> location +
> >> "]",
> >>>> e);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> } else
> >>>> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new GeneralException("For
> widget
> >> script
> >>>> actions the
> >>>>>> script type is not yet supported
> for
> >> location: ["
> >>>> + location
> >>>>>> + "]");
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static
> class
> >> Service
> >>>> extends
> >>>>>> ModelWidgetAction {
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander
> serviceNameExdr;
> >>>>>> +       
> protected
> >>>>>>
> FlexibleMapAccessor<Map<String,
> >>>> Object>>
> >>>>>> resultMapNameAcsr;
> >>>>>> +       
> protected
> >>>>>> FlexibleStringExpander
> autoFieldMapExdr;
> >>>>>> +       
> protected
> >>>>>>
> Map<FlexibleMapAccessor<Object>,
> >>>> Object>
> >>>>>> fieldMap;
> >>>>>> +
> >>>>>> +       
> public
> >>>> Service(ModelWidget
> >>>>>> modelWidget, Element
> serviceElement) {
> >>>>>> +       
>    
> >> super
> >>>>>> (modelWidget, serviceElement);
> >>>>>> +       
> >>    
> >>>>>> this.serviceNameExdr =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
> >>>>>> +       
> >>    
> >>>>>> this.resultMapNameAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
> >>>>>> +       
>    
> >> if
> >>>>>>
> (this.resultMapNameAcsr.isEmpty())
> >>>> this.resultMapNameAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
> >>>>>> +       
> >>    
> >>>>>> this.autoFieldMapExdr =
> >>>>>> 
> >>>> 
> >>
> FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
> >>>>>> +       
> >>    
> >>>> this.fieldMap =
> >>>>>> 
> >> EntityFinderUtil.makeFieldMap(serviceElement);
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> @Override
> >>>>>> +       
> public void
> >>>>>> runAction(Map<String,
> Object>
> >> context) {
> >>>>>> +       
>    
> >> String
> >>>>>> serviceNameExpanded =
> >>>>>> 
> >> this.serviceNameExdr.expandString(context);
> >>>>>> +       
>    
> >> if
> >>>>>> 
> >> (UtilValidate.isEmpty(serviceNameExpanded)) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> >> IllegalArgumentException("Service name
> >>>> was empty,
> >>>>>> expanded from: " +
> >>>> this.serviceNameExdr.getOriginal());
> >>>>>> +       
>    
> >> }
> >>>>>> +
> >>>>>> +       
>    
> >> String
> >>>>>> autoFieldMapString =
> >>>>>> 
> >> this.autoFieldMapExdr.expandString(context);
> >>>>>> +
> >>>>>> +       
>    
> >> try {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Map<String, Object>
> serviceContext =
> >> null;
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>>
> ("true".equals(autoFieldMapString)) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    DispatchContext dc =
> >>>>>> 
> >>>> 
> >>
> WidgetWorker.getDispatcher(context).getDispatchContext();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       //
> try a map called
> >>>> "parameters", try it first
> >>>>>> so values from here are overriden
> by
> >> values in the
> >>>> main
> >>>>>> context
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    Map<String,
> >> Object>
> >>>> combinedMap =
> >>>>>> FastMap.newInstance();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    Map<String,
> >> Object>
> >>>> parametersObj =
> >>>>>> 
> >> UtilGenerics.toMap(context.get("parameters"));
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       if
> (parametersObj !=
> >> null)
> >>>> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>         
> 
> >>>>>>
> combinedMap.putAll(parametersObj);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       }
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
> >>>> 
>    combinedMap.putAll(context);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    serviceContext =
> >>>>>>
> dc.makeValidContext(serviceNameExpanded,
> >>>>>> ModelService.IN_PARAM,
> combinedMap);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else if
> >>>>
> (UtilValidate.isNotEmpty(autoFieldMapString)
> >>>>>> &&
> >> !"false".equals(autoFieldMapString)) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
> >>>> 
>    FlexibleMapAccessor<Object>
> >> fieldFma
> >>>> =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(autoFieldMapString);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    Map<String,
> >> Object>
> >>>> autoFieldMap =
> >>>>>> 
> >> UtilGenerics.toMap(fieldFma.get(context));
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       if
> (autoFieldMap !=
> >> null)
> >>>> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
> >>>>     serviceContext =
> >>>>>> 
> >>>> 
> >>
> WidgetWorker.getDispatcher(context).getDispatchContext().makeValidContext(serviceNameExpanded,
> >>>>>> ModelService.IN_PARAM,
> autoFieldMap);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       }
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (serviceContext == null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    serviceContext =
> >>>> FastMap.newInstance();
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (this.fieldMap != null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>      
> >>>>>> 
> >>>> 
> >>
> EntityFinderUtil.expandFieldMapToContext(this.fieldMap,
> >>>>>> context, serviceContext);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Map<String, Object> result
> =
> >>>>>> 
> >>>> 
> >>
> WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded,
> >>>>>> serviceContext);
> >>>>>> +
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>>
> (!this.resultMapNameAcsr.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
> >>>> 
>    this.resultMapNameAcsr.put(context,
> >>>> result);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
>    String queryString =
> >>>>>>
> (String)result.get("queryString");
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>      
> >> context.put("queryString",
> >>>> queryString);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
> >>>> 
>    context.put("queryStringMap",
> >>>>>> result.get("queryStringMap"));
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       if
> >>>> (UtilValidate.isNotEmpty(queryString)) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    try {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    
> >>>>     String
> >>>>>> queryStringEncoded =
> >>>> queryString.replaceAll("&",
> >>>>>> "%26");
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>         
> 
> >>    
> >>>>>> context.put("queryStringEncoded",
> >>>> queryStringEncoded);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    } catch
> >>>> (PatternSyntaxException
> >>>>>> e) {
> >>>>>> +
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       
>    }
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>       }
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else {
> >>>>>> +       
> >>    
> >>>>     
> > 
> >>>>>>      
> >> context.putAll(result);
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>> catch
> >>>>>> (GenericServiceException e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String errMsg = "Error calling
> service
> >> with name "
> >>>> +
> >>>>>> serviceNameExpanded + ": " +
> >> e.toString();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Debug.logError(e, errMsg,
> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> >> IllegalArgumentException(errMsg);
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> public
> >>>> FlexibleStringExpander
> >>>>>> getServiceNameExdr() {
> >>>>>> +       
>    
> >> return
> >>>>>> this.serviceNameExdr;
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static
> class
> >> EntityOne
> >>>> extends
> >>>>>> ModelWidgetAction {
> >>>>>> +       
> protected
> >>>> PrimaryKeyFinder
> >>>>>> finder;
> >>>>>> +
> >>>>>> +       
> public
> >>>> EntityOne(ModelWidget
> >>>>>> modelWidget, Element
> entityOneElement) {
> >>>>>> +       
>    
> >> super
> >>>>>> (modelWidget, entityOneElement);
> >>>>>> +       
>    
> >> finder
> >>>> = new
> >>>>>>
> PrimaryKeyFinder(entityOneElement);
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> @Override
> >>>>>> +       
> public void
> >>>>>> runAction(Map<String,
> Object>
> >> context) {
> >>>>>> +       
>    
> >> try {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> finder.runFind(context,
> >>>>>>
> WidgetWorker.getDelegator(context));
> >>>>>> +       
>    
> >> }
> >>>> catch
> >>>>>> (GeneralException e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String errMsg = "Error doing
> entity query
> >> by
> >>>> condition: " +
> >>>>>> e.toString();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Debug.logError(e, errMsg,
> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> >> IllegalArgumentException(errMsg);
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> public
> >>>> PrimaryKeyFinder
> >>>>>> getFinder() {
> >>>>>> +       
>    
> >> return
> >>>>>> this.finder;
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static
> class
> >> EntityAnd
> >>>> extends
> >>>>>> ModelWidgetAction {
> >>>>>> +       
> protected
> >> ByAndFinder
> >>>> finder;
> >>>>>> +
> >>>>>> +       
> public
> >>>> EntityAnd(ModelWidget
> >>>>>> modelWidget, Element
> entityAndElement) {
> >>>>>> +       
>    
> >> super
> >>>>>> (modelWidget, entityAndElement);
> >>>>>> +       
>    
> >> finder
> >>>> = new
> >>>>>> ByAndFinder(entityAndElement);
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> @Override
> >>>>>> +       
> public void
> >>>>>> runAction(Map<String,
> Object>
> >> context) {
> >>>>>> +       
>    
> >> try {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> finder.runFind(context,
> >>>>>>
> WidgetWorker.getDelegator(context));
> >>>>>> +       
>    
> >> }
> >>>> catch
> >>>>>> (GeneralException e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String errMsg = "Error doing
> entity query
> >> by
> >>>> condition: " +
> >>>>>> e.toString();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Debug.logError(e, errMsg,
> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> >> IllegalArgumentException(errMsg);
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> public
> >> ByAndFinder
> >>>> getFinder()
> >>>>>> {
> >>>>>> +       
>    
> >> return
> >>>>>> this.finder;
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static
> class
> >> EntityCondition
> >>>> extends
> >>>>>> ModelWidgetAction {
> >>>>>> +       
> >> ByConditionFinder
> >>>> finder;
> >>>>>> +
> >>>>>> +       
> public
> >>>>>> EntityCondition(ModelWidget
> modelWidget,
> >> Element
> >>>>>> entityConditionElement) {
> >>>>>> +       
>    
> >> super
> >>>>>> (modelWidget,
> entityConditionElement);
> >>>>>> +       
>    
> >> finder
> >>>> = new
> >>>>>> 
> >> ByConditionFinder(entityConditionElement);
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> @Override
> >>>>>> +       
> public void
> >>>>>> runAction(Map<String,
> Object>
> >> context) {
> >>>>>> +       
>    
> >> try {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> finder.runFind(context,
> >>>>>>
> WidgetWorker.getDelegator(context));
> >>>>>> +       
>    
> >> }
> >>>> catch
> >>>>>> (GeneralException e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String errMsg = "Error doing
> entity query
> >> by
> >>>> condition: " +
> >>>>>> e.toString();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Debug.logError(e, errMsg,
> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> >> IllegalArgumentException(errMsg);
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> public
> >>>> ByConditionFinder
> >>>>>> getFinder() {
> >>>>>> +       
>    
> >> return
> >>>>>> this.finder;
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static
> class
> >> GetRelatedOne
> >>>> extends
> >>>>>> ModelWidgetAction {
> >>>>>> +       
> protected
> >>>>>> FlexibleMapAccessor<Object>
> >> valueNameAcsr;
> >>>>>> +       
> protected
> >>>>>> FlexibleMapAccessor<Object>
> >>>> toValueNameAcsr;
> >>>>>> +       
> protected
> >> String
> >>>>>> relationName;
> >>>>>> +       
> protected
> >> boolean
> >>>> useCache;
> >>>>>> +
> >>>>>> +       
> public
> >>>>>> GetRelatedOne(ModelWidget
> modelWidget,
> >> Element
> >>>>>> getRelatedOneElement) {
> >>>>>> +       
>    
> >> super
> >>>>>> (modelWidget,
> getRelatedOneElement);
> >>>>>> +       
> >>    
> >>>>>> this.valueNameAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
> >>>>>> +       
>    
> >> if
> >>>>>> (this.valueNameAcsr.isEmpty())
> >> this.valueNameAcsr
> >>>> =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-name"));
> >>>>>> +       
> >>    
> >>>>>> this.toValueNameAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
> >>>>>> +       
>    
> >> if
> >>>>>> (this.toValueNameAcsr.isEmpty())
> >>>> this.toValueNameAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-name"));
> >>>>>> +       
> >>    
> >>>>>> this.relationName =
> >>>>>> 
> >>>> 
> >>
> getRelatedOneElement.getAttribute("relation-name");
> >>>>>> +       
> >>    
> >>>> this.useCache =
> >>>>>> 
> >>>> 
> >>
> "true".equals(getRelatedOneElement.getAttribute("use-cache"));
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> @Override
> >>>>>> +       
> public void
> >>>>>> runAction(Map<String,
> Object>
> >> context) {
> >>>>>> +       
>    
> >> Object
> >>>>>> valueObject =
> valueNameAcsr.get(context);
> >>>>>> +       
>    
> >> if
> >>>> (valueObject
> >>>>>> == null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Debug.logVerbose("Value not found
> with
> >> name: " +
> >>>>>> valueNameAcsr + ", not getting
> >> related...",
> >>>> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> return;
> >>>>>> +       
>    
> >> }
> >>>>>> +       
>    
> >> if
> >>>>>> (!(valueObject instanceof
> GenericValue))
> >> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String errMsg = "Env variable for
> >> value-name " +
> >>>>>> valueNameAcsr.toString() + " is
> not a
> >> GenericValue
> >>>> object;
> >>>>>> for the relation-name: " +
> relationName +
> >> "]";
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Debug.logError(errMsg, module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> >> IllegalArgumentException(errMsg);
> >>>>>> +       
>    
> >> }
> >>>>>> +       
> >>    
> >>>> GenericValue
> >>>>>> value = (GenericValue)
> valueObject;
> >>>>>> +       
>    
> >> try {
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (useCache) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
> >>>> 
>    toValueNameAcsr.put(context,
> >>>>>>
> value.getRelatedOneCache(relationName));
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>   
> >>>> 
>    toValueNameAcsr.put(context,
> >>>>>>
> value.getRelatedOne(relationName));
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>> catch
> >>>>>> (GenericEntityException e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String errMsg = "Problem getting
> related
> >> one from
> >>>> entity
> >>>>>> with name " +
> value.getEntityName() + "
> >> for the
> >>>>>> relation-name: " + relationName +
> ": " +
> >>>> e.getMessage();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Debug.logError(e, errMsg,
> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> >> IllegalArgumentException(errMsg);
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> public
> >> String
> >>>>>> getRelationName() {
> >>>>>> +       
>    
> >> return
> >>>>>> this.relationName;
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    public static
> class
> >> GetRelated
> >>>> extends
> >>>>>> ModelWidgetAction {
> >>>>>> +       
> protected
> >>>>>> FlexibleMapAccessor<Object>
> >> valueNameAcsr;
> >>>>>> +       
> protected
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor<List<GenericValue>>
> >>>>>> listNameAcsr;
> >>>>>> +       
> protected
> >>>>>>
> FlexibleMapAccessor<Map<String,
> >>>> Object>>
> >>>>>> mapAcsr;
> >>>>>> +       
> protected
> >>>>>> 
> >> FlexibleMapAccessor<List<String>>
> >>>>>> orderByListAcsr;
> >>>>>> +       
> protected
> >> String
> >>>>>> relationName;
> >>>>>> +       
> protected
> >> boolean
> >>>> useCache;
> >>>>>> +
> >>>>>> +       
> public
> >>>> GetRelated(ModelWidget
> >>>>>> modelWidget, Element
> getRelatedElement) {
> >>>>>> +       
>    
> >> super
> >>>>>> (modelWidget, getRelatedElement);
> >>>>>> +       
> >>    
> >>>>>> this.valueNameAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
> >>>>>> +       
>    
> >> if
> >>>>>> (this.valueNameAcsr.isEmpty())
> >> this.valueNameAcsr
> >>>> =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-name"));
> >>>>>> +       
> >>    
> >>>>>> this.listNameAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
> >>>>>> +       
>    
> >> if
> >>>>>> (this.listNameAcsr.isEmpty())
> >> this.listNameAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list-name"));
> >>>>>> +       
> >>    
> >>>>>> this.relationName =
> >>>>>> 
> >> getRelatedElement.getAttribute("relation-name");
> >>>>>> +       
> >>    
> >>>> this.mapAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
> >>>>>> +       
>    
> >> if
> >>>>>> (this.mapAcsr.isEmpty())
> this.mapAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map-name"));
> >>>>>> +       
> >>    
> >>>>>> this.orderByListAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
> >>>>>> +       
>    
> >> if
> >>>>>> (this.orderByListAcsr.isEmpty())
> >>>> this.orderByListAcsr =
> >>>>>> 
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list-name"));
> >>>>>> +       
> >>    
> >>>> this.useCache =
> >>>>>> 
> >>>> 
> >>
> "true".equals(getRelatedElement.getAttribute("use-cache"));
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> @Override
> >>>>>> +       
> public void
> >>>>>> runAction(Map<String,
> Object>
> >> context) {
> >>>>>> +       
>    
> >> Object
> >>>>>> valueObject =
> valueNameAcsr.get(context);
> >>>>>> +       
>    
> >> if
> >>>> (valueObject
> >>>>>> == null) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Debug.logVerbose("Value not found
> with
> >> name: " +
> >>>>>> valueNameAcsr + ", not getting
> >> related...",
> >>>> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> return;
> >>>>>> +       
>    
> >> }
> >>>>>> +       
>    
> >> if
> >>>>>> (!(valueObject instanceof
> GenericValue))
> >> {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String errMsg = "Env variable for
> >> value-name " +
> >>>>>> valueNameAcsr.toString() + " is
> not a
> >> GenericValue
> >>>> object;
> >>>>>> for the relation-name: " +
> relationName +
> >> "]";
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Debug.logError(errMsg, module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> >> IllegalArgumentException(errMsg);
> >>>>>> +       
>    
> >> }
> >>>>>> +       
> >>    
> >>>> GenericValue
> >>>>>> value = (GenericValue)
> valueObject;
> >>>>>> +       
> >>    
> >>>>>> List<String> orderByNames =
> null;
> >>>>>> +       
>    
> >> if
> >>>>>> (!orderByListAcsr.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> orderByNames =
> >> orderByListAcsr.get(context);
> >>>>>> +       
>    
> >> }
> >>>>>> +       
> >>    
> >>>> Map<String,
> >>>>>> Object> constraintMap = null;
> >>>>>> +       
>    
> >> if
> >>>>>> (!mapAcsr.isEmpty()) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> constraintMap =
> mapAcsr.get(context);
> >>>>>> +       
>    
> >> }
> >>>>>> +       
>    
> >> try {
> >>>>>> +     
>    
> >>    
> >>>>    if
> >>>>>> (useCache) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>      
> >> listNameAcsr.put(context,
> >>>>>>
> value.getRelatedCache(relationName,
> >>>> constraintMap,
> >>>>>> orderByNames));
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> else {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>>      
> >> listNameAcsr.put(context,
> >>>>>> value.getRelated(relationName,
> >> constraintMap,
> >>>>>> orderByNames));
> >>>>>> +     
>    
> >>    
> >>>>    }
> >>>>>> +       
>    
> >> }
> >>>> catch
> >>>>>> (GenericEntityException e) {
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> String errMsg = "Problem getting
> related
> >> from
> >>>> entity with
> >>>>>> name " + value.getEntityName() + "
> for
> >> the
> >>>> relation-name: "
> >>>>>> + relationName + ": " +
> e.getMessage();
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> Debug.logError(e, errMsg,
> module);
> >>>>>> +       
> >>    
> >>>>     
> >>>>>> throw new
> >> IllegalArgumentException(errMsg);
> >>>>>> +       
>    
> >> }
> >>>>>> +        }
> >>>>>> +
> >>>>>> +       
> public
> >> String
> >>>>>> getRelationName() {
> >>>>>> +       
>    
> >> return
> >>>>>> this.relationName;
> >>>>>> +        }
> >>>>>> +    }
> >>>>>> +}
> >>>>>> 
> >>>>>> Propchange:
> >>>>>> 
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>>>> 
> >>>> 
> >>
> ------------------------------------------------------------------------------
> >>>>>>   
>    svn:eol-style =
> >> native
> >>>>>> 
> >>>>>> Propchange:
> >>>>>> 
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>>>> 
> >>>> 
> >>
> ------------------------------------------------------------------------------
> >>>>>>   
>    svn:keywords = "Date
> >> Rev
> >>>> Author URL Id"
> >>>>>> 
> >>>>>> Propchange:
> >>>>>> 
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>>>> 
> >>>> 
> >>
> ------------------------------------------------------------------------------
> >>>>>>   
>    svn:mime-type =
> >>>> text/plain
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>> 
> >>>>> 
> >>>>> 
> >>>> 
> >>>> 
> >>> 
> >>> 
> >>> 
> >> 
> >> 
> > 
> > 
> > 
> 
> 


      

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by David E Jones <de...@me.com>.
On Jul 2, 2010, at 7:11 PM, Adrian Crum wrote:

> Because I've done it myself. ;-)

Wait, do you mean that in this case you did the actual copying and pasting? Well... I guess that would be one way to know for sure!

> I agree that code can look redundant and not be copy and paste. The obvious ones are easy to spot because... well... they're *obvious*.

It's a great effort to refactor code and reduce it's size and redundancy. IMO that sort of effort is even more bang for the buck than automated testing for reducing bugs, and both developer and user experience with the stuff.

On the other hand, there is such a thing as too much parameterization that results in code that is more complicated and difficult to maintain than an alternative that might seem more redundant. I heard this put a funny way once, something like: if you start getting a nagging feeling that you are creating an alternative to a programming language in order to handle a specific business case then you've already crossed the line. ;)

-David

> --- On Fri, 7/2/10, David E Jones <de...@me.com> wrote:
> 
>> From: David E Jones <de...@me.com>
>> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> To: dev@ofbiz.apache.org
>> Date: Friday, July 2, 2010, 5:44 PM
>> 
>> How do you know it was copy and paste?
>> 
>> It could very well have been different code written by
>> different people and at different times, possibly even with
>> no reference to the other code. Redundant similar code is
>> annoying and nice to eliminate, but it's existence does not
>> imply copy/paste, or even necessarily awareness of the other
>> code.
>> 
>> -David
>> 
>> 
>> On Jul 2, 2010, at 1:18 AM, Adrian Crum wrote:
>> 
>>> My new mantra: Just say no to copy and paste.
>>> 
>>> I'm questioning nearly all of the code I come across.
>>> 
>>> -Adrian
>>> 
>>> 
>>> --- On Thu, 7/1/10, Scott Gray <sc...@hotwaxmedia.com>
>> wrote:
>>> 
>>>> From: Scott Gray <sc...@hotwaxmedia.com>
>>>> Subject: Re: svn commit: r959875 -
>> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> To: dev@ofbiz.apache.org
>>>> Date: Thursday, July 1, 2010, 11:58 PM
>>>> Yeah no worries.  I'd never
>>>> really thought about it before until yesterday
>> when I came
>>>> across a problem in the
>> ModelMenuAction.PropertyMap action,
>>>> it replaces the existing uiLabelMap instead of
>> adding to it
>>>> like the ModelScreenAction version does. 
>> Option was to
>>>> either just copy and paste the screen version or
>> take the
>>>> plunge and sort it all out.
>>>> 
>>>> Regards
>>>> Scott
>>>> 
>>>> On 2/07/2010, at 6:45 PM, Adrian Crum wrote:
>>>> 
>>>>> Thanks! That duplication always bothered me.
>>>>> 
>>>>> -Adrian
>>>>> 
>>>>> --- On Thu, 7/1/10, lektran@apache.org
>>>> <le...@apache.org>
>>>> wrote:
>>>>> 
>>>>>> From: lektran@apache.org
>>>> <le...@apache.org>
>>>>>> Subject: svn commit: r959875 -
>>>> 
>> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>>>> To: commits@ofbiz.apache.org
>>>>>> Date: Thursday, July 1, 2010, 11:38 PM
>>>>>> Author: lektran
>>>>>> Date: Fri Jul  2 06:38:52 2010
>>>>>> New Revision: 959875
>>>>>> 
>>>>>> URL: http://svn.apache.org/viewvc?rev=959875&view=rev
>>>>>> Log:
>>>>>> Added a new class ModelWidgetAction which
>> will
>>>> serve to
>>>>>> replace the duplicate classes
>> ModelScreenAction,
>>>>>> ModelFormAction and ModelMenuAction. 
>> This
>>>> class is
>>>>>> virtually a direct copy of
>> ModelScreenAction and
>>>> its
>>>>>> subclasses.  I'll work over the
>> weekend to
>>>> switch the
>>>>>> existing classes to extend from
>> ModelWidgetAction,
>>>> remove
>>>>>> their methods and then deprecate the
>> shells that
>>>> are left
>>>>>> behind.
>>>>>> 
>>>>>> Added:
>>>>>>      
>>>>>> 
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java   (with
>>>>>> props)
>>>>>> 
>>>>>> Added:
>>>>>> 
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java?rev=959875&view=auto
>>>>>> 
>>>> 
>> ==============================================================================
>>>>>> ---
>>>>>> 
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>>>> (added)
>>>>>> +++
>>>>>> 
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>>>> Fri Jul  2 06:38:52 2010
>>>>>> @@ -0,0 +1,700 @@
>>>>>> 
>>>> 
>> +/*******************************************************************************
>>>>>> + * 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;
>>>>>> +
>>>>>> +import java.io.Serializable;
>>>>>> +import java.text.MessageFormat;
>>>>>> +import java.util.ArrayList;
>>>>>> +import java.util.List;
>>>>>> +import java.util.Locale;
>>>>>> +import java.util.Map;
>>>>>> +import java.util.TimeZone;
>>>>>> +import
>> java.util.regex.PatternSyntaxException;
>>>>>> +
>>>>>> +import javax.servlet.ServletContext;
>>>>>> +import javax.servlet.http.HttpSession;
>>>>>> +
>>>>>> +import javolution.util.FastList;
>>>>>> +import javolution.util.FastMap;
>>>>>> +
>>>>>> +import org.w3c.dom.Element;
>>>>>> +import
>>>> org.codehaus.groovy.runtime.InvokerHelper;
>>>>>> +import org.ofbiz.base.util.BshUtil;
>>>>>> +import org.ofbiz.base.util.Debug;
>>>>>> +import
>> org.ofbiz.base.util.GeneralException;
>>>>>> +import org.ofbiz.base.util.GroovyUtil;
>>>>>> +import org.ofbiz.base.util.ObjectType;
>>>>>> +import org.ofbiz.base.util.StringUtil;
>>>>>> +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.collections.FlexibleMapAccessor;
>>>>>> +import
>>>>>> 
>>>> 
>> org.ofbiz.base.util.collections.ResourceBundleMapWrapper;
>>>>>> +import
>>>> 
>> org.ofbiz.base.util.string.FlexibleStringExpander;
>>>>>> +import
>> org.ofbiz.entity.GenericEntityException;
>>>>>> +import org.ofbiz.entity.GenericValue;
>>>>>> +import
>> org.ofbiz.entity.finder.ByAndFinder;
>>>>>> +import
>>>> org.ofbiz.entity.finder.ByConditionFinder;
>>>>>> +import
>> org.ofbiz.entity.finder.EntityFinderUtil;
>>>>>> +import
>> org.ofbiz.entity.finder.PrimaryKeyFinder;
>>>>>> +import
>> org.ofbiz.minilang.MiniLangException;
>>>>>> +import org.ofbiz.minilang.SimpleMethod;
>>>>>> +import
>> org.ofbiz.minilang.method.MethodContext;
>>>>>> +import
>> org.ofbiz.service.DispatchContext;
>>>>>> +import
>>>> org.ofbiz.service.GenericServiceException;
>>>>>> +import org.ofbiz.service.ModelService;
>>>>>> +
>>>>>> +@SuppressWarnings("serial")
>>>>>> +public abstract class ModelWidgetAction
>>>> implements
>>>>>> Serializable {
>>>>>> +    public static final String
>> module
>>>> =
>>>>>> ModelWidgetAction.class.getName();
>>>>>> +
>>>>>> +    protected ModelWidget
>> modelWidget;
>>>>>> +
>>>>>> +    protected
>> ModelWidgetAction() {}
>>>>>> +
>>>>>> +    public
>>>> ModelWidgetAction(ModelWidget
>>>>>> modelWidget, Element actionElement) {
>>>>>> +       
>> this.modelWidget =
>>>>>> modelWidget;
>>>>>> +        if
>>>> (Debug.verboseOn())
>>>>>> Debug.logVerbose("Reading widget action
>> with name:
>>>> " +
>>>>>> actionElement.getNodeName(), module);
>>>>>> +    }
>>>>>> +
>>>>>> +    public abstract void
>>>>>> runAction(Map<String, Object>
>> context)
>>>> throws
>>>>>> GeneralException;
>>>>>> +
>>>>>> +    public static
>>>> List<ModelWidgetAction>
>>>>>> readSubActions(ModelWidget modelWidget,
>> Element
>>>>>> parentElement) {
>>>>>> +       
>>>> List<ModelWidgetAction>
>>>>>> actions = FastList.newInstance();
>>>>>> +
>>>>>> +        List<?
>> extends
>>>> Element>
>>>>>> actionElementList =
>>>>>> UtilXml.childElementList(parentElement);
>>>>>> +        for (Element
>>>> actionElement:
>>>>>> actionElementList) {
>>>>>> +           
>> if
>>>>>> 
>> ("set".equals(actionElement.getNodeName())) {
>>>>>> +       
>>    
>>>>     
>>>>>> actions.add(new SetField(modelWidget,
>>>> actionElement));
>>>>>> +           
>> } else
>>>> if
>>>>>> 
>>>> 
>> ("property-map".equals(actionElement.getNodeName())) {
>>>>>> +       
>>    
>>>>     
>>>>>> actions.add(new PropertyMap(modelWidget,
>>>> actionElement));
>>>>>> +           
>> } else
>>>> if
>>>>>> 
>>>> 
>> ("property-to-field".equals(actionElement.getNodeName())) {
>>>>>> +       
>>    
>>>>     
>>>>>> actions.add(new
>> PropertyToField(modelWidget,
>>>>>> actionElement));
>>>>>> +           
>> } else
>>>> if
>>>>>> 
>> ("script".equals(actionElement.getNodeName())) {
>>>>>> +       
>>    
>>>>     
>>>>>> actions.add(new Script(modelWidget,
>>>> actionElement));
>>>>>> +           
>> } else
>>>> if
>>>>>> 
>> ("service".equals(actionElement.getNodeName())) {
>>>>>> +       
>>    
>>>>     
>>>>>> actions.add(new Service(modelWidget,
>>>> actionElement));
>>>>>> +           
>> } else
>>>> if
>>>>>> 
>> ("entity-one".equals(actionElement.getNodeName()))
>>>> {
>>>>>> +       
>>    
>>>>     
>>>>>> actions.add(new EntityOne(modelWidget,
>>>> actionElement));
>>>>>> +           
>> } else
>>>> if
>>>>>> 
>> ("entity-and".equals(actionElement.getNodeName()))
>>>> {
>>>>>> +       
>>    
>>>>     
>>>>>> actions.add(new EntityAnd(modelWidget,
>>>> actionElement));
>>>>>> +           
>> } else
>>>> if
>>>>>> 
>>>> 
>> ("entity-condition".equals(actionElement.getNodeName())) {
>>>>>> +       
>>    
>>>>     
>>>>>> actions.add(new
>> EntityCondition(modelWidget,
>>>>>> actionElement));
>>>>>> +           
>> } else
>>>> if
>>>>>> 
>>>> 
>> ("get-related-one".equals(actionElement.getNodeName())) {
>>>>>> +       
>>    
>>>>     
>>>>>> actions.add(new
>> GetRelatedOne(modelWidget,
>>>> actionElement));
>>>>>> +           
>> } else
>>>> if
>>>>>> 
>>>> 
>> ("get-related".equals(actionElement.getNodeName())) {
>>>>>> +       
>>    
>>>>     
>>>>>> actions.add(new GetRelated(modelWidget,
>>>> actionElement));
>>>>>> +           
>> } else
>>>> {
>>>>>> +       
>>    
>>>>     
>>>>>> throw new IllegalArgumentException("Action
>> element
>>>> not
>>>>>> supported with name: " +
>>>> actionElement.getNodeName());
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +
>>>>>> +        return
>> actions;
>>>>>> +    }
>>>>>> +
>>>>>> +    public static void
>>>>>> 
>> runSubActions(List<ModelWidgetAction>
>>>> actions,
>>>>>> Map<String, Object> context) throws
>>>> GeneralException
>>>>>> {
>>>>>> +        if (actions
>> == null)
>>>> return;
>>>>>> +
>>>>>> +        for
>>>> (ModelWidgetAction action:
>>>>>> actions) {
>>>>>> +           
>> if
>>>>>> (Debug.verboseOn())
>> Debug.logVerbose("Running
>>>> widget action
>>>>>> " + action.getClass().getName(), module);
>>>>>> +       
>>    
>>>>>> action.runAction(context);
>>>>>> +        }
>>>>>> +    }
>>>>>> +
>>>>>> +    public static class
>> SetField
>>>> extends
>>>>>> ModelWidgetAction {
>>>>>> +        protected
>>>>>> FlexibleMapAccessor<Object> field;
>>>>>> +        protected
>>>>>> FlexibleMapAccessor<Object>
>> fromField;
>>>>>> +        protected
>>>>>> FlexibleStringExpander valueExdr;
>>>>>> +        protected
>>>>>> FlexibleStringExpander defaultExdr;
>>>>>> +        protected
>>>>>> FlexibleStringExpander globalExdr;
>>>>>> +        protected
>> String
>>>> type;
>>>>>> +        protected
>> String
>>>> toScope;
>>>>>> +        protected
>> String
>>>> fromScope;
>>>>>> +
>>>>>> +        public
>>>> SetField(ModelWidget
>>>>>> modelWidget, Element setElement) {
>>>>>> +           
>> super
>>>>>> (modelWidget, setElement);
>>>>>> +       
>>    
>>>> this.field =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
>>>>>> +       
>>    
>>>> this.fromField =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("from-field"));
>>>>>> +       
>>    
>>>> this.valueExdr =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("value"));
>>>>>> +       
>>    
>>>> this.defaultExdr
>>>>>> =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("default-value"));
>>>>>> +       
>>    
>>>> this.globalExdr
>>>>>> =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>>>>>> +       
>>    
>>>> this.type =
>>>>>> setElement.getAttribute("type");
>>>>>> +       
>>    
>>>> this.toScope =
>>>>>> setElement.getAttribute("to-scope");
>>>>>> +       
>>    
>>>> this.fromScope =
>>>>>> setElement.getAttribute("from-scope");
>>>>>> +           
>> if
>>>>>> (!this.fromField.isEmpty() &&
>>>>>> !this.valueExdr.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>> throw new IllegalArgumentException("Cannot
>> specify
>>>> a
>>>>>> from-field [" +
>>>> setElement.getAttribute("from-field") + "]
>>>>>> and a value [" +
>> setElement.getAttribute("value")
>>>> + "] on
>>>>>> the set action in a widget");
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +
>>>>>> +        @Override
>>>>>> +        public void
>>>>>> runAction(Map<String, Object>
>> context) {
>>>>>> +           
>> String
>>>> globalStr
>>>>>> = this.globalExdr.expandString(context);
>>>>>> +           
>> //
>>>> default to
>>>>>> false
>>>>>> +           
>> boolean
>>>> global =
>>>>>> "true".equals(globalStr);
>>>>>> +
>>>>>> +           
>> Object
>>>> newValue
>>>>>> = null;
>>>>>> +           
>> if
>>>>>> (this.fromScope != null &&
>>>>>> this.fromScope.equals("user")) {
>>>>>> +         
>>    
>>>>    if
>>>>>> (!this.fromField.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>>       HttpSession session =
>>>> (HttpSession)
>>>>>> context.get("session");
>>>>>> +       
>>    
>>>>     
>>>>>>       newValue =
>>>>>> getInMemoryPersistedFromField(session,
>> context);
>>>>>> +       
>>    
>>>>     
>>>>>>       if
>> (Debug.verboseOn())
>>>> Debug.logVerbose("In
>>>>>> user getting value for field from [" +
>>>>>> this.fromField.getOriginalName() + "]: "
>> +
>>>> newValue,
>>>>>> module);
>>>>>> +         
>>    
>>>>    }
>>>>>> else if (!this.valueExdr.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newValue =
>>>> this.valueExdr.expand(context);
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> } else
>>>> if
>>>>>> (this.fromScope != null &&
>>>>>> this.fromScope.equals("application")) {
>>>>>> +         
>>    
>>>>    if
>>>>>> (!this.fromField.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>>       ServletContext
>>>> servletContext =
>>>>>> (ServletContext)
>> context.get("application");
>>>>>> +       
>>    
>>>>     
>>>>>>       newValue =
>>>>>> 
>> getInMemoryPersistedFromField(servletContext,
>>>> context);
>>>>>> +       
>>    
>>>>     
>>>>>>       if
>> (Debug.verboseOn())
>>>> Debug.logVerbose("In
>>>>>> application getting value for field from
>> [" +
>>>>>> this.fromField.getOriginalName() + "]: "
>> +
>>>> newValue,
>>>>>> module);
>>>>>> +         
>>    
>>>>    }
>>>>>> else if (!this.valueExdr.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newValue =
>>>>>> this.valueExdr.expandString(context);
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> } else
>>>> {
>>>>>> +         
>>    
>>>>    if
>>>>>> (!this.fromField.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newValue =
>>>> this.fromField.get(context);
>>>>>> +       
>>    
>>>>     
>>>>>>       if
>> (Debug.verboseOn())
>>>>>> Debug.logVerbose("Getting value for field
>> from ["
>>>> +
>>>>>> this.fromField.getOriginalName() + "]: "
>> +
>>>> newValue,
>>>>>> module);
>>>>>> +         
>>    
>>>>    }
>>>>>> else if (!this.valueExdr.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newValue =
>>>> this.valueExdr.expand(context);
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>>>> +
>>>>>> +           
>> // If
>>>> newValue
>>>>>> is still empty, use the default value
>>>>>> +           
>> if
>>>>>> (ObjectType.isEmpty(newValue) &&
>>>>>> !this.defaultExdr.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>> newValue =
>> this.defaultExdr.expand(context);
>>>>>> +           
>> }
>>>>>> +
>>>>>> +           
>> if
>>>>>> (UtilValidate.isNotEmpty(this.type)) {
>>>>>> +         
>>    
>>>>    if
>>>>>> ("NewMap".equals(this.type)) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newValue =
>>>> FastMap.newInstance();
>>>>>> +         
>>    
>>>>    }
>>>>>> else if ("NewList".equals(this.type)) {
>>>>>> +       
>>    
> 
>>>>     
>>>>>>       newValue =
>>>> FastList.newInstance();
>>>>>> +         
>>    
>>>>    }
>>>>>> else {
>>>>>> +       
>>    
>>>>     
>>>>>>       try {
>>>>>> +       
>>    
>>>>     
>>>>>>           newValue
>> =
>>>>>> ObjectType.simpleTypeConvert(newValue,
>> this.type,
>>>> null,
>>>>>> (TimeZone) context.get("timeZone"),
>> (Locale)
>>>>>> context.get("locale"), true);
>>>>>> +       
>>    
>>>>     
>>>>>>       } catch
>> (GeneralException
>>>> e) {
>>>>>> +       
>>    
>>>>     
>>>>>>           String
>>>> errMsg = "Could not
>>>>>> convert field value for the field: [" +
>>>>>> this.field.getOriginalName() + "] to the
>> [" +
>>>> this.type + "]
>>>>>> type for the value [" + newValue + "]: "
>> +
>>>> e.toString();
>>>>>> +       
>>    
>>>>     
>>>>>>       
>>>>     Debug.logError(e, errMsg,
>>>>>> module);
>>>>>> +       
>>    
>>>>     
>>>>>>           throw
>> new
>>>>>> IllegalArgumentException(errMsg);
>>>>>> +       
>>    
>>>>     
>>>>>>       }
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>>>> +
>>>>>> +           
>> if
>>>> (this.toScope
>>>>>> != null &&
>> this.toScope.equals("user")) {
>>>>>> +       
>>    
>>>>     
>>>>>> String originalName =
>>>> this.field.getOriginalName();
>>>>>> +       
>>    
>>>>     
>>>>>> List<String> currentWidgetTrail =
>>>>>> 
>>>> 
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>>>>>> +       
>>    
>>>>     
>>>>>> String newKey = "";
>>>>>> +         
>>    
>>>>    if
>>>>>> (currentWidgetTrail != null) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newKey =
>>>> StringUtil.join(currentWidgetTrail,
>>>>>> "|");
>>>>>> +         
>>    
>>>>    }
>>>>>> +         
>>    
>>>>    if
>>>>>> (UtilValidate.isNotEmpty(newKey)) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newKey += "|";
>>>>>> +         
>>    
>>>>    }
>>>>>> +       
>>    
>>>>     
>>>>>> newKey += originalName;
>>>>>> +       
>>    
>>>>     
>>>>>> HttpSession session =
>>>> (HttpSession)context.get("session");
>>>>>> +       
>>    
>>>>     
>>>>>> session.setAttribute(newKey, newValue);
>>>>>> +         
>>    
>>>>    if
>>>>>> (Debug.verboseOn()) Debug.logVerbose("In
>> user
>>>> setting value
>>>>>> for field from [" +
>> this.field.getOriginalName() +
>>>> "]: " +
>>>>>> newValue, module);
>>>>>> +           
>> } else
>>>> if
>>>>>> (this.toScope != null &&
>>>>>> this.toScope.equals("application")) {
>>>>>> +       
>>    
>>>>     
>>>>>> String originalName =
>>>> this.field.getOriginalName();
>>>>>> +       
>>    
>>>>     
>>>>>> List<String> currentWidgetTrail =
>>>>>> 
>>>> 
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>>>>>> +       
>>    
>>>>     
>>>>>> String newKey = "";
>>>>>> +         
>>    
>>>>    if
>>>>>> (currentWidgetTrail != null) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newKey =
>>>> StringUtil.join(currentWidgetTrail,
>>>>>> "|");
>>>>>> +         
>>    
>>>>    }
>>>>>> +         
>>    
>>>>    if
>>>>>> (UtilValidate.isNotEmpty(newKey)) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newKey += "|";
>>>>>> +         
>>    
>>>>    }
>>>>>> +       
>>    
>>>>     
>>>>>> newKey += originalName;
>>>>>> +       
>>    
>>>>     
>>>>>> ServletContext servletContext =
>>>>>> 
>> (ServletContext)context.get("application");
>>>>>> +       
>>    
>>>>     
>>>>>> servletContext.setAttribute(newKey,
>> newValue);
>>>>>> +         
>>    
>>>>    if
>>>>>> (Debug.verboseOn()) Debug.logVerbose("In
>>>> application setting
>>>>>> value for field from [" +
>>>> this.field.getOriginalName() + "]:
>>>>>> " + newValue, module);
>>>>>> +           
>> } else
>>>> {
>>>>>> +         
>>    
>>>>    //
>>>>>> only do this if it is not global, if
>> global ONLY
>>>> put it in
>>>>>> the global context
>>>>>> +         
>>    
>>>>    if
>>>>>> (!global) {
>>>>>> +       
>>    
>>>>     
>>>>>>       if
>> (Debug.verboseOn())
>>>>>> Debug.logVerbose("Setting field [" +
>>>>>> this.field.getOriginalName() + "] to
>> value: " +
>>>> newValue,
>>>>>> module);
>>>>>> +       
>>    
>>>>     
>>>>>>      
>> this.field.put(context,
>>>> newValue);
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>>>> +
>>>>>> +           
>> if
>>>> (global) {
>>>>>> +       
>>    
>>>>     
>>>>>> Map<String, Object> globalCtx =
>>>>>> 
>>>> 
>> UtilGenerics.checkMap(context.get("globalContext"));
>>>>>> +         
>>    
>>>>    if
>>>>>> (globalCtx != null) {
>>>>>> +       
>>    
>>>>     
>>>>>>      
>> this.field.put(globalCtx,
>>>> newValue);
>>>>>> +         
>>    
>>>>    }
>>>>>> else {
>>>>>> +       
>>    
>>>>     
>>>>>>      
>> this.field.put(context,
>>>> newValue);
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>>>> +
>>>>>> +           
>> // this
>>>> is a
>>>>>> hack for backward compatibility with the
>> JPublish
>>>> page
>>>>>> object
>>>>>> +       
>>    
>>>> Map<String,
>>>>>> Object> page =
>>>>>> 
>> UtilGenerics.checkMap(context.get("page"));
>>>>>> +           
>> if
>>>> (page !=
>>>>>> null) {
>>>>>> +       
>>    
>>>>     
>>>>>> this.field.put(page, newValue);
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +
>>>>>> +        public
>> Object
>>>>>> getInMemoryPersistedFromField(Object
>> storeAgent,
>>>>>> Map<String, Object> context) {
>>>>>> +           
>> Object
>>>> newValue
>>>>>> = null;
>>>>>> +           
>> String
>>>>>> originalName =
>> this.fromField.getOriginalName();
>>>>>> +       
>>    
>>>>>> List<String> currentWidgetTrail =
>>>>>> 
>>>> 
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>>>>>> +       
>>    
>>>>>> List<String> trailList = new
>>>>>> ArrayList<String>();
>>>>>> +           
>> if
>>>>>> (currentWidgetTrail != null) {
>>>>>> +       
>>    
>>>>     
>>>>>> trailList.addAll(currentWidgetTrail);
>>>>>> +           
>> }
>>>>>> +
>>>>>> +           
>> for
>>>> (int
>>>>>> i=trailList.size(); i >= 0; i--) {
>>>>>> +       
>>    
>>>>     
>>>>>> List<String> subTrail =
>>>> trailList.subList(0,i);
>>>>>> +       
>>    
>>>>     
>>>>>> String newKey = null;
>>>>>> +         
>>    
>>>>    if
>>>>>> (subTrail.size() > 0)
>>>>>> +       
>>    
>>>>     
>>>>>>       newKey =
>>>> StringUtil.join(subTrail, "|") + "|"
>>>>>> + originalName;
>>>>>> +       
>>    
>>>>     
>>>>>> else
>>>>>> +       
>>    
>>>>     
>>>>>>       newKey =
>> originalName;
>>>>>> +
>>>>>> +         
>>    
>>>>    if
>>>>>> (storeAgent instanceof ServletContext) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newValue =
>>>>>> 
>>>> 
>> ((ServletContext)storeAgent).getAttribute(newKey);
>>>>>> +         
>>    
>>>>    }
>>>>>> else if (storeAgent instanceof
>> HttpSession) {
>>>>>> +       
>>    
>>>>     
>>>>>>       newValue =
>>>>>> 
>> ((HttpSession)storeAgent).getAttribute(newKey);
>>>>>> +         
>>    
>>>>    }
>>>>>> +         
>>    
>>>>    if
>>>>>> (newValue != null) {
>>>>>> +       
>>    
>>>>     
>>>>>>       break;
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>>>> +           
>> return
>>>>>> newValue;
>>>>>> +        }
>>>>>> +    }
>>>>>> +
>>>>>> +    public static class
>> PropertyMap
>>>> extends
>>>>>> ModelWidgetAction {
>>>>>> +        protected
>>>>>> FlexibleStringExpander resourceExdr;
>>>>>> +        protected
>>>>>> 
>>>> 
>> FlexibleMapAccessor<ResourceBundleMapWrapper>
>>>>>> mapNameAcsr;
>>>>>> +        protected
>>>>>> FlexibleStringExpander globalExdr;
>>>>>> +
>>>>>> +        public
>>>> PropertyMap(ModelWidget
>>>>>> modelWidget, Element setElement) {
>>>>>> +           
>> super
>>>>>> (modelWidget, setElement);
>>>>>> +       
>>    
>>>>>> this.resourceExdr =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
>>>>>> +       
>>    
>>>> this.mapNameAcsr
>>>>>> =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("map-name"));
>>>>>> +       
>>    
>>>> this.globalExdr
>>>>>> =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>>>>>> +        }
>>>>>> +
>>>>>> +        @Override
>>>>>> +        public void
>>>>>> runAction(Map<String, Object>
>> context) {
>>>>>> +           
>> String
>>>> globalStr
>>>>>> = this.globalExdr.expandString(context);
>>>>>> +           
>> //
>>>> default to
>>>>>> false
>>>>>> +           
>> boolean
>>>> global =
>>>>>> "true".equals(globalStr);
>>>>>> +
>>>>>> +           
>> Locale
>>>> locale =
>>>>>> (Locale) context.get("locale");
>>>>>> +           
>> String
>>>> resource
>>>>>> = this.resourceExdr.expandString(context,
>>>> locale);
>>>>>> +
>>>>>> +       
>>    
>>>>>> ResourceBundleMapWrapper existingPropMap
>> =
>>>>>> this.mapNameAcsr.get(context);
>>>>>> +           
>> if
>>>>>> (existingPropMap == null) {
>>>>>> +       
>>    
>>>>     
>>>>>> this.mapNameAcsr.put(context,
>>>>>> 
>> UtilProperties.getResourceBundleMap(resource,
>>>> locale,
>>>>>> context));
>>>>>> +           
>> } else
>>>> {
>>>>>> +       
>>    
>>>>     
>>>>>> try {
>>>>>> +       
>>    
>>>>     
>>>>>>      
>>>>>> 
>>>> 
>> existingPropMap.addBottomResourceBundle(resource);
>>>>>> +         
>>    
>>>>    }
>>>>>> catch (IllegalArgumentException e) {
>>>>>> +       
>>    
>>>>     
>>>>>>       // log the error, but
>>>> don't let it kill
>>>>>> everything just for a typo or bad char in
>> an l10n
>>>> file
>>>>>> +       
>>    
>>>>     
>>>>>>       Debug.logError(e,
>> "Error
>>>> adding resource
>>>>>> bundle [" + resource + "]: " +
>> e.toString(),
>>>> module);
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>>>> +
>>>>>> +           
>> if
>>>> (global) {
>>>>>> +       
>>    
>>>>     
>>>>>> Map<String, Object> globalCtx =
>>>>>> 
>>>> 
>> UtilGenerics.checkMap(context.get("globalContext"));
>>>>>> +         
>>    
>>>>    if
>>>>>> (globalCtx != null) {
>>>>>> +       
>>    
>>>>     
>>>>>>      
>> ResourceBundleMapWrapper
>>>> globalExistingPropMap
>>>>>> = this.mapNameAcsr.get(globalCtx);
>>>>>> +       
>>    
>>>>     
>>>>>>       if
>> (globalExistingPropMap
>>>> == null) {
>>>>>> +       
>>    
>>>>     
>>>>>>       
>>>>     this.mapNameAcsr.put(globalCtx,
>>>>>> 
>> UtilProperties.getResourceBundleMap(resource,
>>>> locale,
>>>>>> context));
>>>>>> +       
>>    
>>>>     
>>>>>>       } else {
>>>>>> +       
>>    
>>>>     
>>>>>>           // is it
>> the
>>>> same object? if not
>>>>>> add it in here too...
>>>>>> +       
>>    
>>>>     
>>>>>>           if
>>>> (existingPropMap !=
>>>>>> globalExistingPropMap) {
>>>>>> +       
>>    
>>>>     
>>>>>>           
>>>>     try {
>>>>>> +       
>>    
>>>>     
>>>>>>            
>>   
>>>>    
>>>>>> 
>>>> 
>> globalExistingPropMap.addBottomResourceBundle(resource);
>>>>>> +       
>>    
>>>>     
>>>>>>           
>>>>     } catch
>>>>>> (IllegalArgumentException e) {
>>>>>> +       
>>    
>>>>     
>>>>>>            
>>   
>>>>     //
>>>>>> log the error, but don't let it kill
>> everything
>>>> just for a
>>>>>> typo or bad char in an l10n file
>>>>>> +       
>>    
>>>>     
>>>>>>            
>>   
>>>>    
>>>>>> Debug.logError(e, "Error adding resource
>> bundle ["
>>>> +
>>>>>> resource + "]: " + e.toString(), module);
>>>>>> +       
>>    
>>>>     
>>>>>>           
>>>>     }
>>>>>> +       
>>    
>>>>     
>>>>>>           }
>>>>>> +       
>>    
>>>>     
>>>>>>       }
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +    }
>>>>>> +
>>>>>> +    public static class
>> PropertyToField
>>>> extends
>>>>>> ModelWidgetAction {
>>>>>> +
>>>>>> +        protected
>>>>>> FlexibleStringExpander resourceExdr;
>>>>>> +        protected
>>>>>> FlexibleStringExpander propertyExdr;
>>>>>> +        protected
>>>>>> FlexibleMapAccessor<Object>
>> fieldAcsr;
>>>>>> +        protected
>>>>>> FlexibleStringExpander defaultExdr;
>>>>>> +        protected
>> boolean
>>>> noLocale;
>>>>>> +        protected
>>>>>> FlexibleMapAccessor<List<? extends
>>>> Object>>
>>>>>> argListAcsr;
>>>>>> +        protected
>>>>>> FlexibleStringExpander globalExdr;
>>>>>> +
>>>>>> +        public
>>>>>> PropertyToField(ModelWidget modelWidget,
>> Element
>>>> setElement)
>>>>>> {
>>>>>> +           
>> super
>>>>>> (modelWidget, setElement);
>>>>>> +       
>>    
>>>>>> this.resourceExdr =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
>>>>>> +       
>>    
>>>>>> this.propertyExdr =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
>>>>>> +       
>>    
>>>> this.fieldAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
>>>>>> +       
>>    
>>>> this.defaultExdr
>>>>>> =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("default"));
>>>>>> +       
>>    
>>>> this.noLocale =
>>>>>> 
>>>> 
>> "true".equals(setElement.getAttribute("no-locale"));
>>>>>> +       
>>    
>>>> this.argListAcsr
>>>>>> =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("arg-list-name"));
>>>>>> +       
>>    
>>>> this.globalExdr
>>>>>> =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>>>>>> +        }
>>>>>> +
>>>>>> +        @Override
>>>>>> +        public void
>>>>>> runAction(Map<String, Object>
>> context) {
>>>>>> +       
>>    
>>>> //String
>>>>>> globalStr =
>>>> this.globalExdr.expandString(context);
>>>>>> +           
>> //
>>>> default to
>>>>>> false
>>>>>> +       
>>    
>>>> //boolean global
>>>>>> = "true".equals(globalStr);
>>>>>> +
>>>>>> +           
>> Locale
>>>> locale =
>>>>>> (Locale) context.get("locale");
>>>>>> +           
>> String
>>>> resource
>>>>>> = this.resourceExdr.expandString(context,
>>>> locale);
>>>>>> +           
>> String
>>>> property
>>>>>> = this.propertyExdr.expandString(context,
>>>> locale);
>>>>>> +
>>>>>> +           
>> String
>>>> value =
>>>>>> null;
>>>>>> +           
>> if
>>>> (noLocale) {
>>>>>> +       
>>    
>>>>     
>>>>>> value =
>> UtilProperties.getPropertyValue(resource,
>>>>>> property);
>>>>>> +           
>> } else
>>>> {
>>>>>> +       
>>    
>>>>     
>>>>>> value =
>> UtilProperties.getMessage(resource,
>>>> property,
>>>>>> locale);
>>>>>> +           
>> }
>>>>>> +           
>> if
>>>>>> (UtilValidate.isEmpty(value)) {
>>>>>> +       
>>    
>>>>     
>>>>>> value =
>> this.defaultExdr.expandString(context);
>>>>>> +           
>> }
>>>>>> +
>>>>>> +           
>> // note
>>>> that
>>>>>> expanding the value string here will
>> handle
>>>> defaultValue and
>>>>>> the string from
>>>>>> +       
>>    
>>>> //  the
>>>>>> properties file; if we decide later that
>> we don't
>>>> want the
>>>>>> string from the properties
>>>>>> +       
>>    
>>>> //  file to
>>>>>> be expanded we should just expand the
>> defaultValue
>>>> at the
>>>>>> beginning of this method.
>>>>>> +           
>> value
>>>> =
>>>>>> 
>> FlexibleStringExpander.expandString(value,
>>>> context);
>>>>>> +
>>>>>> +           
>> if
>>>>>> (!argListAcsr.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>> List<? extends Object> argList =
>>>>>> argListAcsr.get(context);
>>>>>> +         
>>    
>>>>    if
>>>>>> (UtilValidate.isNotEmpty(argList)) {
>>>>>> +       
>>    
>>>>     
>>>>>>       value =
>>>> MessageFormat.format(value,
>>>>>> argList.toArray());
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>>>> +       
>>    
>>>>>> fieldAcsr.put(context, value);
>>>>>> +        }
>>>>>> +    }
>>>>>> +
>>>>>> +    public static class Script
>> extends
>>>>>> ModelWidgetAction {
>>>>>> +        protected
>> static
>>>> final
>>>>>> Object[] EMPTY_ARGS = {};
>>>>>> +        protected
>> String
>>>> location;
>>>>>> +        protected
>> String
>>>> method;
>>>>>> +
>>>>>> +        public
>>>> Script(ModelWidget
>>>>>> modelWidget, Element scriptElement) {
>>>>>> +           
>> super
>>>>>> (modelWidget, scriptElement);
>>>>>> +           
>> String
>>>>>> scriptLocation =
>>>> scriptElement.getAttribute("location");
>>>>>> +       
>>    
>>>> this.location =
>>>>>> 
>> WidgetWorker.getScriptLocation(scriptLocation);
>>>>>> +       
>>    
>>>> this.method =
>>>>>> 
>> WidgetWorker.getScriptMethodName(scriptLocation);
>>>>>> +        }
>>>>>> +
>>>>>> +        @Override
>>>>>> +        public void
>>>>>> runAction(Map<String, Object>
>> context)
>>>> throws
>>>>>> GeneralException {
>>>>>> +           
>> if
>>>>>> (location.endsWith(".bsh")) {
>>>>>> +       
>>    
>>>>     
>>>>>> try {
>>>>>> +       
>>    
>>>>     
>>>>>>   
>>>>     BshUtil.runBshAtLocation(location,
>>>> context);
>>>>>> +         
>>    
>>>>    }
>>>>>> catch (GeneralException e) {
>>>>>> +       
>>    
>>>>     
>>>>>>       throw new
>>>> GeneralException("Error running BSH
>>>>>> script at location [" + location + "]",
>> e);
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> } else
>>>> if
>>>>>> (location.endsWith(".groovy")) {
>>>>>> +       
>>    
>>>>     
>>>>>> try {
>>>>>> +       
>>    
>>>>     
>>>>>>       groovy.lang.Script
>> script
>>>> =
>>>>>> 
>>>> 
>> InvokerHelper.createScript(GroovyUtil.getScriptClassFromLocation(location),
>>>>>> GroovyUtil.getBinding(context));
>>>>>> +       
>>    
>>>>     
>>>>>>       if
>>>> (UtilValidate.isEmpty(method)) {
>>>>>> +       
>>    
>>>>     
>>>>>>       
>>>>     script.run();
>>>>>> +       
>>    
>>>>     
>>>>>>       } else {
>>>>>> +       
>>    
>>>>     
>>>>>>       
>>>>     script.invokeMethod(method,
>>>>>> EMPTY_ARGS);
>>>>>> +       
>>    
>>>>     
>>>>>>       }
>>>>>> +         
>>    
>>>>    }
>>>>>> catch (GeneralException e) {
>>>>>> +       
>>    
>>>>     
>>>>>>       throw new
>>>> GeneralException("Error running
>>>>>> Groovy script at location [" + location +
>> "]",
>>>> e);
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> } else
>>>> if
>>>>>> (location.endsWith(".xml")) {
>>>>>> +       
>>    
>>>>     
>>>>>> Map<String, Object> localContext =
>>>>>> FastMap.newInstance();
>>>>>> +       
>>    
>>>>     
>>>>>> localContext.putAll(context);
>>>>>> +       
>>    
>>>>     
>>>>>> DispatchContext ctx =
>>>>>> 
>>>> 
>> WidgetWorker.getDispatcher(context).getDispatchContext();
>>>>>> +       
>>    
>>>>     
>>>>>> MethodContext methodContext = new
>>>> MethodContext(ctx,
>>>>>> localContext, null);
>>>>>> +       
>>    
>>>>     
>>>>>> try {
>>>>>> +       
>>    
>>>>     
>>>>>>   
>>>>    
>> SimpleMethod.runSimpleMethod(location,
>>>> method,
>>>>>> methodContext);
>>>>>> +       
>>    
>>>>     
>>>>>>   
>>>>    
>> context.putAll(methodContext.getResults());
>>>>>> +         
>>    
>>>>    }
>>>>>> catch (MiniLangException e) {
>>>>>> +       
>>    
>>>>     
>>>>>>       throw new
>>>> GeneralException("Error running
>>>>>> simple method at location [" + location +
>> "]",
>>>> e);
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> } else
>>>> {
>>>>>> +       
>>    
>>>>     
>>>>>> throw new GeneralException("For widget
>> script
>>>> actions the
>>>>>> script type is not yet supported for
>> location: ["
>>>> + location
>>>>>> + "]");
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +    }
>>>>>> +
>>>>>> +    public static class
>> Service
>>>> extends
>>>>>> ModelWidgetAction {
>>>>>> +        protected
>>>>>> FlexibleStringExpander serviceNameExdr;
>>>>>> +        protected
>>>>>> FlexibleMapAccessor<Map<String,
>>>> Object>>
>>>>>> resultMapNameAcsr;
>>>>>> +        protected
>>>>>> FlexibleStringExpander autoFieldMapExdr;
>>>>>> +        protected
>>>>>> Map<FlexibleMapAccessor<Object>,
>>>> Object>
>>>>>> fieldMap;
>>>>>> +
>>>>>> +        public
>>>> Service(ModelWidget
>>>>>> modelWidget, Element serviceElement) {
>>>>>> +           
>> super
>>>>>> (modelWidget, serviceElement);
>>>>>> +       
>>    
>>>>>> this.serviceNameExdr =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
>>>>>> +       
>>    
>>>>>> this.resultMapNameAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
>>>>>> +           
>> if
>>>>>> (this.resultMapNameAcsr.isEmpty())
>>>> this.resultMapNameAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
>>>>>> +       
>>    
>>>>>> this.autoFieldMapExdr =
>>>>>> 
>>>> 
>> FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
>>>>>> +       
>>    
>>>> this.fieldMap =
>>>>>> 
>> EntityFinderUtil.makeFieldMap(serviceElement);
>>>>>> +        }
>>>>>> +
>>>>>> +        @Override
>>>>>> +        public void
>>>>>> runAction(Map<String, Object>
>> context) {
>>>>>> +           
>> String
>>>>>> serviceNameExpanded =
>>>>>> 
>> this.serviceNameExdr.expandString(context);
>>>>>> +           
>> if
>>>>>> 
>> (UtilValidate.isEmpty(serviceNameExpanded)) {
>>>>>> +       
>>    
>>>>     
>>>>>> throw new
>> IllegalArgumentException("Service name
>>>> was empty,
>>>>>> expanded from: " +
>>>> this.serviceNameExdr.getOriginal());
>>>>>> +           
>> }
>>>>>> +
>>>>>> +           
>> String
>>>>>> autoFieldMapString =
>>>>>> 
>> this.autoFieldMapExdr.expandString(context);
>>>>>> +
>>>>>> +           
>> try {
>>>>>> +       
>>    
>>>>     
>>>>>> Map<String, Object> serviceContext =
>> null;
>>>>>> +         
>>    
>>>>    if
>>>>>> ("true".equals(autoFieldMapString)) {
>>>>>> +       
>>    
>>>>     
>>>>>>       DispatchContext dc =
>>>>>> 
>>>> 
>> WidgetWorker.getDispatcher(context).getDispatchContext();
>>>>>> +       
>>    
>>>>     
>>>>>>       // try a map called
>>>> "parameters", try it first
>>>>>> so values from here are overriden by
>> values in the
>>>> main
>>>>>> context
>>>>>> +       
>>    
>>>>     
>>>>>>       Map<String,
>> Object>
>>>> combinedMap =
>>>>>> FastMap.newInstance();
>>>>>> +       
>>    
>>>>     
>>>>>>       Map<String,
>> Object>
>>>> parametersObj =
>>>>>> 
>> UtilGenerics.toMap(context.get("parameters"));
>>>>>> +       
>>    
>>>>     
>>>>>>       if (parametersObj !=
>> null)
>>>> {
>>>>>> +       
>>    
>>>>     
>>>>>>          
>>>>>> combinedMap.putAll(parametersObj);
>>>>>> +       
>>    
>>>>     
>>>>>>       }
>>>>>> +       
>>    
>>>>     
>>>>>>   
>>>>     combinedMap.putAll(context);
>>>>>> +       
>>    
>>>>     
>>>>>>       serviceContext =
>>>>>> dc.makeValidContext(serviceNameExpanded,
>>>>>> ModelService.IN_PARAM, combinedMap);
>>>>>> +         
>>    
>>>>    }
>>>>>> else if
>>>> (UtilValidate.isNotEmpty(autoFieldMapString)
>>>>>> &&
>> !"false".equals(autoFieldMapString)) {
>>>>>> +       
>>    
>>>>     
>>>>>>   
>>>>     FlexibleMapAccessor<Object>
>> fieldFma
>>>> =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(autoFieldMapString);
>>>>>> +       
>>    
>>>>     
>>>>>>       Map<String,
>> Object>
>>>> autoFieldMap =
>>>>>> 
>> UtilGenerics.toMap(fieldFma.get(context));
>>>>>> +       
>>    
>>>>     
>>>>>>       if (autoFieldMap !=
>> null)
>>>> {
>>>>>> +       
>>    
>>>>     
>>>>>>       
>>>>     serviceContext =
>>>>>> 
>>>> 
>> WidgetWorker.getDispatcher(context).getDispatchContext().makeValidContext(serviceNameExpanded,
>>>>>> ModelService.IN_PARAM, autoFieldMap);
>>>>>> +       
>>    
>>>>     
>>>>>>       }
>>>>>> +         
>>    
>>>>    }
>>>>>> +         
>>    
>>>>    if
>>>>>> (serviceContext == null) {
>>>>>> +       
>>    
>>>>     
>>>>>>       serviceContext =
>>>> FastMap.newInstance();
>>>>>> +         
>>    
>>>>    }
>>>>>> +
>>>>>> +         
>>    
>>>>    if
>>>>>> (this.fieldMap != null) {
>>>>>> +       
>>    
>>>>     
>>>>>>      
>>>>>> 
>>>> 
>> EntityFinderUtil.expandFieldMapToContext(this.fieldMap,
>>>>>> context, serviceContext);
>>>>>> +         
>>    
>>>>    }
>>>>>> +
>>>>>> +       
>>    
>>>>     
>>>>>> Map<String, Object> result =
>>>>>> 
>>>> 
>> WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded,
>>>>>> serviceContext);
>>>>>> +
>>>>>> +         
>>    
>>>>    if
>>>>>> (!this.resultMapNameAcsr.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>>   
>>>>     this.resultMapNameAcsr.put(context,
>>>> result);
>>>>>> +       
>>    
>>>>     
>>>>>>       String queryString =
>>>>>> (String)result.get("queryString");
>>>>>> +       
>>    
>>>>     
>>>>>>      
>> context.put("queryString",
>>>> queryString);
>>>>>> +       
>>    
>>>>     
>>>>>>   
>>>>     context.put("queryStringMap",
>>>>>> result.get("queryStringMap"));
>>>>>> +       
>>    
>>>>     
>>>>>>       if
>>>> (UtilValidate.isNotEmpty(queryString)) {
>>>>>> +       
>>    
>>>>     
>>>>>>           try {
>>>>>> +       
>>    
>>>>     
>>>>>>           
>>>>     String
>>>>>> queryStringEncoded =
>>>> queryString.replaceAll("&",
>>>>>> "%26");
>>>>>> +       
>>    
>>>>     
>>>>>>          
>>    
>>>>>> context.put("queryStringEncoded",
>>>> queryStringEncoded);
>>>>>> +       
>>    
>>>>     
>>>>>>           } catch
>>>> (PatternSyntaxException
>>>>>> e) {
>>>>>> +
>>>>>> +       
>>    
>>>>     
>>>>>>           }
>>>>>> +       
>>    
>>>>     
>>>>>>       }
>>>>>> +         
>>    
>>>>    }
>>>>>> else {
>>>>>> +       
>>    
>>>>     
> 
>>>>>>      
>> context.putAll(result);
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>> catch
>>>>>> (GenericServiceException e) {
>>>>>> +       
>>    
>>>>     
>>>>>> String errMsg = "Error calling service
>> with name "
>>>> +
>>>>>> serviceNameExpanded + ": " +
>> e.toString();
>>>>>> +       
>>    
>>>>     
>>>>>> Debug.logError(e, errMsg, module);
>>>>>> +       
>>    
>>>>     
>>>>>> throw new
>> IllegalArgumentException(errMsg);
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +
>>>>>> +        public
>>>> FlexibleStringExpander
>>>>>> getServiceNameExdr() {
>>>>>> +           
>> return
>>>>>> this.serviceNameExdr;
>>>>>> +        }
>>>>>> +    }
>>>>>> +
>>>>>> +    public static class
>> EntityOne
>>>> extends
>>>>>> ModelWidgetAction {
>>>>>> +        protected
>>>> PrimaryKeyFinder
>>>>>> finder;
>>>>>> +
>>>>>> +        public
>>>> EntityOne(ModelWidget
>>>>>> modelWidget, Element entityOneElement) {
>>>>>> +           
>> super
>>>>>> (modelWidget, entityOneElement);
>>>>>> +           
>> finder
>>>> = new
>>>>>> PrimaryKeyFinder(entityOneElement);
>>>>>> +        }
>>>>>> +
>>>>>> +        @Override
>>>>>> +        public void
>>>>>> runAction(Map<String, Object>
>> context) {
>>>>>> +           
>> try {
>>>>>> +       
>>    
>>>>     
>>>>>> finder.runFind(context,
>>>>>> WidgetWorker.getDelegator(context));
>>>>>> +           
>> }
>>>> catch
>>>>>> (GeneralException e) {
>>>>>> +       
>>    
>>>>     
>>>>>> String errMsg = "Error doing entity query
>> by
>>>> condition: " +
>>>>>> e.toString();
>>>>>> +       
>>    
>>>>     
>>>>>> Debug.logError(e, errMsg, module);
>>>>>> +       
>>    
>>>>     
>>>>>> throw new
>> IllegalArgumentException(errMsg);
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +
>>>>>> +        public
>>>> PrimaryKeyFinder
>>>>>> getFinder() {
>>>>>> +           
>> return
>>>>>> this.finder;
>>>>>> +        }
>>>>>> +    }
>>>>>> +
>>>>>> +    public static class
>> EntityAnd
>>>> extends
>>>>>> ModelWidgetAction {
>>>>>> +        protected
>> ByAndFinder
>>>> finder;
>>>>>> +
>>>>>> +        public
>>>> EntityAnd(ModelWidget
>>>>>> modelWidget, Element entityAndElement) {
>>>>>> +           
>> super
>>>>>> (modelWidget, entityAndElement);
>>>>>> +           
>> finder
>>>> = new
>>>>>> ByAndFinder(entityAndElement);
>>>>>> +        }
>>>>>> +
>>>>>> +        @Override
>>>>>> +        public void
>>>>>> runAction(Map<String, Object>
>> context) {
>>>>>> +           
>> try {
>>>>>> +       
>>    
>>>>     
>>>>>> finder.runFind(context,
>>>>>> WidgetWorker.getDelegator(context));
>>>>>> +           
>> }
>>>> catch
>>>>>> (GeneralException e) {
>>>>>> +       
>>    
>>>>     
>>>>>> String errMsg = "Error doing entity query
>> by
>>>> condition: " +
>>>>>> e.toString();
>>>>>> +       
>>    
>>>>     
>>>>>> Debug.logError(e, errMsg, module);
>>>>>> +       
>>    
>>>>     
>>>>>> throw new
>> IllegalArgumentException(errMsg);
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +
>>>>>> +        public
>> ByAndFinder
>>>> getFinder()
>>>>>> {
>>>>>> +           
>> return
>>>>>> this.finder;
>>>>>> +        }
>>>>>> +    }
>>>>>> +
>>>>>> +    public static class
>> EntityCondition
>>>> extends
>>>>>> ModelWidgetAction {
>>>>>> +       
>> ByConditionFinder
>>>> finder;
>>>>>> +
>>>>>> +        public
>>>>>> EntityCondition(ModelWidget modelWidget,
>> Element
>>>>>> entityConditionElement) {
>>>>>> +           
>> super
>>>>>> (modelWidget, entityConditionElement);
>>>>>> +           
>> finder
>>>> = new
>>>>>> 
>> ByConditionFinder(entityConditionElement);
>>>>>> +        }
>>>>>> +
>>>>>> +        @Override
>>>>>> +        public void
>>>>>> runAction(Map<String, Object>
>> context) {
>>>>>> +           
>> try {
>>>>>> +       
>>    
>>>>     
>>>>>> finder.runFind(context,
>>>>>> WidgetWorker.getDelegator(context));
>>>>>> +           
>> }
>>>> catch
>>>>>> (GeneralException e) {
>>>>>> +       
>>    
>>>>     
>>>>>> String errMsg = "Error doing entity query
>> by
>>>> condition: " +
>>>>>> e.toString();
>>>>>> +       
>>    
>>>>     
>>>>>> Debug.logError(e, errMsg, module);
>>>>>> +       
>>    
>>>>     
>>>>>> throw new
>> IllegalArgumentException(errMsg);
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +
>>>>>> +        public
>>>> ByConditionFinder
>>>>>> getFinder() {
>>>>>> +           
>> return
>>>>>> this.finder;
>>>>>> +        }
>>>>>> +    }
>>>>>> +
>>>>>> +    public static class
>> GetRelatedOne
>>>> extends
>>>>>> ModelWidgetAction {
>>>>>> +        protected
>>>>>> FlexibleMapAccessor<Object>
>> valueNameAcsr;
>>>>>> +        protected
>>>>>> FlexibleMapAccessor<Object>
>>>> toValueNameAcsr;
>>>>>> +        protected
>> String
>>>>>> relationName;
>>>>>> +        protected
>> boolean
>>>> useCache;
>>>>>> +
>>>>>> +        public
>>>>>> GetRelatedOne(ModelWidget modelWidget,
>> Element
>>>>>> getRelatedOneElement) {
>>>>>> +           
>> super
>>>>>> (modelWidget, getRelatedOneElement);
>>>>>> +       
>>    
>>>>>> this.valueNameAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
>>>>>> +           
>> if
>>>>>> (this.valueNameAcsr.isEmpty())
>> this.valueNameAcsr
>>>> =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-name"));
>>>>>> +       
>>    
>>>>>> this.toValueNameAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
>>>>>> +           
>> if
>>>>>> (this.toValueNameAcsr.isEmpty())
>>>> this.toValueNameAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-name"));
>>>>>> +       
>>    
>>>>>> this.relationName =
>>>>>> 
>>>> 
>> getRelatedOneElement.getAttribute("relation-name");
>>>>>> +       
>>    
>>>> this.useCache =
>>>>>> 
>>>> 
>> "true".equals(getRelatedOneElement.getAttribute("use-cache"));
>>>>>> +        }
>>>>>> +
>>>>>> +        @Override
>>>>>> +        public void
>>>>>> runAction(Map<String, Object>
>> context) {
>>>>>> +           
>> Object
>>>>>> valueObject = valueNameAcsr.get(context);
>>>>>> +           
>> if
>>>> (valueObject
>>>>>> == null) {
>>>>>> +       
>>    
>>>>     
>>>>>> Debug.logVerbose("Value not found with
>> name: " +
>>>>>> valueNameAcsr + ", not getting
>> related...",
>>>> module);
>>>>>> +       
>>    
>>>>     
>>>>>> return;
>>>>>> +           
>> }
>>>>>> +           
>> if
>>>>>> (!(valueObject instanceof GenericValue))
>> {
>>>>>> +       
>>    
>>>>     
>>>>>> String errMsg = "Env variable for
>> value-name " +
>>>>>> valueNameAcsr.toString() + " is not a
>> GenericValue
>>>> object;
>>>>>> for the relation-name: " + relationName +
>> "]";
>>>>>> +       
>>    
>>>>     
>>>>>> Debug.logError(errMsg, module);
>>>>>> +       
>>    
>>>>     
>>>>>> throw new
>> IllegalArgumentException(errMsg);
>>>>>> +           
>> }
>>>>>> +       
>>    
>>>> GenericValue
>>>>>> value = (GenericValue) valueObject;
>>>>>> +           
>> try {
>>>>>> +         
>>    
>>>>    if
>>>>>> (useCache) {
>>>>>> +       
>>    
>>>>     
>>>>>>   
>>>>     toValueNameAcsr.put(context,
>>>>>> value.getRelatedOneCache(relationName));
>>>>>> +         
>>    
>>>>    }
>>>>>> else {
>>>>>> +       
>>    
>>>>     
>>>>>>   
>>>>     toValueNameAcsr.put(context,
>>>>>> value.getRelatedOne(relationName));
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>> catch
>>>>>> (GenericEntityException e) {
>>>>>> +       
>>    
>>>>     
>>>>>> String errMsg = "Problem getting related
>> one from
>>>> entity
>>>>>> with name " + value.getEntityName() + "
>> for the
>>>>>> relation-name: " + relationName + ": " +
>>>> e.getMessage();
>>>>>> +       
>>    
>>>>     
>>>>>> Debug.logError(e, errMsg, module);
>>>>>> +       
>>    
>>>>     
>>>>>> throw new
>> IllegalArgumentException(errMsg);
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +
>>>>>> +        public
>> String
>>>>>> getRelationName() {
>>>>>> +           
>> return
>>>>>> this.relationName;
>>>>>> +        }
>>>>>> +    }
>>>>>> +
>>>>>> +    public static class
>> GetRelated
>>>> extends
>>>>>> ModelWidgetAction {
>>>>>> +        protected
>>>>>> FlexibleMapAccessor<Object>
>> valueNameAcsr;
>>>>>> +        protected
>>>>>> 
>>>> 
>> FlexibleMapAccessor<List<GenericValue>>
>>>>>> listNameAcsr;
>>>>>> +        protected
>>>>>> FlexibleMapAccessor<Map<String,
>>>> Object>>
>>>>>> mapAcsr;
>>>>>> +        protected
>>>>>> 
>> FlexibleMapAccessor<List<String>>
>>>>>> orderByListAcsr;
>>>>>> +        protected
>> String
>>>>>> relationName;
>>>>>> +        protected
>> boolean
>>>> useCache;
>>>>>> +
>>>>>> +        public
>>>> GetRelated(ModelWidget
>>>>>> modelWidget, Element getRelatedElement) {
>>>>>> +           
>> super
>>>>>> (modelWidget, getRelatedElement);
>>>>>> +       
>>    
>>>>>> this.valueNameAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
>>>>>> +           
>> if
>>>>>> (this.valueNameAcsr.isEmpty())
>> this.valueNameAcsr
>>>> =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-name"));
>>>>>> +       
>>    
>>>>>> this.listNameAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
>>>>>> +           
>> if
>>>>>> (this.listNameAcsr.isEmpty())
>> this.listNameAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list-name"));
>>>>>> +       
>>    
>>>>>> this.relationName =
>>>>>> 
>> getRelatedElement.getAttribute("relation-name");
>>>>>> +       
>>    
>>>> this.mapAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
>>>>>> +           
>> if
>>>>>> (this.mapAcsr.isEmpty()) this.mapAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map-name"));
>>>>>> +       
>>    
>>>>>> this.orderByListAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
>>>>>> +           
>> if
>>>>>> (this.orderByListAcsr.isEmpty())
>>>> this.orderByListAcsr =
>>>>>> 
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list-name"));
>>>>>> +       
>>    
>>>> this.useCache =
>>>>>> 
>>>> 
>> "true".equals(getRelatedElement.getAttribute("use-cache"));
>>>>>> +        }
>>>>>> +
>>>>>> +        @Override
>>>>>> +        public void
>>>>>> runAction(Map<String, Object>
>> context) {
>>>>>> +           
>> Object
>>>>>> valueObject = valueNameAcsr.get(context);
>>>>>> +           
>> if
>>>> (valueObject
>>>>>> == null) {
>>>>>> +       
>>    
>>>>     
>>>>>> Debug.logVerbose("Value not found with
>> name: " +
>>>>>> valueNameAcsr + ", not getting
>> related...",
>>>> module);
>>>>>> +       
>>    
>>>>     
>>>>>> return;
>>>>>> +           
>> }
>>>>>> +           
>> if
>>>>>> (!(valueObject instanceof GenericValue))
>> {
>>>>>> +       
>>    
>>>>     
>>>>>> String errMsg = "Env variable for
>> value-name " +
>>>>>> valueNameAcsr.toString() + " is not a
>> GenericValue
>>>> object;
>>>>>> for the relation-name: " + relationName +
>> "]";
>>>>>> +       
>>    
>>>>     
>>>>>> Debug.logError(errMsg, module);
>>>>>> +       
>>    
>>>>     
>>>>>> throw new
>> IllegalArgumentException(errMsg);
>>>>>> +           
>> }
>>>>>> +       
>>    
>>>> GenericValue
>>>>>> value = (GenericValue) valueObject;
>>>>>> +       
>>    
>>>>>> List<String> orderByNames = null;
>>>>>> +           
>> if
>>>>>> (!orderByListAcsr.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>> orderByNames =
>> orderByListAcsr.get(context);
>>>>>> +           
>> }
>>>>>> +       
>>    
>>>> Map<String,
>>>>>> Object> constraintMap = null;
>>>>>> +           
>> if
>>>>>> (!mapAcsr.isEmpty()) {
>>>>>> +       
>>    
>>>>     
>>>>>> constraintMap = mapAcsr.get(context);
>>>>>> +           
>> }
>>>>>> +           
>> try {
>>>>>> +         
>>    
>>>>    if
>>>>>> (useCache) {
>>>>>> +       
>>    
>>>>     
>>>>>>      
>> listNameAcsr.put(context,
>>>>>> value.getRelatedCache(relationName,
>>>> constraintMap,
>>>>>> orderByNames));
>>>>>> +         
>>    
>>>>    }
>>>>>> else {
>>>>>> +       
>>    
>>>>     
>>>>>>      
>> listNameAcsr.put(context,
>>>>>> value.getRelated(relationName,
>> constraintMap,
>>>>>> orderByNames));
>>>>>> +         
>>    
>>>>    }
>>>>>> +           
>> }
>>>> catch
>>>>>> (GenericEntityException e) {
>>>>>> +       
>>    
>>>>     
>>>>>> String errMsg = "Problem getting related
>> from
>>>> entity with
>>>>>> name " + value.getEntityName() + " for
>> the
>>>> relation-name: "
>>>>>> + relationName + ": " + e.getMessage();
>>>>>> +       
>>    
>>>>     
>>>>>> Debug.logError(e, errMsg, module);
>>>>>> +       
>>    
>>>>     
>>>>>> throw new
>> IllegalArgumentException(errMsg);
>>>>>> +           
>> }
>>>>>> +        }
>>>>>> +
>>>>>> +        public
>> String
>>>>>> getRelationName() {
>>>>>> +           
>> return
>>>>>> this.relationName;
>>>>>> +        }
>>>>>> +    }
>>>>>> +}
>>>>>> 
>>>>>> Propchange:
>>>>>> 
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>>>> 
>>>> 
>> ------------------------------------------------------------------------------
>>>>>>       svn:eol-style =
>> native
>>>>>> 
>>>>>> Propchange:
>>>>>> 
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>>>> 
>>>> 
>> ------------------------------------------------------------------------------
>>>>>>       svn:keywords = "Date
>> Rev
>>>> Author URL Id"
>>>>>> 
>>>>>> Propchange:
>>>>>> 
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>>>> 
>>>> 
>> ------------------------------------------------------------------------------
>>>>>>       svn:mime-type =
>>>> text/plain
>>>>>> 
>>>>>> 
>>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>> 
>>>> 
>>> 
>>> 
>>> 
>> 
>> 
> 
> 
> 


Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Adrian Crum <ad...@yahoo.com>.
Because I've done it myself. ;-)

I agree that code can look redundant and not be copy and paste. The obvious ones are easy to spot because... well... they're *obvious*.

-Adrian

--- On Fri, 7/2/10, David E Jones <de...@me.com> wrote:

> From: David E Jones <de...@me.com>
> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> To: dev@ofbiz.apache.org
> Date: Friday, July 2, 2010, 5:44 PM
> 
> How do you know it was copy and paste?
> 
> It could very well have been different code written by
> different people and at different times, possibly even with
> no reference to the other code. Redundant similar code is
> annoying and nice to eliminate, but it's existence does not
> imply copy/paste, or even necessarily awareness of the other
> code.
> 
> -David
> 
> 
> On Jul 2, 2010, at 1:18 AM, Adrian Crum wrote:
> 
> > My new mantra: Just say no to copy and paste.
> > 
> > I'm questioning nearly all of the code I come across.
> > 
> > -Adrian
> > 
> > 
> > --- On Thu, 7/1/10, Scott Gray <sc...@hotwaxmedia.com>
> wrote:
> > 
> >> From: Scott Gray <sc...@hotwaxmedia.com>
> >> Subject: Re: svn commit: r959875 -
> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >> To: dev@ofbiz.apache.org
> >> Date: Thursday, July 1, 2010, 11:58 PM
> >> Yeah no worries.  I'd never
> >> really thought about it before until yesterday
> when I came
> >> across a problem in the
> ModelMenuAction.PropertyMap action,
> >> it replaces the existing uiLabelMap instead of
> adding to it
> >> like the ModelScreenAction version does. 
> Option was to
> >> either just copy and paste the screen version or
> take the
> >> plunge and sort it all out.
> >> 
> >> Regards
> >> Scott
> >> 
> >> On 2/07/2010, at 6:45 PM, Adrian Crum wrote:
> >> 
> >>> Thanks! That duplication always bothered me.
> >>> 
> >>> -Adrian
> >>> 
> >>> --- On Thu, 7/1/10, lektran@apache.org
> >> <le...@apache.org>
> >> wrote:
> >>> 
> >>>> From: lektran@apache.org
> >> <le...@apache.org>
> >>>> Subject: svn commit: r959875 -
> >>
> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>> To: commits@ofbiz.apache.org
> >>>> Date: Thursday, July 1, 2010, 11:38 PM
> >>>> Author: lektran
> >>>> Date: Fri Jul  2 06:38:52 2010
> >>>> New Revision: 959875
> >>>> 
> >>>> URL: http://svn.apache.org/viewvc?rev=959875&view=rev
> >>>> Log:
> >>>> Added a new class ModelWidgetAction which
> will
> >> serve to
> >>>> replace the duplicate classes
> ModelScreenAction,
> >>>> ModelFormAction and ModelMenuAction. 
> This
> >> class is
> >>>> virtually a direct copy of
> ModelScreenAction and
> >> its
> >>>> subclasses.  I'll work over the
> weekend to
> >> switch the
> >>>> existing classes to extend from
> ModelWidgetAction,
> >> remove
> >>>> their methods and then deprecate the
> shells that
> >> are left
> >>>> behind.
> >>>> 
> >>>> Added:
> >>>>     
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java   (with
> >>>> props)
> >>>> 
> >>>> Added:
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java?rev=959875&view=auto
> >>>> 
> >>
> ==============================================================================
> >>>> ---
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>> (added)
> >>>> +++
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>> Fri Jul  2 06:38:52 2010
> >>>> @@ -0,0 +1,700 @@
> >>>> 
> >>
> +/*******************************************************************************
> >>>> + * 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;
> >>>> +
> >>>> +import java.io.Serializable;
> >>>> +import java.text.MessageFormat;
> >>>> +import java.util.ArrayList;
> >>>> +import java.util.List;
> >>>> +import java.util.Locale;
> >>>> +import java.util.Map;
> >>>> +import java.util.TimeZone;
> >>>> +import
> java.util.regex.PatternSyntaxException;
> >>>> +
> >>>> +import javax.servlet.ServletContext;
> >>>> +import javax.servlet.http.HttpSession;
> >>>> +
> >>>> +import javolution.util.FastList;
> >>>> +import javolution.util.FastMap;
> >>>> +
> >>>> +import org.w3c.dom.Element;
> >>>> +import
> >> org.codehaus.groovy.runtime.InvokerHelper;
> >>>> +import org.ofbiz.base.util.BshUtil;
> >>>> +import org.ofbiz.base.util.Debug;
> >>>> +import
> org.ofbiz.base.util.GeneralException;
> >>>> +import org.ofbiz.base.util.GroovyUtil;
> >>>> +import org.ofbiz.base.util.ObjectType;
> >>>> +import org.ofbiz.base.util.StringUtil;
> >>>> +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.collections.FlexibleMapAccessor;
> >>>> +import
> >>>> 
> >>
> org.ofbiz.base.util.collections.ResourceBundleMapWrapper;
> >>>> +import
> >>
> org.ofbiz.base.util.string.FlexibleStringExpander;
> >>>> +import
> org.ofbiz.entity.GenericEntityException;
> >>>> +import org.ofbiz.entity.GenericValue;
> >>>> +import
> org.ofbiz.entity.finder.ByAndFinder;
> >>>> +import
> >> org.ofbiz.entity.finder.ByConditionFinder;
> >>>> +import
> org.ofbiz.entity.finder.EntityFinderUtil;
> >>>> +import
> org.ofbiz.entity.finder.PrimaryKeyFinder;
> >>>> +import
> org.ofbiz.minilang.MiniLangException;
> >>>> +import org.ofbiz.minilang.SimpleMethod;
> >>>> +import
> org.ofbiz.minilang.method.MethodContext;
> >>>> +import
> org.ofbiz.service.DispatchContext;
> >>>> +import
> >> org.ofbiz.service.GenericServiceException;
> >>>> +import org.ofbiz.service.ModelService;
> >>>> +
> >>>> +@SuppressWarnings("serial")
> >>>> +public abstract class ModelWidgetAction
> >> implements
> >>>> Serializable {
> >>>> +    public static final String
> module
> >> =
> >>>> ModelWidgetAction.class.getName();
> >>>> +
> >>>> +    protected ModelWidget
> modelWidget;
> >>>> +
> >>>> +    protected
> ModelWidgetAction() {}
> >>>> +
> >>>> +    public
> >> ModelWidgetAction(ModelWidget
> >>>> modelWidget, Element actionElement) {
> >>>> +       
> this.modelWidget =
> >>>> modelWidget;
> >>>> +        if
> >> (Debug.verboseOn())
> >>>> Debug.logVerbose("Reading widget action
> with name:
> >> " +
> >>>> actionElement.getNodeName(), module);
> >>>> +    }
> >>>> +
> >>>> +    public abstract void
> >>>> runAction(Map<String, Object>
> context)
> >> throws
> >>>> GeneralException;
> >>>> +
> >>>> +    public static
> >> List<ModelWidgetAction>
> >>>> readSubActions(ModelWidget modelWidget,
> Element
> >>>> parentElement) {
> >>>> +       
> >> List<ModelWidgetAction>
> >>>> actions = FastList.newInstance();
> >>>> +
> >>>> +        List<?
> extends
> >> Element>
> >>>> actionElementList =
> >>>> UtilXml.childElementList(parentElement);
> >>>> +        for (Element
> >> actionElement:
> >>>> actionElementList) {
> >>>> +           
> if
> >>>>
> ("set".equals(actionElement.getNodeName())) {
> >>>> +       
>    
> >>    
> >>>> actions.add(new SetField(modelWidget,
> >> actionElement));
> >>>> +           
> } else
> >> if
> >>>> 
> >>
> ("property-map".equals(actionElement.getNodeName())) {
> >>>> +       
>    
> >>    
> >>>> actions.add(new PropertyMap(modelWidget,
> >> actionElement));
> >>>> +           
> } else
> >> if
> >>>> 
> >>
> ("property-to-field".equals(actionElement.getNodeName())) {
> >>>> +       
>    
> >>    
> >>>> actions.add(new
> PropertyToField(modelWidget,
> >>>> actionElement));
> >>>> +           
> } else
> >> if
> >>>>
> ("script".equals(actionElement.getNodeName())) {
> >>>> +       
>    
> >>    
> >>>> actions.add(new Script(modelWidget,
> >> actionElement));
> >>>> +           
> } else
> >> if
> >>>>
> ("service".equals(actionElement.getNodeName())) {
> >>>> +       
>    
> >>    
> >>>> actions.add(new Service(modelWidget,
> >> actionElement));
> >>>> +           
> } else
> >> if
> >>>>
> ("entity-one".equals(actionElement.getNodeName()))
> >> {
> >>>> +       
>    
> >>    
> >>>> actions.add(new EntityOne(modelWidget,
> >> actionElement));
> >>>> +           
> } else
> >> if
> >>>>
> ("entity-and".equals(actionElement.getNodeName()))
> >> {
> >>>> +       
>    
> >>    
> >>>> actions.add(new EntityAnd(modelWidget,
> >> actionElement));
> >>>> +           
> } else
> >> if
> >>>> 
> >>
> ("entity-condition".equals(actionElement.getNodeName())) {
> >>>> +       
>    
> >>    
> >>>> actions.add(new
> EntityCondition(modelWidget,
> >>>> actionElement));
> >>>> +           
> } else
> >> if
> >>>> 
> >>
> ("get-related-one".equals(actionElement.getNodeName())) {
> >>>> +       
>    
> >>    
> >>>> actions.add(new
> GetRelatedOne(modelWidget,
> >> actionElement));
> >>>> +           
> } else
> >> if
> >>>> 
> >>
> ("get-related".equals(actionElement.getNodeName())) {
> >>>> +       
>    
> >>    
> >>>> actions.add(new GetRelated(modelWidget,
> >> actionElement));
> >>>> +           
> } else
> >> {
> >>>> +       
>    
> >>    
> >>>> throw new IllegalArgumentException("Action
> element
> >> not
> >>>> supported with name: " +
> >> actionElement.getNodeName());
> >>>> +           
> }
> >>>> +        }
> >>>> +
> >>>> +        return
> actions;
> >>>> +    }
> >>>> +
> >>>> +    public static void
> >>>>
> runSubActions(List<ModelWidgetAction>
> >> actions,
> >>>> Map<String, Object> context) throws
> >> GeneralException
> >>>> {
> >>>> +        if (actions
> == null)
> >> return;
> >>>> +
> >>>> +        for
> >> (ModelWidgetAction action:
> >>>> actions) {
> >>>> +           
> if
> >>>> (Debug.verboseOn())
> Debug.logVerbose("Running
> >> widget action
> >>>> " + action.getClass().getName(), module);
> >>>> +       
>    
> >>>> action.runAction(context);
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +    public static class
> SetField
> >> extends
> >>>> ModelWidgetAction {
> >>>> +        protected
> >>>> FlexibleMapAccessor<Object> field;
> >>>> +        protected
> >>>> FlexibleMapAccessor<Object>
> fromField;
> >>>> +        protected
> >>>> FlexibleStringExpander valueExdr;
> >>>> +        protected
> >>>> FlexibleStringExpander defaultExdr;
> >>>> +        protected
> >>>> FlexibleStringExpander globalExdr;
> >>>> +        protected
> String
> >> type;
> >>>> +        protected
> String
> >> toScope;
> >>>> +        protected
> String
> >> fromScope;
> >>>> +
> >>>> +        public
> >> SetField(ModelWidget
> >>>> modelWidget, Element setElement) {
> >>>> +           
> super
> >>>> (modelWidget, setElement);
> >>>> +       
>    
> >> this.field =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
> >>>> +       
>    
> >> this.fromField =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("from-field"));
> >>>> +       
>    
> >> this.valueExdr =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("value"));
> >>>> +       
>    
> >> this.defaultExdr
> >>>> =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("default-value"));
> >>>> +       
>    
> >> this.globalExdr
> >>>> =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> >>>> +       
>    
> >> this.type =
> >>>> setElement.getAttribute("type");
> >>>> +       
>    
> >> this.toScope =
> >>>> setElement.getAttribute("to-scope");
> >>>> +       
>    
> >> this.fromScope =
> >>>> setElement.getAttribute("from-scope");
> >>>> +           
> if
> >>>> (!this.fromField.isEmpty() &&
> >>>> !this.valueExdr.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>> throw new IllegalArgumentException("Cannot
> specify
> >> a
> >>>> from-field [" +
> >> setElement.getAttribute("from-field") + "]
> >>>> and a value [" +
> setElement.getAttribute("value")
> >> + "] on
> >>>> the set action in a widget");
> >>>> +           
> }
> >>>> +        }
> >>>> +
> >>>> +        @Override
> >>>> +        public void
> >>>> runAction(Map<String, Object>
> context) {
> >>>> +           
> String
> >> globalStr
> >>>> = this.globalExdr.expandString(context);
> >>>> +           
> //
> >> default to
> >>>> false
> >>>> +           
> boolean
> >> global =
> >>>> "true".equals(globalStr);
> >>>> +
> >>>> +           
> Object
> >> newValue
> >>>> = null;
> >>>> +           
> if
> >>>> (this.fromScope != null &&
> >>>> this.fromScope.equals("user")) {
> >>>> +         
>    
> >>   if
> >>>> (!this.fromField.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>>      HttpSession session =
> >> (HttpSession)
> >>>> context.get("session");
> >>>> +       
>    
> >>    
> >>>>      newValue =
> >>>> getInMemoryPersistedFromField(session,
> context);
> >>>> +       
>    
> >>    
> >>>>      if
> (Debug.verboseOn())
> >> Debug.logVerbose("In
> >>>> user getting value for field from [" +
> >>>> this.fromField.getOriginalName() + "]: "
> +
> >> newValue,
> >>>> module);
> >>>> +         
>    
> >>   }
> >>>> else if (!this.valueExdr.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>>      newValue =
> >> this.valueExdr.expand(context);
> >>>> +         
>    
> >>   }
> >>>> +           
> } else
> >> if
> >>>> (this.fromScope != null &&
> >>>> this.fromScope.equals("application")) {
> >>>> +         
>    
> >>   if
> >>>> (!this.fromField.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>>      ServletContext
> >> servletContext =
> >>>> (ServletContext)
> context.get("application");
> >>>> +       
>    
> >>    
> >>>>      newValue =
> >>>>
> getInMemoryPersistedFromField(servletContext,
> >> context);
> >>>> +       
>    
> >>    
> >>>>      if
> (Debug.verboseOn())
> >> Debug.logVerbose("In
> >>>> application getting value for field from
> [" +
> >>>> this.fromField.getOriginalName() + "]: "
> +
> >> newValue,
> >>>> module);
> >>>> +         
>    
> >>   }
> >>>> else if (!this.valueExdr.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>>      newValue =
> >>>> this.valueExdr.expandString(context);
> >>>> +         
>    
> >>   }
> >>>> +           
> } else
> >> {
> >>>> +         
>    
> >>   if
> >>>> (!this.fromField.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>>      newValue =
> >> this.fromField.get(context);
> >>>> +       
>    
> >>    
> >>>>      if
> (Debug.verboseOn())
> >>>> Debug.logVerbose("Getting value for field
> from ["
> >> +
> >>>> this.fromField.getOriginalName() + "]: "
> +
> >> newValue,
> >>>> module);
> >>>> +         
>    
> >>   }
> >>>> else if (!this.valueExdr.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>>      newValue =
> >> this.valueExdr.expand(context);
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >>>> +
> >>>> +           
> // If
> >> newValue
> >>>> is still empty, use the default value
> >>>> +           
> if
> >>>> (ObjectType.isEmpty(newValue) &&
> >>>> !this.defaultExdr.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>> newValue =
> this.defaultExdr.expand(context);
> >>>> +           
> }
> >>>> +
> >>>> +           
> if
> >>>> (UtilValidate.isNotEmpty(this.type)) {
> >>>> +         
>    
> >>   if
> >>>> ("NewMap".equals(this.type)) {
> >>>> +       
>    
> >>    
> >>>>      newValue =
> >> FastMap.newInstance();
> >>>> +         
>    
> >>   }
> >>>> else if ("NewList".equals(this.type)) {
> >>>> +       
>    

> >>    
> >>>>      newValue =
> >> FastList.newInstance();
> >>>> +         
>    
> >>   }
> >>>> else {
> >>>> +       
>    
> >>    
> >>>>      try {
> >>>> +       
>    
> >>    
> >>>>          newValue
> =
> >>>> ObjectType.simpleTypeConvert(newValue,
> this.type,
> >> null,
> >>>> (TimeZone) context.get("timeZone"),
> (Locale)
> >>>> context.get("locale"), true);
> >>>> +       
>    
> >>    
> >>>>      } catch
> (GeneralException
> >> e) {
> >>>> +       
>    
> >>    
> >>>>          String
> >> errMsg = "Could not
> >>>> convert field value for the field: [" +
> >>>> this.field.getOriginalName() + "] to the
> [" +
> >> this.type + "]
> >>>> type for the value [" + newValue + "]: "
> +
> >> e.toString();
> >>>> +       
>    
> >>    
> >>>>      
> >>    Debug.logError(e, errMsg,
> >>>> module);
> >>>> +       
>    
> >>    
> >>>>          throw
> new
> >>>> IllegalArgumentException(errMsg);
> >>>> +       
>    
> >>    
> >>>>      }
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >>>> +
> >>>> +           
> if
> >> (this.toScope
> >>>> != null &&
> this.toScope.equals("user")) {
> >>>> +       
>    
> >>    
> >>>> String originalName =
> >> this.field.getOriginalName();
> >>>> +       
>    
> >>    
> >>>> List<String> currentWidgetTrail =
> >>>> 
> >>
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> >>>> +       
>    
> >>    
> >>>> String newKey = "";
> >>>> +         
>    
> >>   if
> >>>> (currentWidgetTrail != null) {
> >>>> +       
>    
> >>    
> >>>>      newKey =
> >> StringUtil.join(currentWidgetTrail,
> >>>> "|");
> >>>> +         
>    
> >>   }
> >>>> +         
>    
> >>   if
> >>>> (UtilValidate.isNotEmpty(newKey)) {
> >>>> +       
>    
> >>    
> >>>>      newKey += "|";
> >>>> +         
>    
> >>   }
> >>>> +       
>    
> >>    
> >>>> newKey += originalName;
> >>>> +       
>    
> >>    
> >>>> HttpSession session =
> >> (HttpSession)context.get("session");
> >>>> +       
>    
> >>    
> >>>> session.setAttribute(newKey, newValue);
> >>>> +         
>    
> >>   if
> >>>> (Debug.verboseOn()) Debug.logVerbose("In
> user
> >> setting value
> >>>> for field from [" +
> this.field.getOriginalName() +
> >> "]: " +
> >>>> newValue, module);
> >>>> +           
> } else
> >> if
> >>>> (this.toScope != null &&
> >>>> this.toScope.equals("application")) {
> >>>> +       
>    
> >>    
> >>>> String originalName =
> >> this.field.getOriginalName();
> >>>> +       
>    
> >>    
> >>>> List<String> currentWidgetTrail =
> >>>> 
> >>
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> >>>> +       
>    
> >>    
> >>>> String newKey = "";
> >>>> +         
>    
> >>   if
> >>>> (currentWidgetTrail != null) {
> >>>> +       
>    
> >>    
> >>>>      newKey =
> >> StringUtil.join(currentWidgetTrail,
> >>>> "|");
> >>>> +         
>    
> >>   }
> >>>> +         
>    
> >>   if
> >>>> (UtilValidate.isNotEmpty(newKey)) {
> >>>> +       
>    
> >>    
> >>>>      newKey += "|";
> >>>> +         
>    
> >>   }
> >>>> +       
>    
> >>    
> >>>> newKey += originalName;
> >>>> +       
>    
> >>    
> >>>> ServletContext servletContext =
> >>>>
> (ServletContext)context.get("application");
> >>>> +       
>    
> >>    
> >>>> servletContext.setAttribute(newKey,
> newValue);
> >>>> +         
>    
> >>   if
> >>>> (Debug.verboseOn()) Debug.logVerbose("In
> >> application setting
> >>>> value for field from [" +
> >> this.field.getOriginalName() + "]:
> >>>> " + newValue, module);
> >>>> +           
> } else
> >> {
> >>>> +         
>    
> >>   //
> >>>> only do this if it is not global, if
> global ONLY
> >> put it in
> >>>> the global context
> >>>> +         
>    
> >>   if
> >>>> (!global) {
> >>>> +       
>    
> >>    
> >>>>      if
> (Debug.verboseOn())
> >>>> Debug.logVerbose("Setting field [" +
> >>>> this.field.getOriginalName() + "] to
> value: " +
> >> newValue,
> >>>> module);
> >>>> +       
>    
> >>    
> >>>>     
> this.field.put(context,
> >> newValue);
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >>>> +
> >>>> +           
> if
> >> (global) {
> >>>> +       
>    
> >>    
> >>>> Map<String, Object> globalCtx =
> >>>> 
> >>
> UtilGenerics.checkMap(context.get("globalContext"));
> >>>> +         
>    
> >>   if
> >>>> (globalCtx != null) {
> >>>> +       
>    
> >>    
> >>>>     
> this.field.put(globalCtx,
> >> newValue);
> >>>> +         
>    
> >>   }
> >>>> else {
> >>>> +       
>    
> >>    
> >>>>     
> this.field.put(context,
> >> newValue);
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >>>> +
> >>>> +           
> // this
> >> is a
> >>>> hack for backward compatibility with the
> JPublish
> >> page
> >>>> object
> >>>> +       
>    
> >> Map<String,
> >>>> Object> page =
> >>>>
> UtilGenerics.checkMap(context.get("page"));
> >>>> +           
> if
> >> (page !=
> >>>> null) {
> >>>> +       
>    
> >>    
> >>>> this.field.put(page, newValue);
> >>>> +           
> }
> >>>> +        }
> >>>> +
> >>>> +        public
> Object
> >>>> getInMemoryPersistedFromField(Object
> storeAgent,
> >>>> Map<String, Object> context) {
> >>>> +           
> Object
> >> newValue
> >>>> = null;
> >>>> +           
> String
> >>>> originalName =
> this.fromField.getOriginalName();
> >>>> +       
>    
> >>>> List<String> currentWidgetTrail =
> >>>> 
> >>
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> >>>> +       
>    
> >>>> List<String> trailList = new
> >>>> ArrayList<String>();
> >>>> +           
> if
> >>>> (currentWidgetTrail != null) {
> >>>> +       
>    
> >>    
> >>>> trailList.addAll(currentWidgetTrail);
> >>>> +           
> }
> >>>> +
> >>>> +           
> for
> >> (int
> >>>> i=trailList.size(); i >= 0; i--) {
> >>>> +       
>    
> >>    
> >>>> List<String> subTrail =
> >> trailList.subList(0,i);
> >>>> +       
>    
> >>    
> >>>> String newKey = null;
> >>>> +         
>    
> >>   if
> >>>> (subTrail.size() > 0)
> >>>> +       
>    
> >>    
> >>>>      newKey =
> >> StringUtil.join(subTrail, "|") + "|"
> >>>> + originalName;
> >>>> +       
>    
> >>    
> >>>> else
> >>>> +       
>    
> >>    
> >>>>      newKey =
> originalName;
> >>>> +
> >>>> +         
>    
> >>   if
> >>>> (storeAgent instanceof ServletContext) {
> >>>> +       
>    
> >>    
> >>>>      newValue =
> >>>> 
> >>
> ((ServletContext)storeAgent).getAttribute(newKey);
> >>>> +         
>    
> >>   }
> >>>> else if (storeAgent instanceof
> HttpSession) {
> >>>> +       
>    
> >>    
> >>>>      newValue =
> >>>>
> ((HttpSession)storeAgent).getAttribute(newKey);
> >>>> +         
>    
> >>   }
> >>>> +         
>    
> >>   if
> >>>> (newValue != null) {
> >>>> +       
>    
> >>    
> >>>>      break;
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >>>> +           
> return
> >>>> newValue;
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +    public static class
> PropertyMap
> >> extends
> >>>> ModelWidgetAction {
> >>>> +        protected
> >>>> FlexibleStringExpander resourceExdr;
> >>>> +        protected
> >>>> 
> >>
> FlexibleMapAccessor<ResourceBundleMapWrapper>
> >>>> mapNameAcsr;
> >>>> +        protected
> >>>> FlexibleStringExpander globalExdr;
> >>>> +
> >>>> +        public
> >> PropertyMap(ModelWidget
> >>>> modelWidget, Element setElement) {
> >>>> +           
> super
> >>>> (modelWidget, setElement);
> >>>> +       
>    
> >>>> this.resourceExdr =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
> >>>> +       
>    
> >> this.mapNameAcsr
> >>>> =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("map-name"));
> >>>> +       
>    
> >> this.globalExdr
> >>>> =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> >>>> +        }
> >>>> +
> >>>> +        @Override
> >>>> +        public void
> >>>> runAction(Map<String, Object>
> context) {
> >>>> +           
> String
> >> globalStr
> >>>> = this.globalExdr.expandString(context);
> >>>> +           
> //
> >> default to
> >>>> false
> >>>> +           
> boolean
> >> global =
> >>>> "true".equals(globalStr);
> >>>> +
> >>>> +           
> Locale
> >> locale =
> >>>> (Locale) context.get("locale");
> >>>> +           
> String
> >> resource
> >>>> = this.resourceExdr.expandString(context,
> >> locale);
> >>>> +
> >>>> +       
>    
> >>>> ResourceBundleMapWrapper existingPropMap
> =
> >>>> this.mapNameAcsr.get(context);
> >>>> +           
> if
> >>>> (existingPropMap == null) {
> >>>> +       
>    
> >>    
> >>>> this.mapNameAcsr.put(context,
> >>>>
> UtilProperties.getResourceBundleMap(resource,
> >> locale,
> >>>> context));
> >>>> +           
> } else
> >> {
> >>>> +       
>    
> >>    
> >>>> try {
> >>>> +       
>    
> >>    
> >>>>     
> >>>> 
> >>
> existingPropMap.addBottomResourceBundle(resource);
> >>>> +         
>    
> >>   }
> >>>> catch (IllegalArgumentException e) {
> >>>> +       
>    
> >>    
> >>>>      // log the error, but
> >> don't let it kill
> >>>> everything just for a typo or bad char in
> an l10n
> >> file
> >>>> +       
>    
> >>    
> >>>>      Debug.logError(e,
> "Error
> >> adding resource
> >>>> bundle [" + resource + "]: " +
> e.toString(),
> >> module);
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >>>> +
> >>>> +           
> if
> >> (global) {
> >>>> +       
>    
> >>    
> >>>> Map<String, Object> globalCtx =
> >>>> 
> >>
> UtilGenerics.checkMap(context.get("globalContext"));
> >>>> +         
>    
> >>   if
> >>>> (globalCtx != null) {
> >>>> +       
>    
> >>    
> >>>>     
> ResourceBundleMapWrapper
> >> globalExistingPropMap
> >>>> = this.mapNameAcsr.get(globalCtx);
> >>>> +       
>    
> >>    
> >>>>      if
> (globalExistingPropMap
> >> == null) {
> >>>> +       
>    
> >>    
> >>>>      
> >>    this.mapNameAcsr.put(globalCtx,
> >>>>
> UtilProperties.getResourceBundleMap(resource,
> >> locale,
> >>>> context));
> >>>> +       
>    
> >>    
> >>>>      } else {
> >>>> +       
>    
> >>    
> >>>>          // is it
> the
> >> same object? if not
> >>>> add it in here too...
> >>>> +       
>    
> >>    
> >>>>          if
> >> (existingPropMap !=
> >>>> globalExistingPropMap) {
> >>>> +       
>    
> >>    
> >>>>          
> >>    try {
> >>>> +       
>    
> >>    
> >>>>           
>   
> >>   
> >>>> 
> >>
> globalExistingPropMap.addBottomResourceBundle(resource);
> >>>> +       
>    
> >>    
> >>>>          
> >>    } catch
> >>>> (IllegalArgumentException e) {
> >>>> +       
>    
> >>    
> >>>>           
>   
> >>    //
> >>>> log the error, but don't let it kill
> everything
> >> just for a
> >>>> typo or bad char in an l10n file
> >>>> +       
>    
> >>    
> >>>>           
>   
> >>   
> >>>> Debug.logError(e, "Error adding resource
> bundle ["
> >> +
> >>>> resource + "]: " + e.toString(), module);
> >>>> +       
>    
> >>    
> >>>>          
> >>    }
> >>>> +       
>    
> >>    
> >>>>          }
> >>>> +       
>    
> >>    
> >>>>      }
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +    public static class
> PropertyToField
> >> extends
> >>>> ModelWidgetAction {
> >>>> +
> >>>> +        protected
> >>>> FlexibleStringExpander resourceExdr;
> >>>> +        protected
> >>>> FlexibleStringExpander propertyExdr;
> >>>> +        protected
> >>>> FlexibleMapAccessor<Object>
> fieldAcsr;
> >>>> +        protected
> >>>> FlexibleStringExpander defaultExdr;
> >>>> +        protected
> boolean
> >> noLocale;
> >>>> +        protected
> >>>> FlexibleMapAccessor<List<? extends
> >> Object>>
> >>>> argListAcsr;
> >>>> +        protected
> >>>> FlexibleStringExpander globalExdr;
> >>>> +
> >>>> +        public
> >>>> PropertyToField(ModelWidget modelWidget,
> Element
> >> setElement)
> >>>> {
> >>>> +           
> super
> >>>> (modelWidget, setElement);
> >>>> +       
>    
> >>>> this.resourceExdr =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
> >>>> +       
>    
> >>>> this.propertyExdr =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
> >>>> +       
>    
> >> this.fieldAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
> >>>> +       
>    
> >> this.defaultExdr
> >>>> =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("default"));
> >>>> +       
>    
> >> this.noLocale =
> >>>> 
> >>
> "true".equals(setElement.getAttribute("no-locale"));
> >>>> +       
>    
> >> this.argListAcsr
> >>>> =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("arg-list-name"));
> >>>> +       
>    
> >> this.globalExdr
> >>>> =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> >>>> +        }
> >>>> +
> >>>> +        @Override
> >>>> +        public void
> >>>> runAction(Map<String, Object>
> context) {
> >>>> +       
>    
> >> //String
> >>>> globalStr =
> >> this.globalExdr.expandString(context);
> >>>> +           
> //
> >> default to
> >>>> false
> >>>> +       
>    
> >> //boolean global
> >>>> = "true".equals(globalStr);
> >>>> +
> >>>> +           
> Locale
> >> locale =
> >>>> (Locale) context.get("locale");
> >>>> +           
> String
> >> resource
> >>>> = this.resourceExdr.expandString(context,
> >> locale);
> >>>> +           
> String
> >> property
> >>>> = this.propertyExdr.expandString(context,
> >> locale);
> >>>> +
> >>>> +           
> String
> >> value =
> >>>> null;
> >>>> +           
> if
> >> (noLocale) {
> >>>> +       
>    
> >>    
> >>>> value =
> UtilProperties.getPropertyValue(resource,
> >>>> property);
> >>>> +           
> } else
> >> {
> >>>> +       
>    
> >>    
> >>>> value =
> UtilProperties.getMessage(resource,
> >> property,
> >>>> locale);
> >>>> +           
> }
> >>>> +           
> if
> >>>> (UtilValidate.isEmpty(value)) {
> >>>> +       
>    
> >>    
> >>>> value =
> this.defaultExdr.expandString(context);
> >>>> +           
> }
> >>>> +
> >>>> +           
> // note
> >> that
> >>>> expanding the value string here will
> handle
> >> defaultValue and
> >>>> the string from
> >>>> +       
>    
> >> //  the
> >>>> properties file; if we decide later that
> we don't
> >> want the
> >>>> string from the properties
> >>>> +       
>    
> >> //  file to
> >>>> be expanded we should just expand the
> defaultValue
> >> at the
> >>>> beginning of this method.
> >>>> +           
> value
> >> =
> >>>>
> FlexibleStringExpander.expandString(value,
> >> context);
> >>>> +
> >>>> +           
> if
> >>>> (!argListAcsr.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>> List<? extends Object> argList =
> >>>> argListAcsr.get(context);
> >>>> +         
>    
> >>   if
> >>>> (UtilValidate.isNotEmpty(argList)) {
> >>>> +       
>    
> >>    
> >>>>      value =
> >> MessageFormat.format(value,
> >>>> argList.toArray());
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >>>> +       
>    
> >>>> fieldAcsr.put(context, value);
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +    public static class Script
> extends
> >>>> ModelWidgetAction {
> >>>> +        protected
> static
> >> final
> >>>> Object[] EMPTY_ARGS = {};
> >>>> +        protected
> String
> >> location;
> >>>> +        protected
> String
> >> method;
> >>>> +
> >>>> +        public
> >> Script(ModelWidget
> >>>> modelWidget, Element scriptElement) {
> >>>> +           
> super
> >>>> (modelWidget, scriptElement);
> >>>> +           
> String
> >>>> scriptLocation =
> >> scriptElement.getAttribute("location");
> >>>> +       
>    
> >> this.location =
> >>>>
> WidgetWorker.getScriptLocation(scriptLocation);
> >>>> +       
>    
> >> this.method =
> >>>>
> WidgetWorker.getScriptMethodName(scriptLocation);
> >>>> +        }
> >>>> +
> >>>> +        @Override
> >>>> +        public void
> >>>> runAction(Map<String, Object>
> context)
> >> throws
> >>>> GeneralException {
> >>>> +           
> if
> >>>> (location.endsWith(".bsh")) {
> >>>> +       
>    
> >>    
> >>>> try {
> >>>> +       
>    
> >>    
> >>>>  
> >>    BshUtil.runBshAtLocation(location,
> >> context);
> >>>> +         
>    
> >>   }
> >>>> catch (GeneralException e) {
> >>>> +       
>    
> >>    
> >>>>      throw new
> >> GeneralException("Error running BSH
> >>>> script at location [" + location + "]",
> e);
> >>>> +         
>    
> >>   }
> >>>> +           
> } else
> >> if
> >>>> (location.endsWith(".groovy")) {
> >>>> +       
>    
> >>    
> >>>> try {
> >>>> +       
>    
> >>    
> >>>>      groovy.lang.Script
> script
> >> =
> >>>> 
> >>
> InvokerHelper.createScript(GroovyUtil.getScriptClassFromLocation(location),
> >>>> GroovyUtil.getBinding(context));
> >>>> +       
>    
> >>    
> >>>>      if
> >> (UtilValidate.isEmpty(method)) {
> >>>> +       
>    
> >>    
> >>>>      
> >>    script.run();
> >>>> +       
>    
> >>    
> >>>>      } else {
> >>>> +       
>    
> >>    
> >>>>      
> >>    script.invokeMethod(method,
> >>>> EMPTY_ARGS);
> >>>> +       
>    
> >>    
> >>>>      }
> >>>> +         
>    
> >>   }
> >>>> catch (GeneralException e) {
> >>>> +       
>    
> >>    
> >>>>      throw new
> >> GeneralException("Error running
> >>>> Groovy script at location [" + location +
> "]",
> >> e);
> >>>> +         
>    
> >>   }
> >>>> +           
> } else
> >> if
> >>>> (location.endsWith(".xml")) {
> >>>> +       
>    
> >>    
> >>>> Map<String, Object> localContext =
> >>>> FastMap.newInstance();
> >>>> +       
>    
> >>    
> >>>> localContext.putAll(context);
> >>>> +       
>    
> >>    
> >>>> DispatchContext ctx =
> >>>> 
> >>
> WidgetWorker.getDispatcher(context).getDispatchContext();
> >>>> +       
>    
> >>    
> >>>> MethodContext methodContext = new
> >> MethodContext(ctx,
> >>>> localContext, null);
> >>>> +       
>    
> >>    
> >>>> try {
> >>>> +       
>    
> >>    
> >>>>  
> >>   
> SimpleMethod.runSimpleMethod(location,
> >> method,
> >>>> methodContext);
> >>>> +       
>    
> >>    
> >>>>  
> >>   
> context.putAll(methodContext.getResults());
> >>>> +         
>    
> >>   }
> >>>> catch (MiniLangException e) {
> >>>> +       
>    
> >>    
> >>>>      throw new
> >> GeneralException("Error running
> >>>> simple method at location [" + location +
> "]",
> >> e);
> >>>> +         
>    
> >>   }
> >>>> +           
> } else
> >> {
> >>>> +       
>    
> >>    
> >>>> throw new GeneralException("For widget
> script
> >> actions the
> >>>> script type is not yet supported for
> location: ["
> >> + location
> >>>> + "]");
> >>>> +           
> }
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +    public static class
> Service
> >> extends
> >>>> ModelWidgetAction {
> >>>> +        protected
> >>>> FlexibleStringExpander serviceNameExdr;
> >>>> +        protected
> >>>> FlexibleMapAccessor<Map<String,
> >> Object>>
> >>>> resultMapNameAcsr;
> >>>> +        protected
> >>>> FlexibleStringExpander autoFieldMapExdr;
> >>>> +        protected
> >>>> Map<FlexibleMapAccessor<Object>,
> >> Object>
> >>>> fieldMap;
> >>>> +
> >>>> +        public
> >> Service(ModelWidget
> >>>> modelWidget, Element serviceElement) {
> >>>> +           
> super
> >>>> (modelWidget, serviceElement);
> >>>> +       
>    
> >>>> this.serviceNameExdr =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
> >>>> +       
>    
> >>>> this.resultMapNameAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
> >>>> +           
> if
> >>>> (this.resultMapNameAcsr.isEmpty())
> >> this.resultMapNameAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
> >>>> +       
>    
> >>>> this.autoFieldMapExdr =
> >>>> 
> >>
> FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
> >>>> +       
>    
> >> this.fieldMap =
> >>>>
> EntityFinderUtil.makeFieldMap(serviceElement);
> >>>> +        }
> >>>> +
> >>>> +        @Override
> >>>> +        public void
> >>>> runAction(Map<String, Object>
> context) {
> >>>> +           
> String
> >>>> serviceNameExpanded =
> >>>>
> this.serviceNameExdr.expandString(context);
> >>>> +           
> if
> >>>>
> (UtilValidate.isEmpty(serviceNameExpanded)) {
> >>>> +       
>    
> >>    
> >>>> throw new
> IllegalArgumentException("Service name
> >> was empty,
> >>>> expanded from: " +
> >> this.serviceNameExdr.getOriginal());
> >>>> +           
> }
> >>>> +
> >>>> +           
> String
> >>>> autoFieldMapString =
> >>>>
> this.autoFieldMapExdr.expandString(context);
> >>>> +
> >>>> +           
> try {
> >>>> +       
>    
> >>    
> >>>> Map<String, Object> serviceContext =
> null;
> >>>> +         
>    
> >>   if
> >>>> ("true".equals(autoFieldMapString)) {
> >>>> +       
>    
> >>    
> >>>>      DispatchContext dc =
> >>>> 
> >>
> WidgetWorker.getDispatcher(context).getDispatchContext();
> >>>> +       
>    
> >>    
> >>>>      // try a map called
> >> "parameters", try it first
> >>>> so values from here are overriden by
> values in the
> >> main
> >>>> context
> >>>> +       
>    
> >>    
> >>>>      Map<String,
> Object>
> >> combinedMap =
> >>>> FastMap.newInstance();
> >>>> +       
>    
> >>    
> >>>>      Map<String,
> Object>
> >> parametersObj =
> >>>>
> UtilGenerics.toMap(context.get("parameters"));
> >>>> +       
>    
> >>    
> >>>>      if (parametersObj !=
> null)
> >> {
> >>>> +       
>    
> >>    
> >>>>         
> >>>> combinedMap.putAll(parametersObj);
> >>>> +       
>    
> >>    
> >>>>      }
> >>>> +       
>    
> >>    
> >>>>  
> >>    combinedMap.putAll(context);
> >>>> +       
>    
> >>    
> >>>>      serviceContext =
> >>>> dc.makeValidContext(serviceNameExpanded,
> >>>> ModelService.IN_PARAM, combinedMap);
> >>>> +         
>    
> >>   }
> >>>> else if
> >> (UtilValidate.isNotEmpty(autoFieldMapString)
> >>>> &&
> !"false".equals(autoFieldMapString)) {
> >>>> +       
>    
> >>    
> >>>>  
> >>    FlexibleMapAccessor<Object>
> fieldFma
> >> =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(autoFieldMapString);
> >>>> +       
>    
> >>    
> >>>>      Map<String,
> Object>
> >> autoFieldMap =
> >>>>
> UtilGenerics.toMap(fieldFma.get(context));
> >>>> +       
>    
> >>    
> >>>>      if (autoFieldMap !=
> null)
> >> {
> >>>> +       
>    
> >>    
> >>>>      
> >>    serviceContext =
> >>>> 
> >>
> WidgetWorker.getDispatcher(context).getDispatchContext().makeValidContext(serviceNameExpanded,
> >>>> ModelService.IN_PARAM, autoFieldMap);
> >>>> +       
>    
> >>    
> >>>>      }
> >>>> +         
>    
> >>   }
> >>>> +         
>    
> >>   if
> >>>> (serviceContext == null) {
> >>>> +       
>    
> >>    
> >>>>      serviceContext =
> >> FastMap.newInstance();
> >>>> +         
>    
> >>   }
> >>>> +
> >>>> +         
>    
> >>   if
> >>>> (this.fieldMap != null) {
> >>>> +       
>    
> >>    
> >>>>     
> >>>> 
> >>
> EntityFinderUtil.expandFieldMapToContext(this.fieldMap,
> >>>> context, serviceContext);
> >>>> +         
>    
> >>   }
> >>>> +
> >>>> +       
>    
> >>    
> >>>> Map<String, Object> result =
> >>>> 
> >>
> WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded,
> >>>> serviceContext);
> >>>> +
> >>>> +         
>    
> >>   if
> >>>> (!this.resultMapNameAcsr.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>>  
> >>    this.resultMapNameAcsr.put(context,
> >> result);
> >>>> +       
>    
> >>    
> >>>>      String queryString =
> >>>> (String)result.get("queryString");
> >>>> +       
>    
> >>    
> >>>>     
> context.put("queryString",
> >> queryString);
> >>>> +       
>    
> >>    
> >>>>  
> >>    context.put("queryStringMap",
> >>>> result.get("queryStringMap"));
> >>>> +       
>    
> >>    
> >>>>      if
> >> (UtilValidate.isNotEmpty(queryString)) {
> >>>> +       
>    
> >>    
> >>>>          try {
> >>>> +       
>    
> >>    
> >>>>          
> >>    String
> >>>> queryStringEncoded =
> >> queryString.replaceAll("&",
> >>>> "%26");
> >>>> +       
>    
> >>    
> >>>>         
>    
> >>>> context.put("queryStringEncoded",
> >> queryStringEncoded);
> >>>> +       
>    
> >>    
> >>>>          } catch
> >> (PatternSyntaxException
> >>>> e) {
> >>>> +
> >>>> +       
>    
> >>    
> >>>>          }
> >>>> +       
>    
> >>    
> >>>>      }
> >>>> +         
>    
> >>   }
> >>>> else {
> >>>> +       
>    
> >>    

> >>>>     
> context.putAll(result);
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >> catch
> >>>> (GenericServiceException e) {
> >>>> +       
>    
> >>    
> >>>> String errMsg = "Error calling service
> with name "
> >> +
> >>>> serviceNameExpanded + ": " +
> e.toString();
> >>>> +       
>    
> >>    
> >>>> Debug.logError(e, errMsg, module);
> >>>> +       
>    
> >>    
> >>>> throw new
> IllegalArgumentException(errMsg);
> >>>> +           
> }
> >>>> +        }
> >>>> +
> >>>> +        public
> >> FlexibleStringExpander
> >>>> getServiceNameExdr() {
> >>>> +           
> return
> >>>> this.serviceNameExdr;
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +    public static class
> EntityOne
> >> extends
> >>>> ModelWidgetAction {
> >>>> +        protected
> >> PrimaryKeyFinder
> >>>> finder;
> >>>> +
> >>>> +        public
> >> EntityOne(ModelWidget
> >>>> modelWidget, Element entityOneElement) {
> >>>> +           
> super
> >>>> (modelWidget, entityOneElement);
> >>>> +           
> finder
> >> = new
> >>>> PrimaryKeyFinder(entityOneElement);
> >>>> +        }
> >>>> +
> >>>> +        @Override
> >>>> +        public void
> >>>> runAction(Map<String, Object>
> context) {
> >>>> +           
> try {
> >>>> +       
>    
> >>    
> >>>> finder.runFind(context,
> >>>> WidgetWorker.getDelegator(context));
> >>>> +           
> }
> >> catch
> >>>> (GeneralException e) {
> >>>> +       
>    
> >>    
> >>>> String errMsg = "Error doing entity query
> by
> >> condition: " +
> >>>> e.toString();
> >>>> +       
>    
> >>    
> >>>> Debug.logError(e, errMsg, module);
> >>>> +       
>    
> >>    
> >>>> throw new
> IllegalArgumentException(errMsg);
> >>>> +           
> }
> >>>> +        }
> >>>> +
> >>>> +        public
> >> PrimaryKeyFinder
> >>>> getFinder() {
> >>>> +           
> return
> >>>> this.finder;
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +    public static class
> EntityAnd
> >> extends
> >>>> ModelWidgetAction {
> >>>> +        protected
> ByAndFinder
> >> finder;
> >>>> +
> >>>> +        public
> >> EntityAnd(ModelWidget
> >>>> modelWidget, Element entityAndElement) {
> >>>> +           
> super
> >>>> (modelWidget, entityAndElement);
> >>>> +           
> finder
> >> = new
> >>>> ByAndFinder(entityAndElement);
> >>>> +        }
> >>>> +
> >>>> +        @Override
> >>>> +        public void
> >>>> runAction(Map<String, Object>
> context) {
> >>>> +           
> try {
> >>>> +       
>    
> >>    
> >>>> finder.runFind(context,
> >>>> WidgetWorker.getDelegator(context));
> >>>> +           
> }
> >> catch
> >>>> (GeneralException e) {
> >>>> +       
>    
> >>    
> >>>> String errMsg = "Error doing entity query
> by
> >> condition: " +
> >>>> e.toString();
> >>>> +       
>    
> >>    
> >>>> Debug.logError(e, errMsg, module);
> >>>> +       
>    
> >>    
> >>>> throw new
> IllegalArgumentException(errMsg);
> >>>> +           
> }
> >>>> +        }
> >>>> +
> >>>> +        public
> ByAndFinder
> >> getFinder()
> >>>> {
> >>>> +           
> return
> >>>> this.finder;
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +    public static class
> EntityCondition
> >> extends
> >>>> ModelWidgetAction {
> >>>> +       
> ByConditionFinder
> >> finder;
> >>>> +
> >>>> +        public
> >>>> EntityCondition(ModelWidget modelWidget,
> Element
> >>>> entityConditionElement) {
> >>>> +           
> super
> >>>> (modelWidget, entityConditionElement);
> >>>> +           
> finder
> >> = new
> >>>>
> ByConditionFinder(entityConditionElement);
> >>>> +        }
> >>>> +
> >>>> +        @Override
> >>>> +        public void
> >>>> runAction(Map<String, Object>
> context) {
> >>>> +           
> try {
> >>>> +       
>    
> >>    
> >>>> finder.runFind(context,
> >>>> WidgetWorker.getDelegator(context));
> >>>> +           
> }
> >> catch
> >>>> (GeneralException e) {
> >>>> +       
>    
> >>    
> >>>> String errMsg = "Error doing entity query
> by
> >> condition: " +
> >>>> e.toString();
> >>>> +       
>    
> >>    
> >>>> Debug.logError(e, errMsg, module);
> >>>> +       
>    
> >>    
> >>>> throw new
> IllegalArgumentException(errMsg);
> >>>> +           
> }
> >>>> +        }
> >>>> +
> >>>> +        public
> >> ByConditionFinder
> >>>> getFinder() {
> >>>> +           
> return
> >>>> this.finder;
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +    public static class
> GetRelatedOne
> >> extends
> >>>> ModelWidgetAction {
> >>>> +        protected
> >>>> FlexibleMapAccessor<Object>
> valueNameAcsr;
> >>>> +        protected
> >>>> FlexibleMapAccessor<Object>
> >> toValueNameAcsr;
> >>>> +        protected
> String
> >>>> relationName;
> >>>> +        protected
> boolean
> >> useCache;
> >>>> +
> >>>> +        public
> >>>> GetRelatedOne(ModelWidget modelWidget,
> Element
> >>>> getRelatedOneElement) {
> >>>> +           
> super
> >>>> (modelWidget, getRelatedOneElement);
> >>>> +       
>    
> >>>> this.valueNameAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
> >>>> +           
> if
> >>>> (this.valueNameAcsr.isEmpty())
> this.valueNameAcsr
> >> =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-name"));
> >>>> +       
>    
> >>>> this.toValueNameAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
> >>>> +           
> if
> >>>> (this.toValueNameAcsr.isEmpty())
> >> this.toValueNameAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-name"));
> >>>> +       
>    
> >>>> this.relationName =
> >>>> 
> >>
> getRelatedOneElement.getAttribute("relation-name");
> >>>> +       
>    
> >> this.useCache =
> >>>> 
> >>
> "true".equals(getRelatedOneElement.getAttribute("use-cache"));
> >>>> +        }
> >>>> +
> >>>> +        @Override
> >>>> +        public void
> >>>> runAction(Map<String, Object>
> context) {
> >>>> +           
> Object
> >>>> valueObject = valueNameAcsr.get(context);
> >>>> +           
> if
> >> (valueObject
> >>>> == null) {
> >>>> +       
>    
> >>    
> >>>> Debug.logVerbose("Value not found with
> name: " +
> >>>> valueNameAcsr + ", not getting
> related...",
> >> module);
> >>>> +       
>    
> >>    
> >>>> return;
> >>>> +           
> }
> >>>> +           
> if
> >>>> (!(valueObject instanceof GenericValue))
> {
> >>>> +       
>    
> >>    
> >>>> String errMsg = "Env variable for
> value-name " +
> >>>> valueNameAcsr.toString() + " is not a
> GenericValue
> >> object;
> >>>> for the relation-name: " + relationName +
> "]";
> >>>> +       
>    
> >>    
> >>>> Debug.logError(errMsg, module);
> >>>> +       
>    
> >>    
> >>>> throw new
> IllegalArgumentException(errMsg);
> >>>> +           
> }
> >>>> +       
>    
> >> GenericValue
> >>>> value = (GenericValue) valueObject;
> >>>> +           
> try {
> >>>> +         
>    
> >>   if
> >>>> (useCache) {
> >>>> +       
>    
> >>    
> >>>>  
> >>    toValueNameAcsr.put(context,
> >>>> value.getRelatedOneCache(relationName));
> >>>> +         
>    
> >>   }
> >>>> else {
> >>>> +       
>    
> >>    
> >>>>  
> >>    toValueNameAcsr.put(context,
> >>>> value.getRelatedOne(relationName));
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >> catch
> >>>> (GenericEntityException e) {
> >>>> +       
>    
> >>    
> >>>> String errMsg = "Problem getting related
> one from
> >> entity
> >>>> with name " + value.getEntityName() + "
> for the
> >>>> relation-name: " + relationName + ": " +
> >> e.getMessage();
> >>>> +       
>    
> >>    
> >>>> Debug.logError(e, errMsg, module);
> >>>> +       
>    
> >>    
> >>>> throw new
> IllegalArgumentException(errMsg);
> >>>> +           
> }
> >>>> +        }
> >>>> +
> >>>> +        public
> String
> >>>> getRelationName() {
> >>>> +           
> return
> >>>> this.relationName;
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +    public static class
> GetRelated
> >> extends
> >>>> ModelWidgetAction {
> >>>> +        protected
> >>>> FlexibleMapAccessor<Object>
> valueNameAcsr;
> >>>> +        protected
> >>>> 
> >>
> FlexibleMapAccessor<List<GenericValue>>
> >>>> listNameAcsr;
> >>>> +        protected
> >>>> FlexibleMapAccessor<Map<String,
> >> Object>>
> >>>> mapAcsr;
> >>>> +        protected
> >>>>
> FlexibleMapAccessor<List<String>>
> >>>> orderByListAcsr;
> >>>> +        protected
> String
> >>>> relationName;
> >>>> +        protected
> boolean
> >> useCache;
> >>>> +
> >>>> +        public
> >> GetRelated(ModelWidget
> >>>> modelWidget, Element getRelatedElement) {
> >>>> +           
> super
> >>>> (modelWidget, getRelatedElement);
> >>>> +       
>    
> >>>> this.valueNameAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
> >>>> +           
> if
> >>>> (this.valueNameAcsr.isEmpty())
> this.valueNameAcsr
> >> =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-name"));
> >>>> +       
>    
> >>>> this.listNameAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
> >>>> +           
> if
> >>>> (this.listNameAcsr.isEmpty())
> this.listNameAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list-name"));
> >>>> +       
>    
> >>>> this.relationName =
> >>>>
> getRelatedElement.getAttribute("relation-name");
> >>>> +       
>    
> >> this.mapAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
> >>>> +           
> if
> >>>> (this.mapAcsr.isEmpty()) this.mapAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map-name"));
> >>>> +       
>    
> >>>> this.orderByListAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
> >>>> +           
> if
> >>>> (this.orderByListAcsr.isEmpty())
> >> this.orderByListAcsr =
> >>>> 
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list-name"));
> >>>> +       
>    
> >> this.useCache =
> >>>> 
> >>
> "true".equals(getRelatedElement.getAttribute("use-cache"));
> >>>> +        }
> >>>> +
> >>>> +        @Override
> >>>> +        public void
> >>>> runAction(Map<String, Object>
> context) {
> >>>> +           
> Object
> >>>> valueObject = valueNameAcsr.get(context);
> >>>> +           
> if
> >> (valueObject
> >>>> == null) {
> >>>> +       
>    
> >>    
> >>>> Debug.logVerbose("Value not found with
> name: " +
> >>>> valueNameAcsr + ", not getting
> related...",
> >> module);
> >>>> +       
>    
> >>    
> >>>> return;
> >>>> +           
> }
> >>>> +           
> if
> >>>> (!(valueObject instanceof GenericValue))
> {
> >>>> +       
>    
> >>    
> >>>> String errMsg = "Env variable for
> value-name " +
> >>>> valueNameAcsr.toString() + " is not a
> GenericValue
> >> object;
> >>>> for the relation-name: " + relationName +
> "]";
> >>>> +       
>    
> >>    
> >>>> Debug.logError(errMsg, module);
> >>>> +       
>    
> >>    
> >>>> throw new
> IllegalArgumentException(errMsg);
> >>>> +           
> }
> >>>> +       
>    
> >> GenericValue
> >>>> value = (GenericValue) valueObject;
> >>>> +       
>    
> >>>> List<String> orderByNames = null;
> >>>> +           
> if
> >>>> (!orderByListAcsr.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>> orderByNames =
> orderByListAcsr.get(context);
> >>>> +           
> }
> >>>> +       
>    
> >> Map<String,
> >>>> Object> constraintMap = null;
> >>>> +           
> if
> >>>> (!mapAcsr.isEmpty()) {
> >>>> +       
>    
> >>    
> >>>> constraintMap = mapAcsr.get(context);
> >>>> +           
> }
> >>>> +           
> try {
> >>>> +         
>    
> >>   if
> >>>> (useCache) {
> >>>> +       
>    
> >>    
> >>>>     
> listNameAcsr.put(context,
> >>>> value.getRelatedCache(relationName,
> >> constraintMap,
> >>>> orderByNames));
> >>>> +         
>    
> >>   }
> >>>> else {
> >>>> +       
>    
> >>    
> >>>>     
> listNameAcsr.put(context,
> >>>> value.getRelated(relationName,
> constraintMap,
> >>>> orderByNames));
> >>>> +         
>    
> >>   }
> >>>> +           
> }
> >> catch
> >>>> (GenericEntityException e) {
> >>>> +       
>    
> >>    
> >>>> String errMsg = "Problem getting related
> from
> >> entity with
> >>>> name " + value.getEntityName() + " for
> the
> >> relation-name: "
> >>>> + relationName + ": " + e.getMessage();
> >>>> +       
>    
> >>    
> >>>> Debug.logError(e, errMsg, module);
> >>>> +       
>    
> >>    
> >>>> throw new
> IllegalArgumentException(errMsg);
> >>>> +           
> }
> >>>> +        }
> >>>> +
> >>>> +        public
> String
> >>>> getRelationName() {
> >>>> +           
> return
> >>>> this.relationName;
> >>>> +        }
> >>>> +    }
> >>>> +}
> >>>> 
> >>>> Propchange:
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>> 
> >>
> ------------------------------------------------------------------------------
> >>>>      svn:eol-style =
> native
> >>>> 
> >>>> Propchange:
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>> 
> >>
> ------------------------------------------------------------------------------
> >>>>      svn:keywords = "Date
> Rev
> >> Author URL Id"
> >>>> 
> >>>> Propchange:
> >>>> 
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>>> 
> >>
> ------------------------------------------------------------------------------
> >>>>      svn:mime-type =
> >> text/plain
> >>>> 
> >>>> 
> >>>> 
> >>> 
> >>> 
> >>> 
> >> 
> >> 
> > 
> > 
> > 
> 
> 


      

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by David E Jones <de...@me.com>.
How do you know it was copy and paste?

It could very well have been different code written by different people and at different times, possibly even with no reference to the other code. Redundant similar code is annoying and nice to eliminate, but it's existence does not imply copy/paste, or even necessarily awareness of the other code.

-David


On Jul 2, 2010, at 1:18 AM, Adrian Crum wrote:

> My new mantra: Just say no to copy and paste.
> 
> I'm questioning nearly all of the code I come across.
> 
> -Adrian
> 
> 
> --- On Thu, 7/1/10, Scott Gray <sc...@hotwaxmedia.com> wrote:
> 
>> From: Scott Gray <sc...@hotwaxmedia.com>
>> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> To: dev@ofbiz.apache.org
>> Date: Thursday, July 1, 2010, 11:58 PM
>> Yeah no worries.  I'd never
>> really thought about it before until yesterday when I came
>> across a problem in the ModelMenuAction.PropertyMap action,
>> it replaces the existing uiLabelMap instead of adding to it
>> like the ModelScreenAction version does.  Option was to
>> either just copy and paste the screen version or take the
>> plunge and sort it all out.
>> 
>> Regards
>> Scott
>> 
>> On 2/07/2010, at 6:45 PM, Adrian Crum wrote:
>> 
>>> Thanks! That duplication always bothered me.
>>> 
>>> -Adrian
>>> 
>>> --- On Thu, 7/1/10, lektran@apache.org
>> <le...@apache.org>
>> wrote:
>>> 
>>>> From: lektran@apache.org
>> <le...@apache.org>
>>>> Subject: svn commit: r959875 -
>> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> To: commits@ofbiz.apache.org
>>>> Date: Thursday, July 1, 2010, 11:38 PM
>>>> Author: lektran
>>>> Date: Fri Jul  2 06:38:52 2010
>>>> New Revision: 959875
>>>> 
>>>> URL: http://svn.apache.org/viewvc?rev=959875&view=rev
>>>> Log:
>>>> Added a new class ModelWidgetAction which will
>> serve to
>>>> replace the duplicate classes ModelScreenAction,
>>>> ModelFormAction and ModelMenuAction.  This
>> class is
>>>> virtually a direct copy of ModelScreenAction and
>> its
>>>> subclasses.  I'll work over the weekend to
>> switch the
>>>> existing classes to extend from ModelWidgetAction,
>> remove
>>>> their methods and then deprecate the shells that
>> are left
>>>> behind.
>>>> 
>>>> Added:
>>>>     
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java   (with
>>>> props)
>>>> 
>>>> Added:
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java?rev=959875&view=auto
>>>> 
>> ==============================================================================
>>>> ---
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> (added)
>>>> +++
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> Fri Jul  2 06:38:52 2010
>>>> @@ -0,0 +1,700 @@
>>>> 
>> +/*******************************************************************************
>>>> + * 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;
>>>> +
>>>> +import java.io.Serializable;
>>>> +import java.text.MessageFormat;
>>>> +import java.util.ArrayList;
>>>> +import java.util.List;
>>>> +import java.util.Locale;
>>>> +import java.util.Map;
>>>> +import java.util.TimeZone;
>>>> +import java.util.regex.PatternSyntaxException;
>>>> +
>>>> +import javax.servlet.ServletContext;
>>>> +import javax.servlet.http.HttpSession;
>>>> +
>>>> +import javolution.util.FastList;
>>>> +import javolution.util.FastMap;
>>>> +
>>>> +import org.w3c.dom.Element;
>>>> +import
>> org.codehaus.groovy.runtime.InvokerHelper;
>>>> +import org.ofbiz.base.util.BshUtil;
>>>> +import org.ofbiz.base.util.Debug;
>>>> +import org.ofbiz.base.util.GeneralException;
>>>> +import org.ofbiz.base.util.GroovyUtil;
>>>> +import org.ofbiz.base.util.ObjectType;
>>>> +import org.ofbiz.base.util.StringUtil;
>>>> +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.collections.FlexibleMapAccessor;
>>>> +import
>>>> 
>> org.ofbiz.base.util.collections.ResourceBundleMapWrapper;
>>>> +import
>> org.ofbiz.base.util.string.FlexibleStringExpander;
>>>> +import org.ofbiz.entity.GenericEntityException;
>>>> +import org.ofbiz.entity.GenericValue;
>>>> +import org.ofbiz.entity.finder.ByAndFinder;
>>>> +import
>> org.ofbiz.entity.finder.ByConditionFinder;
>>>> +import org.ofbiz.entity.finder.EntityFinderUtil;
>>>> +import org.ofbiz.entity.finder.PrimaryKeyFinder;
>>>> +import org.ofbiz.minilang.MiniLangException;
>>>> +import org.ofbiz.minilang.SimpleMethod;
>>>> +import org.ofbiz.minilang.method.MethodContext;
>>>> +import org.ofbiz.service.DispatchContext;
>>>> +import
>> org.ofbiz.service.GenericServiceException;
>>>> +import org.ofbiz.service.ModelService;
>>>> +
>>>> +@SuppressWarnings("serial")
>>>> +public abstract class ModelWidgetAction
>> implements
>>>> Serializable {
>>>> +    public static final String module
>> =
>>>> ModelWidgetAction.class.getName();
>>>> +
>>>> +    protected ModelWidget modelWidget;
>>>> +
>>>> +    protected ModelWidgetAction() {}
>>>> +
>>>> +    public
>> ModelWidgetAction(ModelWidget
>>>> modelWidget, Element actionElement) {
>>>> +        this.modelWidget =
>>>> modelWidget;
>>>> +        if
>> (Debug.verboseOn())
>>>> Debug.logVerbose("Reading widget action with name:
>> " +
>>>> actionElement.getNodeName(), module);
>>>> +    }
>>>> +
>>>> +    public abstract void
>>>> runAction(Map<String, Object> context)
>> throws
>>>> GeneralException;
>>>> +
>>>> +    public static
>> List<ModelWidgetAction>
>>>> readSubActions(ModelWidget modelWidget, Element
>>>> parentElement) {
>>>> +       
>> List<ModelWidgetAction>
>>>> actions = FastList.newInstance();
>>>> +
>>>> +        List<? extends
>> Element>
>>>> actionElementList =
>>>> UtilXml.childElementList(parentElement);
>>>> +        for (Element
>> actionElement:
>>>> actionElementList) {
>>>> +            if
>>>> ("set".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new SetField(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> 
>> ("property-map".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new PropertyMap(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> 
>> ("property-to-field".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new PropertyToField(modelWidget,
>>>> actionElement));
>>>> +            } else
>> if
>>>> ("script".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new Script(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> ("service".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new Service(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> ("entity-one".equals(actionElement.getNodeName()))
>> {
>>>> +           
>>    
>>>> actions.add(new EntityOne(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> ("entity-and".equals(actionElement.getNodeName()))
>> {
>>>> +           
>>    
>>>> actions.add(new EntityAnd(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> 
>> ("entity-condition".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new EntityCondition(modelWidget,
>>>> actionElement));
>>>> +            } else
>> if
>>>> 
>> ("get-related-one".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new GetRelatedOne(modelWidget,
>> actionElement));
>>>> +            } else
>> if
>>>> 
>> ("get-related".equals(actionElement.getNodeName())) {
>>>> +           
>>    
>>>> actions.add(new GetRelated(modelWidget,
>> actionElement));
>>>> +            } else
>> {
>>>> +           
>>    
>>>> throw new IllegalArgumentException("Action element
>> not
>>>> supported with name: " +
>> actionElement.getNodeName());
>>>> +            }
>>>> +        }
>>>> +
>>>> +        return actions;
>>>> +    }
>>>> +
>>>> +    public static void
>>>> runSubActions(List<ModelWidgetAction>
>> actions,
>>>> Map<String, Object> context) throws
>> GeneralException
>>>> {
>>>> +        if (actions == null)
>> return;
>>>> +
>>>> +        for
>> (ModelWidgetAction action:
>>>> actions) {
>>>> +            if
>>>> (Debug.verboseOn()) Debug.logVerbose("Running
>> widget action
>>>> " + action.getClass().getName(), module);
>>>> +           
>>>> action.runAction(context);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class SetField
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>>>> FlexibleMapAccessor<Object> field;
>>>> +        protected
>>>> FlexibleMapAccessor<Object> fromField;
>>>> +        protected
>>>> FlexibleStringExpander valueExdr;
>>>> +        protected
>>>> FlexibleStringExpander defaultExdr;
>>>> +        protected
>>>> FlexibleStringExpander globalExdr;
>>>> +        protected String
>> type;
>>>> +        protected String
>> toScope;
>>>> +        protected String
>> fromScope;
>>>> +
>>>> +        public
>> SetField(ModelWidget
>>>> modelWidget, Element setElement) {
>>>> +            super
>>>> (modelWidget, setElement);
>>>> +           
>> this.field =
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
>>>> +           
>> this.fromField =
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("from-field"));
>>>> +           
>> this.valueExdr =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("value"));
>>>> +           
>> this.defaultExdr
>>>> =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("default-value"));
>>>> +           
>> this.globalExdr
>>>> =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>>>> +           
>> this.type =
>>>> setElement.getAttribute("type");
>>>> +           
>> this.toScope =
>>>> setElement.getAttribute("to-scope");
>>>> +           
>> this.fromScope =
>>>> setElement.getAttribute("from-scope");
>>>> +            if
>>>> (!this.fromField.isEmpty() &&
>>>> !this.valueExdr.isEmpty()) {
>>>> +           
>>    
>>>> throw new IllegalArgumentException("Cannot specify
>> a
>>>> from-field [" +
>> setElement.getAttribute("from-field") + "]
>>>> and a value [" + setElement.getAttribute("value")
>> + "] on
>>>> the set action in a widget");
>>>> +            }
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            String
>> globalStr
>>>> = this.globalExdr.expandString(context);
>>>> +            //
>> default to
>>>> false
>>>> +            boolean
>> global =
>>>> "true".equals(globalStr);
>>>> +
>>>> +            Object
>> newValue
>>>> = null;
>>>> +            if
>>>> (this.fromScope != null &&
>>>> this.fromScope.equals("user")) {
>>>> +             
>>   if
>>>> (!this.fromField.isEmpty()) {
>>>> +           
>>    
>>>>      HttpSession session =
>> (HttpSession)
>>>> context.get("session");
>>>> +           
>>    
>>>>      newValue =
>>>> getInMemoryPersistedFromField(session, context);
>>>> +           
>>    
>>>>      if (Debug.verboseOn())
>> Debug.logVerbose("In
>>>> user getting value for field from [" +
>>>> this.fromField.getOriginalName() + "]: " +
>> newValue,
>>>> module);
>>>> +             
>>   }
>>>> else if (!this.valueExdr.isEmpty()) {
>>>> +           
>>    
>>>>      newValue =
>> this.valueExdr.expand(context);
>>>> +             
>>   }
>>>> +            } else
>> if
>>>> (this.fromScope != null &&
>>>> this.fromScope.equals("application")) {
>>>> +             
>>   if
>>>> (!this.fromField.isEmpty()) {
>>>> +           
>>    
>>>>      ServletContext
>> servletContext =
>>>> (ServletContext) context.get("application");
>>>> +           
>>    
>>>>      newValue =
>>>> getInMemoryPersistedFromField(servletContext,
>> context);
>>>> +           
>>    
>>>>      if (Debug.verboseOn())
>> Debug.logVerbose("In
>>>> application getting value for field from [" +
>>>> this.fromField.getOriginalName() + "]: " +
>> newValue,
>>>> module);
>>>> +             
>>   }
>>>> else if (!this.valueExdr.isEmpty()) {
>>>> +           
>>    
>>>>      newValue =
>>>> this.valueExdr.expandString(context);
>>>> +             
>>   }
>>>> +            } else
>> {
>>>> +             
>>   if
>>>> (!this.fromField.isEmpty()) {
>>>> +           
>>    
>>>>      newValue =
>> this.fromField.get(context);
>>>> +           
>>    
>>>>      if (Debug.verboseOn())
>>>> Debug.logVerbose("Getting value for field from ["
>> +
>>>> this.fromField.getOriginalName() + "]: " +
>> newValue,
>>>> module);
>>>> +             
>>   }
>>>> else if (!this.valueExdr.isEmpty()) {
>>>> +           
>>    
>>>>      newValue =
>> this.valueExdr.expand(context);
>>>> +             
>>   }
>>>> +            }
>>>> +
>>>> +            // If
>> newValue
>>>> is still empty, use the default value
>>>> +            if
>>>> (ObjectType.isEmpty(newValue) &&
>>>> !this.defaultExdr.isEmpty()) {
>>>> +           
>>    
>>>> newValue = this.defaultExdr.expand(context);
>>>> +            }
>>>> +
>>>> +            if
>>>> (UtilValidate.isNotEmpty(this.type)) {
>>>> +             
>>   if
>>>> ("NewMap".equals(this.type)) {
>>>> +           
>>    
>>>>      newValue =
>> FastMap.newInstance();
>>>> +             
>>   }
>>>> else if ("NewList".equals(this.type)) {
>>>> +           
>>    
>>>>      newValue =
>> FastList.newInstance();
>>>> +             
>>   }
>>>> else {
>>>> +           
>>    
>>>>      try {
>>>> +           
>>    
>>>>          newValue =
>>>> ObjectType.simpleTypeConvert(newValue, this.type,
>> null,
>>>> (TimeZone) context.get("timeZone"), (Locale)
>>>> context.get("locale"), true);
>>>> +           
>>    
>>>>      } catch (GeneralException
>> e) {
>>>> +           
>>    
>>>>          String
>> errMsg = "Could not
>>>> convert field value for the field: [" +
>>>> this.field.getOriginalName() + "] to the [" +
>> this.type + "]
>>>> type for the value [" + newValue + "]: " +
>> e.toString();
>>>> +           
>>    
>>>>      
>>    Debug.logError(e, errMsg,
>>>> module);
>>>> +           
>>    
>>>>          throw new
>>>> IllegalArgumentException(errMsg);
>>>> +           
>>    
>>>>      }
>>>> +             
>>   }
>>>> +            }
>>>> +
>>>> +            if
>> (this.toScope
>>>> != null && this.toScope.equals("user")) {
>>>> +           
>>    
>>>> String originalName =
>> this.field.getOriginalName();
>>>> +           
>>    
>>>> List<String> currentWidgetTrail =
>>>> 
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>>>> +           
>>    
>>>> String newKey = "";
>>>> +             
>>   if
>>>> (currentWidgetTrail != null) {
>>>> +           
>>    
>>>>      newKey =
>> StringUtil.join(currentWidgetTrail,
>>>> "|");
>>>> +             
>>   }
>>>> +             
>>   if
>>>> (UtilValidate.isNotEmpty(newKey)) {
>>>> +           
>>    
>>>>      newKey += "|";
>>>> +             
>>   }
>>>> +           
>>    
>>>> newKey += originalName;
>>>> +           
>>    
>>>> HttpSession session =
>> (HttpSession)context.get("session");
>>>> +           
>>    
>>>> session.setAttribute(newKey, newValue);
>>>> +             
>>   if
>>>> (Debug.verboseOn()) Debug.logVerbose("In user
>> setting value
>>>> for field from [" + this.field.getOriginalName() +
>> "]: " +
>>>> newValue, module);
>>>> +            } else
>> if
>>>> (this.toScope != null &&
>>>> this.toScope.equals("application")) {
>>>> +           
>>    
>>>> String originalName =
>> this.field.getOriginalName();
>>>> +           
>>    
>>>> List<String> currentWidgetTrail =
>>>> 
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>>>> +           
>>    
>>>> String newKey = "";
>>>> +             
>>   if
>>>> (currentWidgetTrail != null) {
>>>> +           
>>    
>>>>      newKey =
>> StringUtil.join(currentWidgetTrail,
>>>> "|");
>>>> +             
>>   }
>>>> +             
>>   if
>>>> (UtilValidate.isNotEmpty(newKey)) {
>>>> +           
>>    
>>>>      newKey += "|";
>>>> +             
>>   }
>>>> +           
>>    
>>>> newKey += originalName;
>>>> +           
>>    
>>>> ServletContext servletContext =
>>>> (ServletContext)context.get("application");
>>>> +           
>>    
>>>> servletContext.setAttribute(newKey, newValue);
>>>> +             
>>   if
>>>> (Debug.verboseOn()) Debug.logVerbose("In
>> application setting
>>>> value for field from [" +
>> this.field.getOriginalName() + "]:
>>>> " + newValue, module);
>>>> +            } else
>> {
>>>> +             
>>   //
>>>> only do this if it is not global, if global ONLY
>> put it in
>>>> the global context
>>>> +             
>>   if
>>>> (!global) {
>>>> +           
>>    
>>>>      if (Debug.verboseOn())
>>>> Debug.logVerbose("Setting field [" +
>>>> this.field.getOriginalName() + "] to value: " +
>> newValue,
>>>> module);
>>>> +           
>>    
>>>>      this.field.put(context,
>> newValue);
>>>> +             
>>   }
>>>> +            }
>>>> +
>>>> +            if
>> (global) {
>>>> +           
>>    
>>>> Map<String, Object> globalCtx =
>>>> 
>> UtilGenerics.checkMap(context.get("globalContext"));
>>>> +             
>>   if
>>>> (globalCtx != null) {
>>>> +           
>>    
>>>>      this.field.put(globalCtx,
>> newValue);
>>>> +             
>>   }
>>>> else {
>>>> +           
>>    
>>>>      this.field.put(context,
>> newValue);
>>>> +             
>>   }
>>>> +            }
>>>> +
>>>> +            // this
>> is a
>>>> hack for backward compatibility with the JPublish
>> page
>>>> object
>>>> +           
>> Map<String,
>>>> Object> page =
>>>> UtilGenerics.checkMap(context.get("page"));
>>>> +            if
>> (page !=
>>>> null) {
>>>> +           
>>    
>>>> this.field.put(page, newValue);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public Object
>>>> getInMemoryPersistedFromField(Object storeAgent,
>>>> Map<String, Object> context) {
>>>> +            Object
>> newValue
>>>> = null;
>>>> +            String
>>>> originalName = this.fromField.getOriginalName();
>>>> +           
>>>> List<String> currentWidgetTrail =
>>>> 
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>>>> +           
>>>> List<String> trailList = new
>>>> ArrayList<String>();
>>>> +            if
>>>> (currentWidgetTrail != null) {
>>>> +           
>>    
>>>> trailList.addAll(currentWidgetTrail);
>>>> +            }
>>>> +
>>>> +            for
>> (int
>>>> i=trailList.size(); i >= 0; i--) {
>>>> +           
>>    
>>>> List<String> subTrail =
>> trailList.subList(0,i);
>>>> +           
>>    
>>>> String newKey = null;
>>>> +             
>>   if
>>>> (subTrail.size() > 0)
>>>> +           
>>    
>>>>      newKey =
>> StringUtil.join(subTrail, "|") + "|"
>>>> + originalName;
>>>> +           
>>    
>>>> else
>>>> +           
>>    
>>>>      newKey = originalName;
>>>> +
>>>> +             
>>   if
>>>> (storeAgent instanceof ServletContext) {
>>>> +           
>>    
>>>>      newValue =
>>>> 
>> ((ServletContext)storeAgent).getAttribute(newKey);
>>>> +             
>>   }
>>>> else if (storeAgent instanceof HttpSession) {
>>>> +           
>>    
>>>>      newValue =
>>>> ((HttpSession)storeAgent).getAttribute(newKey);
>>>> +             
>>   }
>>>> +             
>>   if
>>>> (newValue != null) {
>>>> +           
>>    
>>>>      break;
>>>> +             
>>   }
>>>> +            }
>>>> +            return
>>>> newValue;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class PropertyMap
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>>>> FlexibleStringExpander resourceExdr;
>>>> +        protected
>>>> 
>> FlexibleMapAccessor<ResourceBundleMapWrapper>
>>>> mapNameAcsr;
>>>> +        protected
>>>> FlexibleStringExpander globalExdr;
>>>> +
>>>> +        public
>> PropertyMap(ModelWidget
>>>> modelWidget, Element setElement) {
>>>> +            super
>>>> (modelWidget, setElement);
>>>> +           
>>>> this.resourceExdr =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
>>>> +           
>> this.mapNameAcsr
>>>> =
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("map-name"));
>>>> +           
>> this.globalExdr
>>>> =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            String
>> globalStr
>>>> = this.globalExdr.expandString(context);
>>>> +            //
>> default to
>>>> false
>>>> +            boolean
>> global =
>>>> "true".equals(globalStr);
>>>> +
>>>> +            Locale
>> locale =
>>>> (Locale) context.get("locale");
>>>> +            String
>> resource
>>>> = this.resourceExdr.expandString(context,
>> locale);
>>>> +
>>>> +           
>>>> ResourceBundleMapWrapper existingPropMap =
>>>> this.mapNameAcsr.get(context);
>>>> +            if
>>>> (existingPropMap == null) {
>>>> +           
>>    
>>>> this.mapNameAcsr.put(context,
>>>> UtilProperties.getResourceBundleMap(resource,
>> locale,
>>>> context));
>>>> +            } else
>> {
>>>> +           
>>    
>>>> try {
>>>> +           
>>    
>>>>     
>>>> 
>> existingPropMap.addBottomResourceBundle(resource);
>>>> +             
>>   }
>>>> catch (IllegalArgumentException e) {
>>>> +           
>>    
>>>>      // log the error, but
>> don't let it kill
>>>> everything just for a typo or bad char in an l10n
>> file
>>>> +           
>>    
>>>>      Debug.logError(e, "Error
>> adding resource
>>>> bundle [" + resource + "]: " + e.toString(),
>> module);
>>>> +             
>>   }
>>>> +            }
>>>> +
>>>> +            if
>> (global) {
>>>> +           
>>    
>>>> Map<String, Object> globalCtx =
>>>> 
>> UtilGenerics.checkMap(context.get("globalContext"));
>>>> +             
>>   if
>>>> (globalCtx != null) {
>>>> +           
>>    
>>>>      ResourceBundleMapWrapper
>> globalExistingPropMap
>>>> = this.mapNameAcsr.get(globalCtx);
>>>> +           
>>    
>>>>      if (globalExistingPropMap
>> == null) {
>>>> +           
>>    
>>>>      
>>    this.mapNameAcsr.put(globalCtx,
>>>> UtilProperties.getResourceBundleMap(resource,
>> locale,
>>>> context));
>>>> +           
>>    
>>>>      } else {
>>>> +           
>>    
>>>>          // is it the
>> same object? if not
>>>> add it in here too...
>>>> +           
>>    
>>>>          if
>> (existingPropMap !=
>>>> globalExistingPropMap) {
>>>> +           
>>    
>>>>          
>>    try {
>>>> +           
>>    
>>>>              
>>   
>>>> 
>> globalExistingPropMap.addBottomResourceBundle(resource);
>>>> +           
>>    
>>>>          
>>    } catch
>>>> (IllegalArgumentException e) {
>>>> +           
>>    
>>>>              
>>    //
>>>> log the error, but don't let it kill everything
>> just for a
>>>> typo or bad char in an l10n file
>>>> +           
>>    
>>>>              
>>   
>>>> Debug.logError(e, "Error adding resource bundle ["
>> +
>>>> resource + "]: " + e.toString(), module);
>>>> +           
>>    
>>>>          
>>    }
>>>> +           
>>    
>>>>          }
>>>> +           
>>    
>>>>      }
>>>> +             
>>   }
>>>> +            }
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class PropertyToField
>> extends
>>>> ModelWidgetAction {
>>>> +
>>>> +        protected
>>>> FlexibleStringExpander resourceExdr;
>>>> +        protected
>>>> FlexibleStringExpander propertyExdr;
>>>> +        protected
>>>> FlexibleMapAccessor<Object> fieldAcsr;
>>>> +        protected
>>>> FlexibleStringExpander defaultExdr;
>>>> +        protected boolean
>> noLocale;
>>>> +        protected
>>>> FlexibleMapAccessor<List<? extends
>> Object>>
>>>> argListAcsr;
>>>> +        protected
>>>> FlexibleStringExpander globalExdr;
>>>> +
>>>> +        public
>>>> PropertyToField(ModelWidget modelWidget, Element
>> setElement)
>>>> {
>>>> +            super
>>>> (modelWidget, setElement);
>>>> +           
>>>> this.resourceExdr =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
>>>> +           
>>>> this.propertyExdr =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
>>>> +           
>> this.fieldAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
>>>> +           
>> this.defaultExdr
>>>> =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("default"));
>>>> +           
>> this.noLocale =
>>>> 
>> "true".equals(setElement.getAttribute("no-locale"));
>>>> +           
>> this.argListAcsr
>>>> =
>>>> 
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("arg-list-name"));
>>>> +           
>> this.globalExdr
>>>> =
>>>> 
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +           
>> //String
>>>> globalStr =
>> this.globalExdr.expandString(context);
>>>> +            //
>> default to
>>>> false
>>>> +           
>> //boolean global
>>>> = "true".equals(globalStr);
>>>> +
>>>> +            Locale
>> locale =
>>>> (Locale) context.get("locale");
>>>> +            String
>> resource
>>>> = this.resourceExdr.expandString(context,
>> locale);
>>>> +            String
>> property
>>>> = this.propertyExdr.expandString(context,
>> locale);
>>>> +
>>>> +            String
>> value =
>>>> null;
>>>> +            if
>> (noLocale) {
>>>> +           
>>    
>>>> value = UtilProperties.getPropertyValue(resource,
>>>> property);
>>>> +            } else
>> {
>>>> +           
>>    
>>>> value = UtilProperties.getMessage(resource,
>> property,
>>>> locale);
>>>> +            }
>>>> +            if
>>>> (UtilValidate.isEmpty(value)) {
>>>> +           
>>    
>>>> value = this.defaultExdr.expandString(context);
>>>> +            }
>>>> +
>>>> +            // note
>> that
>>>> expanding the value string here will handle
>> defaultValue and
>>>> the string from
>>>> +           
>> //  the
>>>> properties file; if we decide later that we don't
>> want the
>>>> string from the properties
>>>> +           
>> //  file to
>>>> be expanded we should just expand the defaultValue
>> at the
>>>> beginning of this method.
>>>> +            value
>> =
>>>> FlexibleStringExpander.expandString(value,
>> context);
>>>> +
>>>> +            if
>>>> (!argListAcsr.isEmpty()) {
>>>> +           
>>    
>>>> List<? extends Object> argList =
>>>> argListAcsr.get(context);
>>>> +             
>>   if
>>>> (UtilValidate.isNotEmpty(argList)) {
>>>> +           
>>    
>>>>      value =
>> MessageFormat.format(value,
>>>> argList.toArray());
>>>> +             
>>   }
>>>> +            }
>>>> +           
>>>> fieldAcsr.put(context, value);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class Script extends
>>>> ModelWidgetAction {
>>>> +        protected static
>> final
>>>> Object[] EMPTY_ARGS = {};
>>>> +        protected String
>> location;
>>>> +        protected String
>> method;
>>>> +
>>>> +        public
>> Script(ModelWidget
>>>> modelWidget, Element scriptElement) {
>>>> +            super
>>>> (modelWidget, scriptElement);
>>>> +            String
>>>> scriptLocation =
>> scriptElement.getAttribute("location");
>>>> +           
>> this.location =
>>>> WidgetWorker.getScriptLocation(scriptLocation);
>>>> +           
>> this.method =
>>>> WidgetWorker.getScriptMethodName(scriptLocation);
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context)
>> throws
>>>> GeneralException {
>>>> +            if
>>>> (location.endsWith(".bsh")) {
>>>> +           
>>    
>>>> try {
>>>> +           
>>    
>>>>  
>>    BshUtil.runBshAtLocation(location,
>> context);
>>>> +             
>>   }
>>>> catch (GeneralException e) {
>>>> +           
>>    
>>>>      throw new
>> GeneralException("Error running BSH
>>>> script at location [" + location + "]", e);
>>>> +             
>>   }
>>>> +            } else
>> if
>>>> (location.endsWith(".groovy")) {
>>>> +           
>>    
>>>> try {
>>>> +           
>>    
>>>>      groovy.lang.Script script
>> =
>>>> 
>> InvokerHelper.createScript(GroovyUtil.getScriptClassFromLocation(location),
>>>> GroovyUtil.getBinding(context));
>>>> +           
>>    
>>>>      if
>> (UtilValidate.isEmpty(method)) {
>>>> +           
>>    
>>>>      
>>    script.run();
>>>> +           
>>    
>>>>      } else {
>>>> +           
>>    
>>>>      
>>    script.invokeMethod(method,
>>>> EMPTY_ARGS);
>>>> +           
>>    
>>>>      }
>>>> +             
>>   }
>>>> catch (GeneralException e) {
>>>> +           
>>    
>>>>      throw new
>> GeneralException("Error running
>>>> Groovy script at location [" + location + "]",
>> e);
>>>> +             
>>   }
>>>> +            } else
>> if
>>>> (location.endsWith(".xml")) {
>>>> +           
>>    
>>>> Map<String, Object> localContext =
>>>> FastMap.newInstance();
>>>> +           
>>    
>>>> localContext.putAll(context);
>>>> +           
>>    
>>>> DispatchContext ctx =
>>>> 
>> WidgetWorker.getDispatcher(context).getDispatchContext();
>>>> +           
>>    
>>>> MethodContext methodContext = new
>> MethodContext(ctx,
>>>> localContext, null);
>>>> +           
>>    
>>>> try {
>>>> +           
>>    
>>>>  
>>    SimpleMethod.runSimpleMethod(location,
>> method,
>>>> methodContext);
>>>> +           
>>    
>>>>  
>>    context.putAll(methodContext.getResults());
>>>> +             
>>   }
>>>> catch (MiniLangException e) {
>>>> +           
>>    
>>>>      throw new
>> GeneralException("Error running
>>>> simple method at location [" + location + "]",
>> e);
>>>> +             
>>   }
>>>> +            } else
>> {
>>>> +           
>>    
>>>> throw new GeneralException("For widget script
>> actions the
>>>> script type is not yet supported for location: ["
>> + location
>>>> + "]");
>>>> +            }
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class Service
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>>>> FlexibleStringExpander serviceNameExdr;
>>>> +        protected
>>>> FlexibleMapAccessor<Map<String,
>> Object>>
>>>> resultMapNameAcsr;
>>>> +        protected
>>>> FlexibleStringExpander autoFieldMapExdr;
>>>> +        protected
>>>> Map<FlexibleMapAccessor<Object>,
>> Object>
>>>> fieldMap;
>>>> +
>>>> +        public
>> Service(ModelWidget
>>>> modelWidget, Element serviceElement) {
>>>> +            super
>>>> (modelWidget, serviceElement);
>>>> +           
>>>> this.serviceNameExdr =
>>>> 
>> FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
>>>> +           
>>>> this.resultMapNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
>>>> +            if
>>>> (this.resultMapNameAcsr.isEmpty())
>> this.resultMapNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
>>>> +           
>>>> this.autoFieldMapExdr =
>>>> 
>> FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
>>>> +           
>> this.fieldMap =
>>>> EntityFinderUtil.makeFieldMap(serviceElement);
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            String
>>>> serviceNameExpanded =
>>>> this.serviceNameExdr.expandString(context);
>>>> +            if
>>>> (UtilValidate.isEmpty(serviceNameExpanded)) {
>>>> +           
>>    
>>>> throw new IllegalArgumentException("Service name
>> was empty,
>>>> expanded from: " +
>> this.serviceNameExdr.getOriginal());
>>>> +            }
>>>> +
>>>> +            String
>>>> autoFieldMapString =
>>>> this.autoFieldMapExdr.expandString(context);
>>>> +
>>>> +            try {
>>>> +           
>>    
>>>> Map<String, Object> serviceContext = null;
>>>> +             
>>   if
>>>> ("true".equals(autoFieldMapString)) {
>>>> +           
>>    
>>>>      DispatchContext dc =
>>>> 
>> WidgetWorker.getDispatcher(context).getDispatchContext();
>>>> +           
>>    
>>>>      // try a map called
>> "parameters", try it first
>>>> so values from here are overriden by values in the
>> main
>>>> context
>>>> +           
>>    
>>>>      Map<String, Object>
>> combinedMap =
>>>> FastMap.newInstance();
>>>> +           
>>    
>>>>      Map<String, Object>
>> parametersObj =
>>>> UtilGenerics.toMap(context.get("parameters"));
>>>> +           
>>    
>>>>      if (parametersObj != null)
>> {
>>>> +           
>>    
>>>>         
>>>> combinedMap.putAll(parametersObj);
>>>> +           
>>    
>>>>      }
>>>> +           
>>    
>>>>  
>>    combinedMap.putAll(context);
>>>> +           
>>    
>>>>      serviceContext =
>>>> dc.makeValidContext(serviceNameExpanded,
>>>> ModelService.IN_PARAM, combinedMap);
>>>> +             
>>   }
>>>> else if
>> (UtilValidate.isNotEmpty(autoFieldMapString)
>>>> && !"false".equals(autoFieldMapString)) {
>>>> +           
>>    
>>>>  
>>    FlexibleMapAccessor<Object> fieldFma
>> =
>>>> 
>> FlexibleMapAccessor.getInstance(autoFieldMapString);
>>>> +           
>>    
>>>>      Map<String, Object>
>> autoFieldMap =
>>>> UtilGenerics.toMap(fieldFma.get(context));
>>>> +           
>>    
>>>>      if (autoFieldMap != null)
>> {
>>>> +           
>>    
>>>>      
>>    serviceContext =
>>>> 
>> WidgetWorker.getDispatcher(context).getDispatchContext().makeValidContext(serviceNameExpanded,
>>>> ModelService.IN_PARAM, autoFieldMap);
>>>> +           
>>    
>>>>      }
>>>> +             
>>   }
>>>> +             
>>   if
>>>> (serviceContext == null) {
>>>> +           
>>    
>>>>      serviceContext =
>> FastMap.newInstance();
>>>> +             
>>   }
>>>> +
>>>> +             
>>   if
>>>> (this.fieldMap != null) {
>>>> +           
>>    
>>>>     
>>>> 
>> EntityFinderUtil.expandFieldMapToContext(this.fieldMap,
>>>> context, serviceContext);
>>>> +             
>>   }
>>>> +
>>>> +           
>>    
>>>> Map<String, Object> result =
>>>> 
>> WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded,
>>>> serviceContext);
>>>> +
>>>> +             
>>   if
>>>> (!this.resultMapNameAcsr.isEmpty()) {
>>>> +           
>>    
>>>>  
>>    this.resultMapNameAcsr.put(context,
>> result);
>>>> +           
>>    
>>>>      String queryString =
>>>> (String)result.get("queryString");
>>>> +           
>>    
>>>>      context.put("queryString",
>> queryString);
>>>> +           
>>    
>>>>  
>>    context.put("queryStringMap",
>>>> result.get("queryStringMap"));
>>>> +           
>>    
>>>>      if
>> (UtilValidate.isNotEmpty(queryString)) {
>>>> +           
>>    
>>>>          try {
>>>> +           
>>    
>>>>          
>>    String
>>>> queryStringEncoded =
>> queryString.replaceAll("&",
>>>> "%26");
>>>> +           
>>    
>>>>             
>>>> context.put("queryStringEncoded",
>> queryStringEncoded);
>>>> +           
>>    
>>>>          } catch
>> (PatternSyntaxException
>>>> e) {
>>>> +
>>>> +           
>>    
>>>>          }
>>>> +           
>>    
>>>>      }
>>>> +             
>>   }
>>>> else {
>>>> +           
>>    
>>>>      context.putAll(result);
>>>> +             
>>   }
>>>> +            }
>> catch
>>>> (GenericServiceException e) {
>>>> +           
>>    
>>>> String errMsg = "Error calling service with name "
>> +
>>>> serviceNameExpanded + ": " + e.toString();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public
>> FlexibleStringExpander
>>>> getServiceNameExdr() {
>>>> +            return
>>>> this.serviceNameExdr;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class EntityOne
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>> PrimaryKeyFinder
>>>> finder;
>>>> +
>>>> +        public
>> EntityOne(ModelWidget
>>>> modelWidget, Element entityOneElement) {
>>>> +            super
>>>> (modelWidget, entityOneElement);
>>>> +            finder
>> = new
>>>> PrimaryKeyFinder(entityOneElement);
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            try {
>>>> +           
>>    
>>>> finder.runFind(context,
>>>> WidgetWorker.getDelegator(context));
>>>> +            }
>> catch
>>>> (GeneralException e) {
>>>> +           
>>    
>>>> String errMsg = "Error doing entity query by
>> condition: " +
>>>> e.toString();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public
>> PrimaryKeyFinder
>>>> getFinder() {
>>>> +            return
>>>> this.finder;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class EntityAnd
>> extends
>>>> ModelWidgetAction {
>>>> +        protected ByAndFinder
>> finder;
>>>> +
>>>> +        public
>> EntityAnd(ModelWidget
>>>> modelWidget, Element entityAndElement) {
>>>> +            super
>>>> (modelWidget, entityAndElement);
>>>> +            finder
>> = new
>>>> ByAndFinder(entityAndElement);
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            try {
>>>> +           
>>    
>>>> finder.runFind(context,
>>>> WidgetWorker.getDelegator(context));
>>>> +            }
>> catch
>>>> (GeneralException e) {
>>>> +           
>>    
>>>> String errMsg = "Error doing entity query by
>> condition: " +
>>>> e.toString();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public ByAndFinder
>> getFinder()
>>>> {
>>>> +            return
>>>> this.finder;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class EntityCondition
>> extends
>>>> ModelWidgetAction {
>>>> +        ByConditionFinder
>> finder;
>>>> +
>>>> +        public
>>>> EntityCondition(ModelWidget modelWidget, Element
>>>> entityConditionElement) {
>>>> +            super
>>>> (modelWidget, entityConditionElement);
>>>> +            finder
>> = new
>>>> ByConditionFinder(entityConditionElement);
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            try {
>>>> +           
>>    
>>>> finder.runFind(context,
>>>> WidgetWorker.getDelegator(context));
>>>> +            }
>> catch
>>>> (GeneralException e) {
>>>> +           
>>    
>>>> String errMsg = "Error doing entity query by
>> condition: " +
>>>> e.toString();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public
>> ByConditionFinder
>>>> getFinder() {
>>>> +            return
>>>> this.finder;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class GetRelatedOne
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>>>> FlexibleMapAccessor<Object> valueNameAcsr;
>>>> +        protected
>>>> FlexibleMapAccessor<Object>
>> toValueNameAcsr;
>>>> +        protected String
>>>> relationName;
>>>> +        protected boolean
>> useCache;
>>>> +
>>>> +        public
>>>> GetRelatedOne(ModelWidget modelWidget, Element
>>>> getRelatedOneElement) {
>>>> +            super
>>>> (modelWidget, getRelatedOneElement);
>>>> +           
>>>> this.valueNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
>>>> +            if
>>>> (this.valueNameAcsr.isEmpty()) this.valueNameAcsr
>> =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-name"));
>>>> +           
>>>> this.toValueNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
>>>> +            if
>>>> (this.toValueNameAcsr.isEmpty())
>> this.toValueNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-name"));
>>>> +           
>>>> this.relationName =
>>>> 
>> getRelatedOneElement.getAttribute("relation-name");
>>>> +           
>> this.useCache =
>>>> 
>> "true".equals(getRelatedOneElement.getAttribute("use-cache"));
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            Object
>>>> valueObject = valueNameAcsr.get(context);
>>>> +            if
>> (valueObject
>>>> == null) {
>>>> +           
>>    
>>>> Debug.logVerbose("Value not found with name: " +
>>>> valueNameAcsr + ", not getting related...",
>> module);
>>>> +           
>>    
>>>> return;
>>>> +            }
>>>> +            if
>>>> (!(valueObject instanceof GenericValue)) {
>>>> +           
>>    
>>>> String errMsg = "Env variable for value-name " +
>>>> valueNameAcsr.toString() + " is not a GenericValue
>> object;
>>>> for the relation-name: " + relationName + "]";
>>>> +           
>>    
>>>> Debug.logError(errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +           
>> GenericValue
>>>> value = (GenericValue) valueObject;
>>>> +            try {
>>>> +             
>>   if
>>>> (useCache) {
>>>> +           
>>    
>>>>  
>>    toValueNameAcsr.put(context,
>>>> value.getRelatedOneCache(relationName));
>>>> +             
>>   }
>>>> else {
>>>> +           
>>    
>>>>  
>>    toValueNameAcsr.put(context,
>>>> value.getRelatedOne(relationName));
>>>> +             
>>   }
>>>> +            }
>> catch
>>>> (GenericEntityException e) {
>>>> +           
>>    
>>>> String errMsg = "Problem getting related one from
>> entity
>>>> with name " + value.getEntityName() + " for the
>>>> relation-name: " + relationName + ": " +
>> e.getMessage();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public String
>>>> getRelationName() {
>>>> +            return
>>>> this.relationName;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static class GetRelated
>> extends
>>>> ModelWidgetAction {
>>>> +        protected
>>>> FlexibleMapAccessor<Object> valueNameAcsr;
>>>> +        protected
>>>> 
>> FlexibleMapAccessor<List<GenericValue>>
>>>> listNameAcsr;
>>>> +        protected
>>>> FlexibleMapAccessor<Map<String,
>> Object>>
>>>> mapAcsr;
>>>> +        protected
>>>> FlexibleMapAccessor<List<String>>
>>>> orderByListAcsr;
>>>> +        protected String
>>>> relationName;
>>>> +        protected boolean
>> useCache;
>>>> +
>>>> +        public
>> GetRelated(ModelWidget
>>>> modelWidget, Element getRelatedElement) {
>>>> +            super
>>>> (modelWidget, getRelatedElement);
>>>> +           
>>>> this.valueNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
>>>> +            if
>>>> (this.valueNameAcsr.isEmpty()) this.valueNameAcsr
>> =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-name"));
>>>> +           
>>>> this.listNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
>>>> +            if
>>>> (this.listNameAcsr.isEmpty()) this.listNameAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list-name"));
>>>> +           
>>>> this.relationName =
>>>> getRelatedElement.getAttribute("relation-name");
>>>> +           
>> this.mapAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
>>>> +            if
>>>> (this.mapAcsr.isEmpty()) this.mapAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map-name"));
>>>> +           
>>>> this.orderByListAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
>>>> +            if
>>>> (this.orderByListAcsr.isEmpty())
>> this.orderByListAcsr =
>>>> 
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list-name"));
>>>> +           
>> this.useCache =
>>>> 
>> "true".equals(getRelatedElement.getAttribute("use-cache"));
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public void
>>>> runAction(Map<String, Object> context) {
>>>> +            Object
>>>> valueObject = valueNameAcsr.get(context);
>>>> +            if
>> (valueObject
>>>> == null) {
>>>> +           
>>    
>>>> Debug.logVerbose("Value not found with name: " +
>>>> valueNameAcsr + ", not getting related...",
>> module);
>>>> +           
>>    
>>>> return;
>>>> +            }
>>>> +            if
>>>> (!(valueObject instanceof GenericValue)) {
>>>> +           
>>    
>>>> String errMsg = "Env variable for value-name " +
>>>> valueNameAcsr.toString() + " is not a GenericValue
>> object;
>>>> for the relation-name: " + relationName + "]";
>>>> +           
>>    
>>>> Debug.logError(errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +           
>> GenericValue
>>>> value = (GenericValue) valueObject;
>>>> +           
>>>> List<String> orderByNames = null;
>>>> +            if
>>>> (!orderByListAcsr.isEmpty()) {
>>>> +           
>>    
>>>> orderByNames = orderByListAcsr.get(context);
>>>> +            }
>>>> +           
>> Map<String,
>>>> Object> constraintMap = null;
>>>> +            if
>>>> (!mapAcsr.isEmpty()) {
>>>> +           
>>    
>>>> constraintMap = mapAcsr.get(context);
>>>> +            }
>>>> +            try {
>>>> +             
>>   if
>>>> (useCache) {
>>>> +           
>>    
>>>>      listNameAcsr.put(context,
>>>> value.getRelatedCache(relationName,
>> constraintMap,
>>>> orderByNames));
>>>> +             
>>   }
>>>> else {
>>>> +           
>>    
>>>>      listNameAcsr.put(context,
>>>> value.getRelated(relationName, constraintMap,
>>>> orderByNames));
>>>> +             
>>   }
>>>> +            }
>> catch
>>>> (GenericEntityException e) {
>>>> +           
>>    
>>>> String errMsg = "Problem getting related from
>> entity with
>>>> name " + value.getEntityName() + " for the
>> relation-name: "
>>>> + relationName + ": " + e.getMessage();
>>>> +           
>>    
>>>> Debug.logError(e, errMsg, module);
>>>> +           
>>    
>>>> throw new IllegalArgumentException(errMsg);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        public String
>>>> getRelationName() {
>>>> +            return
>>>> this.relationName;
>>>> +        }
>>>> +    }
>>>> +}
>>>> 
>>>> Propchange:
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> 
>> ------------------------------------------------------------------------------
>>>>      svn:eol-style = native
>>>> 
>>>> Propchange:
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> 
>> ------------------------------------------------------------------------------
>>>>      svn:keywords = "Date Rev
>> Author URL Id"
>>>> 
>>>> Propchange:
>>>> 
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>>>> 
>> ------------------------------------------------------------------------------
>>>>      svn:mime-type =
>> text/plain
>>>> 
>>>> 
>>>> 
>>> 
>>> 
>>> 
>> 
>> 
> 
> 
> 


Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Erwan de FERRIERES <er...@nereide.fr>.
Le 02/07/2010 09:18, Adrian Crum a écrit :
> My new mantra: Just say no to copy and paste.
>
> I'm questioning nearly all of the code I come across.
>
> -Adrian
>
>
just run a sonar analysis of the project, there is a copy and paste 
detector !!

Cheers,

-- 
Erwan de FERRIERES
www.nereide.biz

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Adrian Crum <ad...@yahoo.com>.
My new mantra: Just say no to copy and paste.

I'm questioning nearly all of the code I come across.

-Adrian


--- On Thu, 7/1/10, Scott Gray <sc...@hotwaxmedia.com> wrote:

> From: Scott Gray <sc...@hotwaxmedia.com>
> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> To: dev@ofbiz.apache.org
> Date: Thursday, July 1, 2010, 11:58 PM
> Yeah no worries.  I'd never
> really thought about it before until yesterday when I came
> across a problem in the ModelMenuAction.PropertyMap action,
> it replaces the existing uiLabelMap instead of adding to it
> like the ModelScreenAction version does.  Option was to
> either just copy and paste the screen version or take the
> plunge and sort it all out.
> 
> Regards
> Scott
> 
> On 2/07/2010, at 6:45 PM, Adrian Crum wrote:
> 
> > Thanks! That duplication always bothered me.
> > 
> > -Adrian
> > 
> > --- On Thu, 7/1/10, lektran@apache.org
> <le...@apache.org>
> wrote:
> > 
> >> From: lektran@apache.org
> <le...@apache.org>
> >> Subject: svn commit: r959875 -
> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >> To: commits@ofbiz.apache.org
> >> Date: Thursday, July 1, 2010, 11:38 PM
> >> Author: lektran
> >> Date: Fri Jul  2 06:38:52 2010
> >> New Revision: 959875
> >> 
> >> URL: http://svn.apache.org/viewvc?rev=959875&view=rev
> >> Log:
> >> Added a new class ModelWidgetAction which will
> serve to
> >> replace the duplicate classes ModelScreenAction,
> >> ModelFormAction and ModelMenuAction.  This
> class is
> >> virtually a direct copy of ModelScreenAction and
> its
> >> subclasses.  I'll work over the weekend to
> switch the
> >> existing classes to extend from ModelWidgetAction,
> remove
> >> their methods and then deprecate the shells that
> are left
> >> behind.
> >> 
> >> Added:
> >>    
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java   (with
> >> props)
> >> 
> >> Added:
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java?rev=959875&view=auto
> >>
> ==============================================================================
> >> ---
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >> (added)
> >> +++
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >> Fri Jul  2 06:38:52 2010
> >> @@ -0,0 +1,700 @@
> >>
> +/*******************************************************************************
> >> + * 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;
> >> +
> >> +import java.io.Serializable;
> >> +import java.text.MessageFormat;
> >> +import java.util.ArrayList;
> >> +import java.util.List;
> >> +import java.util.Locale;
> >> +import java.util.Map;
> >> +import java.util.TimeZone;
> >> +import java.util.regex.PatternSyntaxException;
> >> +
> >> +import javax.servlet.ServletContext;
> >> +import javax.servlet.http.HttpSession;
> >> +
> >> +import javolution.util.FastList;
> >> +import javolution.util.FastMap;
> >> +
> >> +import org.w3c.dom.Element;
> >> +import
> org.codehaus.groovy.runtime.InvokerHelper;
> >> +import org.ofbiz.base.util.BshUtil;
> >> +import org.ofbiz.base.util.Debug;
> >> +import org.ofbiz.base.util.GeneralException;
> >> +import org.ofbiz.base.util.GroovyUtil;
> >> +import org.ofbiz.base.util.ObjectType;
> >> +import org.ofbiz.base.util.StringUtil;
> >> +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.collections.FlexibleMapAccessor;
> >> +import
> >>
> org.ofbiz.base.util.collections.ResourceBundleMapWrapper;
> >> +import
> org.ofbiz.base.util.string.FlexibleStringExpander;
> >> +import org.ofbiz.entity.GenericEntityException;
> >> +import org.ofbiz.entity.GenericValue;
> >> +import org.ofbiz.entity.finder.ByAndFinder;
> >> +import
> org.ofbiz.entity.finder.ByConditionFinder;
> >> +import org.ofbiz.entity.finder.EntityFinderUtil;
> >> +import org.ofbiz.entity.finder.PrimaryKeyFinder;
> >> +import org.ofbiz.minilang.MiniLangException;
> >> +import org.ofbiz.minilang.SimpleMethod;
> >> +import org.ofbiz.minilang.method.MethodContext;
> >> +import org.ofbiz.service.DispatchContext;
> >> +import
> org.ofbiz.service.GenericServiceException;
> >> +import org.ofbiz.service.ModelService;
> >> +
> >> +@SuppressWarnings("serial")
> >> +public abstract class ModelWidgetAction
> implements
> >> Serializable {
> >> +    public static final String module
> =
> >> ModelWidgetAction.class.getName();
> >> +
> >> +    protected ModelWidget modelWidget;
> >> +
> >> +    protected ModelWidgetAction() {}
> >> +
> >> +    public
> ModelWidgetAction(ModelWidget
> >> modelWidget, Element actionElement) {
> >> +        this.modelWidget =
> >> modelWidget;
> >> +        if
> (Debug.verboseOn())
> >> Debug.logVerbose("Reading widget action with name:
> " +
> >> actionElement.getNodeName(), module);
> >> +    }
> >> +
> >> +    public abstract void
> >> runAction(Map<String, Object> context)
> throws
> >> GeneralException;
> >> +
> >> +    public static
> List<ModelWidgetAction>
> >> readSubActions(ModelWidget modelWidget, Element
> >> parentElement) {
> >> +       
> List<ModelWidgetAction>
> >> actions = FastList.newInstance();
> >> +
> >> +        List<? extends
> Element>
> >> actionElementList =
> >> UtilXml.childElementList(parentElement);
> >> +        for (Element
> actionElement:
> >> actionElementList) {
> >> +            if
> >> ("set".equals(actionElement.getNodeName())) {
> >> +           
>    
> >> actions.add(new SetField(modelWidget,
> actionElement));
> >> +            } else
> if
> >>
> ("property-map".equals(actionElement.getNodeName())) {
> >> +           
>    
> >> actions.add(new PropertyMap(modelWidget,
> actionElement));
> >> +            } else
> if
> >>
> ("property-to-field".equals(actionElement.getNodeName())) {
> >> +           
>    
> >> actions.add(new PropertyToField(modelWidget,
> >> actionElement));
> >> +            } else
> if
> >> ("script".equals(actionElement.getNodeName())) {
> >> +           
>    
> >> actions.add(new Script(modelWidget,
> actionElement));
> >> +            } else
> if
> >> ("service".equals(actionElement.getNodeName())) {
> >> +           
>    
> >> actions.add(new Service(modelWidget,
> actionElement));
> >> +            } else
> if
> >> ("entity-one".equals(actionElement.getNodeName()))
> {
> >> +           
>    
> >> actions.add(new EntityOne(modelWidget,
> actionElement));
> >> +            } else
> if
> >> ("entity-and".equals(actionElement.getNodeName()))
> {
> >> +           
>    
> >> actions.add(new EntityAnd(modelWidget,
> actionElement));
> >> +            } else
> if
> >>
> ("entity-condition".equals(actionElement.getNodeName())) {
> >> +           
>    
> >> actions.add(new EntityCondition(modelWidget,
> >> actionElement));
> >> +            } else
> if
> >>
> ("get-related-one".equals(actionElement.getNodeName())) {
> >> +           
>    
> >> actions.add(new GetRelatedOne(modelWidget,
> actionElement));
> >> +            } else
> if
> >>
> ("get-related".equals(actionElement.getNodeName())) {
> >> +           
>    
> >> actions.add(new GetRelated(modelWidget,
> actionElement));
> >> +            } else
> {
> >> +           
>    
> >> throw new IllegalArgumentException("Action element
> not
> >> supported with name: " +
> actionElement.getNodeName());
> >> +            }
> >> +        }
> >> +
> >> +        return actions;
> >> +    }
> >> +
> >> +    public static void
> >> runSubActions(List<ModelWidgetAction>
> actions,
> >> Map<String, Object> context) throws
> GeneralException
> >> {
> >> +        if (actions == null)
> return;
> >> +
> >> +        for
> (ModelWidgetAction action:
> >> actions) {
> >> +            if
> >> (Debug.verboseOn()) Debug.logVerbose("Running
> widget action
> >> " + action.getClass().getName(), module);
> >> +           
> >> action.runAction(context);
> >> +        }
> >> +    }
> >> +
> >> +    public static class SetField
> extends
> >> ModelWidgetAction {
> >> +        protected
> >> FlexibleMapAccessor<Object> field;
> >> +        protected
> >> FlexibleMapAccessor<Object> fromField;
> >> +        protected
> >> FlexibleStringExpander valueExdr;
> >> +        protected
> >> FlexibleStringExpander defaultExdr;
> >> +        protected
> >> FlexibleStringExpander globalExdr;
> >> +        protected String
> type;
> >> +        protected String
> toScope;
> >> +        protected String
> fromScope;
> >> +
> >> +        public
> SetField(ModelWidget
> >> modelWidget, Element setElement) {
> >> +            super
> >> (modelWidget, setElement);
> >> +           
> this.field =
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
> >> +           
> this.fromField =
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("from-field"));
> >> +           
> this.valueExdr =
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("value"));
> >> +           
> this.defaultExdr
> >> =
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("default-value"));
> >> +           
> this.globalExdr
> >> =
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> >> +           
> this.type =
> >> setElement.getAttribute("type");
> >> +           
> this.toScope =
> >> setElement.getAttribute("to-scope");
> >> +           
> this.fromScope =
> >> setElement.getAttribute("from-scope");
> >> +            if
> >> (!this.fromField.isEmpty() &&
> >> !this.valueExdr.isEmpty()) {
> >> +           
>    
> >> throw new IllegalArgumentException("Cannot specify
> a
> >> from-field [" +
> setElement.getAttribute("from-field") + "]
> >> and a value [" + setElement.getAttribute("value")
> + "] on
> >> the set action in a widget");
> >> +            }
> >> +        }
> >> +
> >> +        @Override
> >> +        public void
> >> runAction(Map<String, Object> context) {
> >> +            String
> globalStr
> >> = this.globalExdr.expandString(context);
> >> +            //
> default to
> >> false
> >> +            boolean
> global =
> >> "true".equals(globalStr);
> >> +
> >> +            Object
> newValue
> >> = null;
> >> +            if
> >> (this.fromScope != null &&
> >> this.fromScope.equals("user")) {
> >> +             
>   if
> >> (!this.fromField.isEmpty()) {
> >> +           
>    
> >>     HttpSession session =
> (HttpSession)
> >> context.get("session");
> >> +           
>    
> >>     newValue =
> >> getInMemoryPersistedFromField(session, context);
> >> +           
>    
> >>     if (Debug.verboseOn())
> Debug.logVerbose("In
> >> user getting value for field from [" +
> >> this.fromField.getOriginalName() + "]: " +
> newValue,
> >> module);
> >> +             
>   }
> >> else if (!this.valueExdr.isEmpty()) {
> >> +           
>    
> >>     newValue =
> this.valueExdr.expand(context);
> >> +             
>   }
> >> +            } else
> if
> >> (this.fromScope != null &&
> >> this.fromScope.equals("application")) {
> >> +             
>   if
> >> (!this.fromField.isEmpty()) {
> >> +           
>    
> >>     ServletContext
> servletContext =
> >> (ServletContext) context.get("application");
> >> +           
>    
> >>     newValue =
> >> getInMemoryPersistedFromField(servletContext,
> context);
> >> +           
>    
> >>     if (Debug.verboseOn())
> Debug.logVerbose("In
> >> application getting value for field from [" +
> >> this.fromField.getOriginalName() + "]: " +
> newValue,
> >> module);
> >> +             
>   }
> >> else if (!this.valueExdr.isEmpty()) {
> >> +           
>    
> >>     newValue =
> >> this.valueExdr.expandString(context);
> >> +             
>   }
> >> +            } else
> {
> >> +             
>   if
> >> (!this.fromField.isEmpty()) {
> >> +           
>    
> >>     newValue =
> this.fromField.get(context);
> >> +           
>    
> >>     if (Debug.verboseOn())
> >> Debug.logVerbose("Getting value for field from ["
> +
> >> this.fromField.getOriginalName() + "]: " +
> newValue,
> >> module);
> >> +             
>   }
> >> else if (!this.valueExdr.isEmpty()) {
> >> +           
>    
> >>     newValue =
> this.valueExdr.expand(context);
> >> +             
>   }
> >> +            }
> >> +
> >> +            // If
> newValue
> >> is still empty, use the default value
> >> +            if
> >> (ObjectType.isEmpty(newValue) &&
> >> !this.defaultExdr.isEmpty()) {
> >> +           
>    
> >> newValue = this.defaultExdr.expand(context);
> >> +            }
> >> +
> >> +            if
> >> (UtilValidate.isNotEmpty(this.type)) {
> >> +             
>   if
> >> ("NewMap".equals(this.type)) {
> >> +           
>    
> >>     newValue =
> FastMap.newInstance();
> >> +             
>   }
> >> else if ("NewList".equals(this.type)) {
> >> +           
>    
> >>     newValue =
> FastList.newInstance();
> >> +             
>   }
> >> else {
> >> +           
>    
> >>     try {
> >> +           
>    
> >>         newValue =
> >> ObjectType.simpleTypeConvert(newValue, this.type,
> null,
> >> (TimeZone) context.get("timeZone"), (Locale)
> >> context.get("locale"), true);
> >> +           
>    
> >>     } catch (GeneralException
> e) {
> >> +           
>    
> >>         String
> errMsg = "Could not
> >> convert field value for the field: [" +
> >> this.field.getOriginalName() + "] to the [" +
> this.type + "]
> >> type for the value [" + newValue + "]: " +
> e.toString();
> >> +           
>    
> >>     
>    Debug.logError(e, errMsg,
> >> module);
> >> +           
>    
> >>         throw new
> >> IllegalArgumentException(errMsg);
> >> +           
>    
> >>     }
> >> +             
>   }
> >> +            }
> >> +
> >> +            if
> (this.toScope
> >> != null && this.toScope.equals("user")) {
> >> +           
>    
> >> String originalName =
> this.field.getOriginalName();
> >> +           
>    
> >> List<String> currentWidgetTrail =
> >>
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> >> +           
>    
> >> String newKey = "";
> >> +             
>   if
> >> (currentWidgetTrail != null) {
> >> +           
>    
> >>     newKey =
> StringUtil.join(currentWidgetTrail,
> >> "|");
> >> +             
>   }
> >> +             
>   if
> >> (UtilValidate.isNotEmpty(newKey)) {
> >> +           
>    
> >>     newKey += "|";
> >> +             
>   }
> >> +           
>    
> >> newKey += originalName;
> >> +           
>    
> >> HttpSession session =
> (HttpSession)context.get("session");
> >> +           
>    
> >> session.setAttribute(newKey, newValue);
> >> +             
>   if
> >> (Debug.verboseOn()) Debug.logVerbose("In user
> setting value
> >> for field from [" + this.field.getOriginalName() +
> "]: " +
> >> newValue, module);
> >> +            } else
> if
> >> (this.toScope != null &&
> >> this.toScope.equals("application")) {
> >> +           
>    
> >> String originalName =
> this.field.getOriginalName();
> >> +           
>    
> >> List<String> currentWidgetTrail =
> >>
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> >> +           
>    
> >> String newKey = "";
> >> +             
>   if
> >> (currentWidgetTrail != null) {
> >> +           
>    
> >>     newKey =
> StringUtil.join(currentWidgetTrail,
> >> "|");
> >> +             
>   }
> >> +             
>   if
> >> (UtilValidate.isNotEmpty(newKey)) {
> >> +           
>    
> >>     newKey += "|";
> >> +             
>   }
> >> +           
>    
> >> newKey += originalName;
> >> +           
>    
> >> ServletContext servletContext =
> >> (ServletContext)context.get("application");
> >> +           
>    
> >> servletContext.setAttribute(newKey, newValue);
> >> +             
>   if
> >> (Debug.verboseOn()) Debug.logVerbose("In
> application setting
> >> value for field from [" +
> this.field.getOriginalName() + "]:
> >> " + newValue, module);
> >> +            } else
> {
> >> +             
>   //
> >> only do this if it is not global, if global ONLY
> put it in
> >> the global context
> >> +             
>   if
> >> (!global) {
> >> +           
>    
> >>     if (Debug.verboseOn())
> >> Debug.logVerbose("Setting field [" +
> >> this.field.getOriginalName() + "] to value: " +
> newValue,
> >> module);
> >> +           
>    
> >>     this.field.put(context,
> newValue);
> >> +             
>   }
> >> +            }
> >> +
> >> +            if
> (global) {
> >> +           
>    
> >> Map<String, Object> globalCtx =
> >>
> UtilGenerics.checkMap(context.get("globalContext"));
> >> +             
>   if
> >> (globalCtx != null) {
> >> +           
>    
> >>     this.field.put(globalCtx,
> newValue);
> >> +             
>   }
> >> else {
> >> +           
>    
> >>     this.field.put(context,
> newValue);
> >> +             
>   }
> >> +            }
> >> +
> >> +            // this
> is a
> >> hack for backward compatibility with the JPublish
> page
> >> object
> >> +           
> Map<String,
> >> Object> page =
> >> UtilGenerics.checkMap(context.get("page"));
> >> +            if
> (page !=
> >> null) {
> >> +           
>    
> >> this.field.put(page, newValue);
> >> +            }
> >> +        }
> >> +
> >> +        public Object
> >> getInMemoryPersistedFromField(Object storeAgent,
> >> Map<String, Object> context) {
> >> +            Object
> newValue
> >> = null;
> >> +            String
> >> originalName = this.fromField.getOriginalName();
> >> +           
> >> List<String> currentWidgetTrail =
> >>
> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
> >> +           
> >> List<String> trailList = new
> >> ArrayList<String>();
> >> +            if
> >> (currentWidgetTrail != null) {
> >> +           
>    
> >> trailList.addAll(currentWidgetTrail);
> >> +            }
> >> +
> >> +            for
> (int
> >> i=trailList.size(); i >= 0; i--) {
> >> +           
>    
> >> List<String> subTrail =
> trailList.subList(0,i);
> >> +           
>    
> >> String newKey = null;
> >> +             
>   if
> >> (subTrail.size() > 0)
> >> +           
>    
> >>     newKey =
> StringUtil.join(subTrail, "|") + "|"
> >> + originalName;
> >> +           
>    
> >> else
> >> +           
>    
> >>     newKey = originalName;
> >> +
> >> +             
>   if
> >> (storeAgent instanceof ServletContext) {
> >> +           
>    
> >>     newValue =
> >>
> ((ServletContext)storeAgent).getAttribute(newKey);
> >> +             
>   }
> >> else if (storeAgent instanceof HttpSession) {
> >> +           
>    
> >>     newValue =
> >> ((HttpSession)storeAgent).getAttribute(newKey);
> >> +             
>   }
> >> +             
>   if
> >> (newValue != null) {
> >> +           
>    
> >>     break;
> >> +             
>   }
> >> +            }
> >> +            return
> >> newValue;
> >> +        }
> >> +    }
> >> +
> >> +    public static class PropertyMap
> extends
> >> ModelWidgetAction {
> >> +        protected
> >> FlexibleStringExpander resourceExdr;
> >> +        protected
> >>
> FlexibleMapAccessor<ResourceBundleMapWrapper>
> >> mapNameAcsr;
> >> +        protected
> >> FlexibleStringExpander globalExdr;
> >> +
> >> +        public
> PropertyMap(ModelWidget
> >> modelWidget, Element setElement) {
> >> +            super
> >> (modelWidget, setElement);
> >> +           
> >> this.resourceExdr =
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
> >> +           
> this.mapNameAcsr
> >> =
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("map-name"));
> >> +           
> this.globalExdr
> >> =
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> >> +        }
> >> +
> >> +        @Override
> >> +        public void
> >> runAction(Map<String, Object> context) {
> >> +            String
> globalStr
> >> = this.globalExdr.expandString(context);
> >> +            //
> default to
> >> false
> >> +            boolean
> global =
> >> "true".equals(globalStr);
> >> +
> >> +            Locale
> locale =
> >> (Locale) context.get("locale");
> >> +            String
> resource
> >> = this.resourceExdr.expandString(context,
> locale);
> >> +
> >> +           
> >> ResourceBundleMapWrapper existingPropMap =
> >> this.mapNameAcsr.get(context);
> >> +            if
> >> (existingPropMap == null) {
> >> +           
>    
> >> this.mapNameAcsr.put(context,
> >> UtilProperties.getResourceBundleMap(resource,
> locale,
> >> context));
> >> +            } else
> {
> >> +           
>    
> >> try {
> >> +           
>    
> >>    
> >>
> existingPropMap.addBottomResourceBundle(resource);
> >> +             
>   }
> >> catch (IllegalArgumentException e) {
> >> +           
>    
> >>     // log the error, but
> don't let it kill
> >> everything just for a typo or bad char in an l10n
> file
> >> +           
>    
> >>     Debug.logError(e, "Error
> adding resource
> >> bundle [" + resource + "]: " + e.toString(),
> module);
> >> +             
>   }
> >> +            }
> >> +
> >> +            if
> (global) {
> >> +           
>    
> >> Map<String, Object> globalCtx =
> >>
> UtilGenerics.checkMap(context.get("globalContext"));
> >> +             
>   if
> >> (globalCtx != null) {
> >> +           
>    
> >>     ResourceBundleMapWrapper
> globalExistingPropMap
> >> = this.mapNameAcsr.get(globalCtx);
> >> +           
>    
> >>     if (globalExistingPropMap
> == null) {
> >> +           
>    
> >>     
>    this.mapNameAcsr.put(globalCtx,
> >> UtilProperties.getResourceBundleMap(resource,
> locale,
> >> context));
> >> +           
>    
> >>     } else {
> >> +           
>    
> >>         // is it the
> same object? if not
> >> add it in here too...
> >> +           
>    
> >>         if
> (existingPropMap !=
> >> globalExistingPropMap) {
> >> +           
>    
> >>         
>    try {
> >> +           
>    
> >>             
>   
> >>
> globalExistingPropMap.addBottomResourceBundle(resource);
> >> +           
>    
> >>         
>    } catch
> >> (IllegalArgumentException e) {
> >> +           
>    
> >>             
>    //
> >> log the error, but don't let it kill everything
> just for a
> >> typo or bad char in an l10n file
> >> +           
>    
> >>             
>   
> >> Debug.logError(e, "Error adding resource bundle ["
> +
> >> resource + "]: " + e.toString(), module);
> >> +           
>    
> >>         
>    }
> >> +           
>    
> >>         }
> >> +           
>    
> >>     }
> >> +             
>   }
> >> +            }
> >> +        }
> >> +    }
> >> +
> >> +    public static class PropertyToField
> extends
> >> ModelWidgetAction {
> >> +
> >> +        protected
> >> FlexibleStringExpander resourceExdr;
> >> +        protected
> >> FlexibleStringExpander propertyExdr;
> >> +        protected
> >> FlexibleMapAccessor<Object> fieldAcsr;
> >> +        protected
> >> FlexibleStringExpander defaultExdr;
> >> +        protected boolean
> noLocale;
> >> +        protected
> >> FlexibleMapAccessor<List<? extends
> Object>>
> >> argListAcsr;
> >> +        protected
> >> FlexibleStringExpander globalExdr;
> >> +
> >> +        public
> >> PropertyToField(ModelWidget modelWidget, Element
> setElement)
> >> {
> >> +            super
> >> (modelWidget, setElement);
> >> +           
> >> this.resourceExdr =
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
> >> +           
> >> this.propertyExdr =
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
> >> +           
> this.fieldAcsr =
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
> >> +           
> this.defaultExdr
> >> =
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("default"));
> >> +           
> this.noLocale =
> >>
> "true".equals(setElement.getAttribute("no-locale"));
> >> +           
> this.argListAcsr
> >> =
> >>
> FlexibleMapAccessor.getInstance(setElement.getAttribute("arg-list-name"));
> >> +           
> this.globalExdr
> >> =
> >>
> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
> >> +        }
> >> +
> >> +        @Override
> >> +        public void
> >> runAction(Map<String, Object> context) {
> >> +           
> //String
> >> globalStr =
> this.globalExdr.expandString(context);
> >> +            //
> default to
> >> false
> >> +           
> //boolean global
> >> = "true".equals(globalStr);
> >> +
> >> +            Locale
> locale =
> >> (Locale) context.get("locale");
> >> +            String
> resource
> >> = this.resourceExdr.expandString(context,
> locale);
> >> +            String
> property
> >> = this.propertyExdr.expandString(context,
> locale);
> >> +
> >> +            String
> value =
> >> null;
> >> +            if
> (noLocale) {
> >> +           
>    
> >> value = UtilProperties.getPropertyValue(resource,
> >> property);
> >> +            } else
> {
> >> +           
>    
> >> value = UtilProperties.getMessage(resource,
> property,
> >> locale);
> >> +            }
> >> +            if
> >> (UtilValidate.isEmpty(value)) {
> >> +           
>    
> >> value = this.defaultExdr.expandString(context);
> >> +            }
> >> +
> >> +            // note
> that
> >> expanding the value string here will handle
> defaultValue and
> >> the string from
> >> +           
> //  the
> >> properties file; if we decide later that we don't
> want the
> >> string from the properties
> >> +           
> //  file to
> >> be expanded we should just expand the defaultValue
> at the
> >> beginning of this method.
> >> +            value
> =
> >> FlexibleStringExpander.expandString(value,
> context);
> >> +
> >> +            if
> >> (!argListAcsr.isEmpty()) {
> >> +           
>    
> >> List<? extends Object> argList =
> >> argListAcsr.get(context);
> >> +             
>   if
> >> (UtilValidate.isNotEmpty(argList)) {
> >> +           
>    
> >>     value =
> MessageFormat.format(value,
> >> argList.toArray());
> >> +             
>   }
> >> +            }
> >> +           
> >> fieldAcsr.put(context, value);
> >> +        }
> >> +    }
> >> +
> >> +    public static class Script extends
> >> ModelWidgetAction {
> >> +        protected static
> final
> >> Object[] EMPTY_ARGS = {};
> >> +        protected String
> location;
> >> +        protected String
> method;
> >> +
> >> +        public
> Script(ModelWidget
> >> modelWidget, Element scriptElement) {
> >> +            super
> >> (modelWidget, scriptElement);
> >> +            String
> >> scriptLocation =
> scriptElement.getAttribute("location");
> >> +           
> this.location =
> >> WidgetWorker.getScriptLocation(scriptLocation);
> >> +           
> this.method =
> >> WidgetWorker.getScriptMethodName(scriptLocation);
> >> +        }
> >> +
> >> +        @Override
> >> +        public void
> >> runAction(Map<String, Object> context)
> throws
> >> GeneralException {
> >> +            if
> >> (location.endsWith(".bsh")) {
> >> +           
>    
> >> try {
> >> +           
>    
> >> 
>    BshUtil.runBshAtLocation(location,
> context);
> >> +             
>   }
> >> catch (GeneralException e) {
> >> +           
>    
> >>     throw new
> GeneralException("Error running BSH
> >> script at location [" + location + "]", e);
> >> +             
>   }
> >> +            } else
> if
> >> (location.endsWith(".groovy")) {
> >> +           
>    
> >> try {
> >> +           
>    
> >>     groovy.lang.Script script
> =
> >>
> InvokerHelper.createScript(GroovyUtil.getScriptClassFromLocation(location),
> >> GroovyUtil.getBinding(context));
> >> +           
>    
> >>     if
> (UtilValidate.isEmpty(method)) {
> >> +           
>    
> >>     
>    script.run();
> >> +           
>    
> >>     } else {
> >> +           
>    
> >>     
>    script.invokeMethod(method,
> >> EMPTY_ARGS);
> >> +           
>    
> >>     }
> >> +             
>   }
> >> catch (GeneralException e) {
> >> +           
>    
> >>     throw new
> GeneralException("Error running
> >> Groovy script at location [" + location + "]",
> e);
> >> +             
>   }
> >> +            } else
> if
> >> (location.endsWith(".xml")) {
> >> +           
>    
> >> Map<String, Object> localContext =
> >> FastMap.newInstance();
> >> +           
>    
> >> localContext.putAll(context);
> >> +           
>    
> >> DispatchContext ctx =
> >>
> WidgetWorker.getDispatcher(context).getDispatchContext();
> >> +           
>    
> >> MethodContext methodContext = new
> MethodContext(ctx,
> >> localContext, null);
> >> +           
>    
> >> try {
> >> +           
>    
> >> 
>    SimpleMethod.runSimpleMethod(location,
> method,
> >> methodContext);
> >> +           
>    
> >> 
>    context.putAll(methodContext.getResults());
> >> +             
>   }
> >> catch (MiniLangException e) {
> >> +           
>    
> >>     throw new
> GeneralException("Error running
> >> simple method at location [" + location + "]",
> e);
> >> +             
>   }
> >> +            } else
> {
> >> +           
>    
> >> throw new GeneralException("For widget script
> actions the
> >> script type is not yet supported for location: ["
> + location
> >> + "]");
> >> +            }
> >> +        }
> >> +    }
> >> +
> >> +    public static class Service
> extends
> >> ModelWidgetAction {
> >> +        protected
> >> FlexibleStringExpander serviceNameExdr;
> >> +        protected
> >> FlexibleMapAccessor<Map<String,
> Object>>
> >> resultMapNameAcsr;
> >> +        protected
> >> FlexibleStringExpander autoFieldMapExdr;
> >> +        protected
> >> Map<FlexibleMapAccessor<Object>,
> Object>
> >> fieldMap;
> >> +
> >> +        public
> Service(ModelWidget
> >> modelWidget, Element serviceElement) {
> >> +            super
> >> (modelWidget, serviceElement);
> >> +           
> >> this.serviceNameExdr =
> >>
> FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
> >> +           
> >> this.resultMapNameAcsr =
> >>
> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
> >> +            if
> >> (this.resultMapNameAcsr.isEmpty())
> this.resultMapNameAcsr =
> >>
> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
> >> +           
> >> this.autoFieldMapExdr =
> >>
> FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
> >> +           
> this.fieldMap =
> >> EntityFinderUtil.makeFieldMap(serviceElement);
> >> +        }
> >> +
> >> +        @Override
> >> +        public void
> >> runAction(Map<String, Object> context) {
> >> +            String
> >> serviceNameExpanded =
> >> this.serviceNameExdr.expandString(context);
> >> +            if
> >> (UtilValidate.isEmpty(serviceNameExpanded)) {
> >> +           
>    
> >> throw new IllegalArgumentException("Service name
> was empty,
> >> expanded from: " +
> this.serviceNameExdr.getOriginal());
> >> +            }
> >> +
> >> +            String
> >> autoFieldMapString =
> >> this.autoFieldMapExdr.expandString(context);
> >> +
> >> +            try {
> >> +           
>    
> >> Map<String, Object> serviceContext = null;
> >> +             
>   if
> >> ("true".equals(autoFieldMapString)) {
> >> +           
>    
> >>     DispatchContext dc =
> >>
> WidgetWorker.getDispatcher(context).getDispatchContext();
> >> +           
>    
> >>     // try a map called
> "parameters", try it first
> >> so values from here are overriden by values in the
> main
> >> context
> >> +           
>    
> >>     Map<String, Object>
> combinedMap =
> >> FastMap.newInstance();
> >> +           
>    
> >>     Map<String, Object>
> parametersObj =
> >> UtilGenerics.toMap(context.get("parameters"));
> >> +           
>    
> >>     if (parametersObj != null)
> {
> >> +           
>    
> >>        
> >> combinedMap.putAll(parametersObj);
> >> +           
>    
> >>     }
> >> +           
>    
> >> 
>    combinedMap.putAll(context);
> >> +           
>    
> >>     serviceContext =
> >> dc.makeValidContext(serviceNameExpanded,
> >> ModelService.IN_PARAM, combinedMap);
> >> +             
>   }
> >> else if
> (UtilValidate.isNotEmpty(autoFieldMapString)
> >> && !"false".equals(autoFieldMapString)) {
> >> +           
>    
> >> 
>    FlexibleMapAccessor<Object> fieldFma
> =
> >>
> FlexibleMapAccessor.getInstance(autoFieldMapString);
> >> +           
>    
> >>     Map<String, Object>
> autoFieldMap =
> >> UtilGenerics.toMap(fieldFma.get(context));
> >> +           
>    
> >>     if (autoFieldMap != null)
> {
> >> +           
>    
> >>     
>    serviceContext =
> >>
> WidgetWorker.getDispatcher(context).getDispatchContext().makeValidContext(serviceNameExpanded,
> >> ModelService.IN_PARAM, autoFieldMap);
> >> +           
>    
> >>     }
> >> +             
>   }
> >> +             
>   if
> >> (serviceContext == null) {
> >> +           
>    
> >>     serviceContext =
> FastMap.newInstance();
> >> +             
>   }
> >> +
> >> +             
>   if
> >> (this.fieldMap != null) {
> >> +           
>    
> >>    
> >>
> EntityFinderUtil.expandFieldMapToContext(this.fieldMap,
> >> context, serviceContext);
> >> +             
>   }
> >> +
> >> +           
>    
> >> Map<String, Object> result =
> >>
> WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded,
> >> serviceContext);
> >> +
> >> +             
>   if
> >> (!this.resultMapNameAcsr.isEmpty()) {
> >> +           
>    
> >> 
>    this.resultMapNameAcsr.put(context,
> result);
> >> +           
>    
> >>     String queryString =
> >> (String)result.get("queryString");
> >> +           
>    
> >>     context.put("queryString",
> queryString);
> >> +           
>    
> >> 
>    context.put("queryStringMap",
> >> result.get("queryStringMap"));
> >> +           
>    
> >>     if
> (UtilValidate.isNotEmpty(queryString)) {
> >> +           
>    
> >>         try {
> >> +           
>    
> >>         
>    String
> >> queryStringEncoded =
> queryString.replaceAll("&",
> >> "%26");
> >> +           
>    
> >>            
> >> context.put("queryStringEncoded",
> queryStringEncoded);
> >> +           
>    
> >>         } catch
> (PatternSyntaxException
> >> e) {
> >> +
> >> +           
>    
> >>         }
> >> +           
>    
> >>     }
> >> +             
>   }
> >> else {
> >> +           
>    
> >>     context.putAll(result);
> >> +             
>   }
> >> +            }
> catch
> >> (GenericServiceException e) {
> >> +           
>    
> >> String errMsg = "Error calling service with name "
> +
> >> serviceNameExpanded + ": " + e.toString();
> >> +           
>    
> >> Debug.logError(e, errMsg, module);
> >> +           
>    
> >> throw new IllegalArgumentException(errMsg);
> >> +            }
> >> +        }
> >> +
> >> +        public
> FlexibleStringExpander
> >> getServiceNameExdr() {
> >> +            return
> >> this.serviceNameExdr;
> >> +        }
> >> +    }
> >> +
> >> +    public static class EntityOne
> extends
> >> ModelWidgetAction {
> >> +        protected
> PrimaryKeyFinder
> >> finder;
> >> +
> >> +        public
> EntityOne(ModelWidget
> >> modelWidget, Element entityOneElement) {
> >> +            super
> >> (modelWidget, entityOneElement);
> >> +            finder
> = new
> >> PrimaryKeyFinder(entityOneElement);
> >> +        }
> >> +
> >> +        @Override
> >> +        public void
> >> runAction(Map<String, Object> context) {
> >> +            try {
> >> +           
>    
> >> finder.runFind(context,
> >> WidgetWorker.getDelegator(context));
> >> +            }
> catch
> >> (GeneralException e) {
> >> +           
>    
> >> String errMsg = "Error doing entity query by
> condition: " +
> >> e.toString();
> >> +           
>    
> >> Debug.logError(e, errMsg, module);
> >> +           
>    
> >> throw new IllegalArgumentException(errMsg);
> >> +            }
> >> +        }
> >> +
> >> +        public
> PrimaryKeyFinder
> >> getFinder() {
> >> +            return
> >> this.finder;
> >> +        }
> >> +    }
> >> +
> >> +    public static class EntityAnd
> extends
> >> ModelWidgetAction {
> >> +        protected ByAndFinder
> finder;
> >> +
> >> +        public
> EntityAnd(ModelWidget
> >> modelWidget, Element entityAndElement) {
> >> +            super
> >> (modelWidget, entityAndElement);
> >> +            finder
> = new
> >> ByAndFinder(entityAndElement);
> >> +        }
> >> +
> >> +        @Override
> >> +        public void
> >> runAction(Map<String, Object> context) {
> >> +            try {
> >> +           
>    
> >> finder.runFind(context,
> >> WidgetWorker.getDelegator(context));
> >> +            }
> catch
> >> (GeneralException e) {
> >> +           
>    
> >> String errMsg = "Error doing entity query by
> condition: " +
> >> e.toString();
> >> +           
>    
> >> Debug.logError(e, errMsg, module);
> >> +           
>    
> >> throw new IllegalArgumentException(errMsg);
> >> +            }
> >> +        }
> >> +
> >> +        public ByAndFinder
> getFinder()
> >> {
> >> +            return
> >> this.finder;
> >> +        }
> >> +    }
> >> +
> >> +    public static class EntityCondition
> extends
> >> ModelWidgetAction {
> >> +        ByConditionFinder
> finder;
> >> +
> >> +        public
> >> EntityCondition(ModelWidget modelWidget, Element
> >> entityConditionElement) {
> >> +            super
> >> (modelWidget, entityConditionElement);
> >> +            finder
> = new
> >> ByConditionFinder(entityConditionElement);
> >> +        }
> >> +
> >> +        @Override
> >> +        public void
> >> runAction(Map<String, Object> context) {
> >> +            try {
> >> +           
>    
> >> finder.runFind(context,
> >> WidgetWorker.getDelegator(context));
> >> +            }
> catch
> >> (GeneralException e) {
> >> +           
>    
> >> String errMsg = "Error doing entity query by
> condition: " +
> >> e.toString();
> >> +           
>    
> >> Debug.logError(e, errMsg, module);
> >> +           
>    
> >> throw new IllegalArgumentException(errMsg);
> >> +            }
> >> +        }
> >> +
> >> +        public
> ByConditionFinder
> >> getFinder() {
> >> +            return
> >> this.finder;
> >> +        }
> >> +    }
> >> +
> >> +    public static class GetRelatedOne
> extends
> >> ModelWidgetAction {
> >> +        protected
> >> FlexibleMapAccessor<Object> valueNameAcsr;
> >> +        protected
> >> FlexibleMapAccessor<Object>
> toValueNameAcsr;
> >> +        protected String
> >> relationName;
> >> +        protected boolean
> useCache;
> >> +
> >> +        public
> >> GetRelatedOne(ModelWidget modelWidget, Element
> >> getRelatedOneElement) {
> >> +            super
> >> (modelWidget, getRelatedOneElement);
> >> +           
> >> this.valueNameAcsr =
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
> >> +            if
> >> (this.valueNameAcsr.isEmpty()) this.valueNameAcsr
> =
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-name"));
> >> +           
> >> this.toValueNameAcsr =
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
> >> +            if
> >> (this.toValueNameAcsr.isEmpty())
> this.toValueNameAcsr =
> >>
> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-name"));
> >> +           
> >> this.relationName =
> >>
> getRelatedOneElement.getAttribute("relation-name");
> >> +           
> this.useCache =
> >>
> "true".equals(getRelatedOneElement.getAttribute("use-cache"));
> >> +        }
> >> +
> >> +        @Override
> >> +        public void
> >> runAction(Map<String, Object> context) {
> >> +            Object
> >> valueObject = valueNameAcsr.get(context);
> >> +            if
> (valueObject
> >> == null) {
> >> +           
>    
> >> Debug.logVerbose("Value not found with name: " +
> >> valueNameAcsr + ", not getting related...",
> module);
> >> +           
>    
> >> return;
> >> +            }
> >> +            if
> >> (!(valueObject instanceof GenericValue)) {
> >> +           
>    
> >> String errMsg = "Env variable for value-name " +
> >> valueNameAcsr.toString() + " is not a GenericValue
> object;
> >> for the relation-name: " + relationName + "]";
> >> +           
>    
> >> Debug.logError(errMsg, module);
> >> +           
>    
> >> throw new IllegalArgumentException(errMsg);
> >> +            }
> >> +           
> GenericValue
> >> value = (GenericValue) valueObject;
> >> +            try {
> >> +             
>   if
> >> (useCache) {
> >> +           
>    
> >> 
>    toValueNameAcsr.put(context,
> >> value.getRelatedOneCache(relationName));
> >> +             
>   }
> >> else {
> >> +           
>    
> >> 
>    toValueNameAcsr.put(context,
> >> value.getRelatedOne(relationName));
> >> +             
>   }
> >> +            }
> catch
> >> (GenericEntityException e) {
> >> +           
>    
> >> String errMsg = "Problem getting related one from
> entity
> >> with name " + value.getEntityName() + " for the
> >> relation-name: " + relationName + ": " +
> e.getMessage();
> >> +           
>    
> >> Debug.logError(e, errMsg, module);
> >> +           
>    
> >> throw new IllegalArgumentException(errMsg);
> >> +            }
> >> +        }
> >> +
> >> +        public String
> >> getRelationName() {
> >> +            return
> >> this.relationName;
> >> +        }
> >> +    }
> >> +
> >> +    public static class GetRelated
> extends
> >> ModelWidgetAction {
> >> +        protected
> >> FlexibleMapAccessor<Object> valueNameAcsr;
> >> +        protected
> >>
> FlexibleMapAccessor<List<GenericValue>>
> >> listNameAcsr;
> >> +        protected
> >> FlexibleMapAccessor<Map<String,
> Object>>
> >> mapAcsr;
> >> +        protected
> >> FlexibleMapAccessor<List<String>>
> >> orderByListAcsr;
> >> +        protected String
> >> relationName;
> >> +        protected boolean
> useCache;
> >> +
> >> +        public
> GetRelated(ModelWidget
> >> modelWidget, Element getRelatedElement) {
> >> +            super
> >> (modelWidget, getRelatedElement);
> >> +           
> >> this.valueNameAcsr =
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
> >> +            if
> >> (this.valueNameAcsr.isEmpty()) this.valueNameAcsr
> =
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-name"));
> >> +           
> >> this.listNameAcsr =
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
> >> +            if
> >> (this.listNameAcsr.isEmpty()) this.listNameAcsr =
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list-name"));
> >> +           
> >> this.relationName =
> >> getRelatedElement.getAttribute("relation-name");
> >> +           
> this.mapAcsr =
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
> >> +            if
> >> (this.mapAcsr.isEmpty()) this.mapAcsr =
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map-name"));
> >> +           
> >> this.orderByListAcsr =
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
> >> +            if
> >> (this.orderByListAcsr.isEmpty())
> this.orderByListAcsr =
> >>
> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list-name"));
> >> +           
> this.useCache =
> >>
> "true".equals(getRelatedElement.getAttribute("use-cache"));
> >> +        }
> >> +
> >> +        @Override
> >> +        public void
> >> runAction(Map<String, Object> context) {
> >> +            Object
> >> valueObject = valueNameAcsr.get(context);
> >> +            if
> (valueObject
> >> == null) {
> >> +           
>    
> >> Debug.logVerbose("Value not found with name: " +
> >> valueNameAcsr + ", not getting related...",
> module);
> >> +           
>    
> >> return;
> >> +            }
> >> +            if
> >> (!(valueObject instanceof GenericValue)) {
> >> +           
>    
> >> String errMsg = "Env variable for value-name " +
> >> valueNameAcsr.toString() + " is not a GenericValue
> object;
> >> for the relation-name: " + relationName + "]";
> >> +           
>    
> >> Debug.logError(errMsg, module);
> >> +           
>    
> >> throw new IllegalArgumentException(errMsg);
> >> +            }
> >> +           
> GenericValue
> >> value = (GenericValue) valueObject;
> >> +           
> >> List<String> orderByNames = null;
> >> +            if
> >> (!orderByListAcsr.isEmpty()) {
> >> +           
>    
> >> orderByNames = orderByListAcsr.get(context);
> >> +            }
> >> +           
> Map<String,
> >> Object> constraintMap = null;
> >> +            if
> >> (!mapAcsr.isEmpty()) {
> >> +           
>    
> >> constraintMap = mapAcsr.get(context);
> >> +            }
> >> +            try {
> >> +             
>   if
> >> (useCache) {
> >> +           
>    
> >>     listNameAcsr.put(context,
> >> value.getRelatedCache(relationName,
> constraintMap,
> >> orderByNames));
> >> +             
>   }
> >> else {
> >> +           
>    
> >>     listNameAcsr.put(context,
> >> value.getRelated(relationName, constraintMap,
> >> orderByNames));
> >> +             
>   }
> >> +            }
> catch
> >> (GenericEntityException e) {
> >> +           
>    
> >> String errMsg = "Problem getting related from
> entity with
> >> name " + value.getEntityName() + " for the
> relation-name: "
> >> + relationName + ": " + e.getMessage();
> >> +           
>    
> >> Debug.logError(e, errMsg, module);
> >> +           
>    
> >> throw new IllegalArgumentException(errMsg);
> >> +            }
> >> +        }
> >> +
> >> +        public String
> >> getRelationName() {
> >> +            return
> >> this.relationName;
> >> +        }
> >> +    }
> >> +}
> >> 
> >> Propchange:
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>
> ------------------------------------------------------------------------------
> >>     svn:eol-style = native
> >> 
> >> Propchange:
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>
> ------------------------------------------------------------------------------
> >>     svn:keywords = "Date Rev
> Author URL Id"
> >> 
> >> Propchange:
> >>
> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
> >>
> ------------------------------------------------------------------------------
> >>     svn:mime-type =
> text/plain
> >> 
> >> 
> >> 
> > 
> > 
> > 
> 
> 


      

Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java

Posted by Scott Gray <sc...@hotwaxmedia.com>.
Yeah no worries.  I'd never really thought about it before until yesterday when I came across a problem in the ModelMenuAction.PropertyMap action, it replaces the existing uiLabelMap instead of adding to it like the ModelScreenAction version does.  Option was to either just copy and paste the screen version or take the plunge and sort it all out.

Regards
Scott

On 2/07/2010, at 6:45 PM, Adrian Crum wrote:

> Thanks! That duplication always bothered me.
> 
> -Adrian
> 
> --- On Thu, 7/1/10, lektran@apache.org <le...@apache.org> wrote:
> 
>> From: lektran@apache.org <le...@apache.org>
>> Subject: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> To: commits@ofbiz.apache.org
>> Date: Thursday, July 1, 2010, 11:38 PM
>> Author: lektran
>> Date: Fri Jul  2 06:38:52 2010
>> New Revision: 959875
>> 
>> URL: http://svn.apache.org/viewvc?rev=959875&view=rev
>> Log:
>> Added a new class ModelWidgetAction which will serve to
>> replace the duplicate classes ModelScreenAction,
>> ModelFormAction and ModelMenuAction.  This class is
>> virtually a direct copy of ModelScreenAction and its
>> subclasses.  I'll work over the weekend to switch the
>> existing classes to extend from ModelWidgetAction, remove
>> their methods and then deprecate the shells that are left
>> behind.
>> 
>> Added:
>>    
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java   (with
>> props)
>> 
>> Added:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java?rev=959875&view=auto
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> (added)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> Fri Jul  2 06:38:52 2010
>> @@ -0,0 +1,700 @@
>> +/*******************************************************************************
>> + * 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;
>> +
>> +import java.io.Serializable;
>> +import java.text.MessageFormat;
>> +import java.util.ArrayList;
>> +import java.util.List;
>> +import java.util.Locale;
>> +import java.util.Map;
>> +import java.util.TimeZone;
>> +import java.util.regex.PatternSyntaxException;
>> +
>> +import javax.servlet.ServletContext;
>> +import javax.servlet.http.HttpSession;
>> +
>> +import javolution.util.FastList;
>> +import javolution.util.FastMap;
>> +
>> +import org.w3c.dom.Element;
>> +import org.codehaus.groovy.runtime.InvokerHelper;
>> +import org.ofbiz.base.util.BshUtil;
>> +import org.ofbiz.base.util.Debug;
>> +import org.ofbiz.base.util.GeneralException;
>> +import org.ofbiz.base.util.GroovyUtil;
>> +import org.ofbiz.base.util.ObjectType;
>> +import org.ofbiz.base.util.StringUtil;
>> +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.collections.FlexibleMapAccessor;
>> +import
>> org.ofbiz.base.util.collections.ResourceBundleMapWrapper;
>> +import org.ofbiz.base.util.string.FlexibleStringExpander;
>> +import org.ofbiz.entity.GenericEntityException;
>> +import org.ofbiz.entity.GenericValue;
>> +import org.ofbiz.entity.finder.ByAndFinder;
>> +import org.ofbiz.entity.finder.ByConditionFinder;
>> +import org.ofbiz.entity.finder.EntityFinderUtil;
>> +import org.ofbiz.entity.finder.PrimaryKeyFinder;
>> +import org.ofbiz.minilang.MiniLangException;
>> +import org.ofbiz.minilang.SimpleMethod;
>> +import org.ofbiz.minilang.method.MethodContext;
>> +import org.ofbiz.service.DispatchContext;
>> +import org.ofbiz.service.GenericServiceException;
>> +import org.ofbiz.service.ModelService;
>> +
>> +@SuppressWarnings("serial")
>> +public abstract class ModelWidgetAction implements
>> Serializable {
>> +    public static final String module =
>> ModelWidgetAction.class.getName();
>> +
>> +    protected ModelWidget modelWidget;
>> +
>> +    protected ModelWidgetAction() {}
>> +
>> +    public ModelWidgetAction(ModelWidget
>> modelWidget, Element actionElement) {
>> +        this.modelWidget =
>> modelWidget;
>> +        if (Debug.verboseOn())
>> Debug.logVerbose("Reading widget action with name: " +
>> actionElement.getNodeName(), module);
>> +    }
>> +
>> +    public abstract void
>> runAction(Map<String, Object> context) throws
>> GeneralException;
>> +
>> +    public static List<ModelWidgetAction>
>> readSubActions(ModelWidget modelWidget, Element
>> parentElement) {
>> +        List<ModelWidgetAction>
>> actions = FastList.newInstance();
>> +
>> +        List<? extends Element>
>> actionElementList =
>> UtilXml.childElementList(parentElement);
>> +        for (Element actionElement:
>> actionElementList) {
>> +            if
>> ("set".equals(actionElement.getNodeName())) {
>> +               
>> actions.add(new SetField(modelWidget, actionElement));
>> +            } else if
>> ("property-map".equals(actionElement.getNodeName())) {
>> +               
>> actions.add(new PropertyMap(modelWidget, actionElement));
>> +            } else if
>> ("property-to-field".equals(actionElement.getNodeName())) {
>> +               
>> actions.add(new PropertyToField(modelWidget,
>> actionElement));
>> +            } else if
>> ("script".equals(actionElement.getNodeName())) {
>> +               
>> actions.add(new Script(modelWidget, actionElement));
>> +            } else if
>> ("service".equals(actionElement.getNodeName())) {
>> +               
>> actions.add(new Service(modelWidget, actionElement));
>> +            } else if
>> ("entity-one".equals(actionElement.getNodeName())) {
>> +               
>> actions.add(new EntityOne(modelWidget, actionElement));
>> +            } else if
>> ("entity-and".equals(actionElement.getNodeName())) {
>> +               
>> actions.add(new EntityAnd(modelWidget, actionElement));
>> +            } else if
>> ("entity-condition".equals(actionElement.getNodeName())) {
>> +               
>> actions.add(new EntityCondition(modelWidget,
>> actionElement));
>> +            } else if
>> ("get-related-one".equals(actionElement.getNodeName())) {
>> +               
>> actions.add(new GetRelatedOne(modelWidget, actionElement));
>> +            } else if
>> ("get-related".equals(actionElement.getNodeName())) {
>> +               
>> actions.add(new GetRelated(modelWidget, actionElement));
>> +            } else {
>> +               
>> throw new IllegalArgumentException("Action element not
>> supported with name: " + actionElement.getNodeName());
>> +            }
>> +        }
>> +
>> +        return actions;
>> +    }
>> +
>> +    public static void
>> runSubActions(List<ModelWidgetAction> actions,
>> Map<String, Object> context) throws GeneralException
>> {
>> +        if (actions == null) return;
>> +
>> +        for (ModelWidgetAction action:
>> actions) {
>> +            if
>> (Debug.verboseOn()) Debug.logVerbose("Running widget action
>> " + action.getClass().getName(), module);
>> +           
>> action.runAction(context);
>> +        }
>> +    }
>> +
>> +    public static class SetField extends
>> ModelWidgetAction {
>> +        protected
>> FlexibleMapAccessor<Object> field;
>> +        protected
>> FlexibleMapAccessor<Object> fromField;
>> +        protected
>> FlexibleStringExpander valueExdr;
>> +        protected
>> FlexibleStringExpander defaultExdr;
>> +        protected
>> FlexibleStringExpander globalExdr;
>> +        protected String type;
>> +        protected String toScope;
>> +        protected String fromScope;
>> +
>> +        public SetField(ModelWidget
>> modelWidget, Element setElement) {
>> +            super
>> (modelWidget, setElement);
>> +            this.field =
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
>> +            this.fromField =
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("from-field"));
>> +            this.valueExdr =
>> FlexibleStringExpander.getInstance(setElement.getAttribute("value"));
>> +            this.defaultExdr
>> =
>> FlexibleStringExpander.getInstance(setElement.getAttribute("default-value"));
>> +            this.globalExdr
>> =
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>> +            this.type =
>> setElement.getAttribute("type");
>> +            this.toScope =
>> setElement.getAttribute("to-scope");
>> +            this.fromScope =
>> setElement.getAttribute("from-scope");
>> +            if
>> (!this.fromField.isEmpty() &&
>> !this.valueExdr.isEmpty()) {
>> +               
>> throw new IllegalArgumentException("Cannot specify a
>> from-field [" + setElement.getAttribute("from-field") + "]
>> and a value [" + setElement.getAttribute("value") + "] on
>> the set action in a widget");
>> +            }
>> +        }
>> +
>> +        @Override
>> +        public void
>> runAction(Map<String, Object> context) {
>> +            String globalStr
>> = this.globalExdr.expandString(context);
>> +            // default to
>> false
>> +            boolean global =
>> "true".equals(globalStr);
>> +
>> +            Object newValue
>> = null;
>> +            if
>> (this.fromScope != null &&
>> this.fromScope.equals("user")) {
>> +                if
>> (!this.fromField.isEmpty()) {
>> +               
>>     HttpSession session = (HttpSession)
>> context.get("session");
>> +               
>>     newValue =
>> getInMemoryPersistedFromField(session, context);
>> +               
>>     if (Debug.verboseOn()) Debug.logVerbose("In
>> user getting value for field from [" +
>> this.fromField.getOriginalName() + "]: " + newValue,
>> module);
>> +                }
>> else if (!this.valueExdr.isEmpty()) {
>> +               
>>     newValue = this.valueExdr.expand(context);
>> +                }
>> +            } else if
>> (this.fromScope != null &&
>> this.fromScope.equals("application")) {
>> +                if
>> (!this.fromField.isEmpty()) {
>> +               
>>     ServletContext servletContext =
>> (ServletContext) context.get("application");
>> +               
>>     newValue =
>> getInMemoryPersistedFromField(servletContext, context);
>> +               
>>     if (Debug.verboseOn()) Debug.logVerbose("In
>> application getting value for field from [" +
>> this.fromField.getOriginalName() + "]: " + newValue,
>> module);
>> +                }
>> else if (!this.valueExdr.isEmpty()) {
>> +               
>>     newValue =
>> this.valueExdr.expandString(context);
>> +                }
>> +            } else {
>> +                if
>> (!this.fromField.isEmpty()) {
>> +               
>>     newValue = this.fromField.get(context);
>> +               
>>     if (Debug.verboseOn())
>> Debug.logVerbose("Getting value for field from [" +
>> this.fromField.getOriginalName() + "]: " + newValue,
>> module);
>> +                }
>> else if (!this.valueExdr.isEmpty()) {
>> +               
>>     newValue = this.valueExdr.expand(context);
>> +                }
>> +            }
>> +
>> +            // If newValue
>> is still empty, use the default value
>> +            if
>> (ObjectType.isEmpty(newValue) &&
>> !this.defaultExdr.isEmpty()) {
>> +               
>> newValue = this.defaultExdr.expand(context);
>> +            }
>> +
>> +            if
>> (UtilValidate.isNotEmpty(this.type)) {
>> +                if
>> ("NewMap".equals(this.type)) {
>> +               
>>     newValue = FastMap.newInstance();
>> +                }
>> else if ("NewList".equals(this.type)) {
>> +               
>>     newValue = FastList.newInstance();
>> +                }
>> else {
>> +               
>>     try {
>> +               
>>         newValue =
>> ObjectType.simpleTypeConvert(newValue, this.type, null,
>> (TimeZone) context.get("timeZone"), (Locale)
>> context.get("locale"), true);
>> +               
>>     } catch (GeneralException e) {
>> +               
>>         String errMsg = "Could not
>> convert field value for the field: [" +
>> this.field.getOriginalName() + "] to the [" + this.type + "]
>> type for the value [" + newValue + "]: " + e.toString();
>> +               
>>         Debug.logError(e, errMsg,
>> module);
>> +               
>>         throw new
>> IllegalArgumentException(errMsg);
>> +               
>>     }
>> +                }
>> +            }
>> +
>> +            if (this.toScope
>> != null && this.toScope.equals("user")) {
>> +               
>> String originalName = this.field.getOriginalName();
>> +               
>> List<String> currentWidgetTrail =
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>> +               
>> String newKey = "";
>> +                if
>> (currentWidgetTrail != null) {
>> +               
>>     newKey = StringUtil.join(currentWidgetTrail,
>> "|");
>> +                }
>> +                if
>> (UtilValidate.isNotEmpty(newKey)) {
>> +               
>>     newKey += "|";
>> +                }
>> +               
>> newKey += originalName;
>> +               
>> HttpSession session = (HttpSession)context.get("session");
>> +               
>> session.setAttribute(newKey, newValue);
>> +                if
>> (Debug.verboseOn()) Debug.logVerbose("In user setting value
>> for field from [" + this.field.getOriginalName() + "]: " +
>> newValue, module);
>> +            } else if
>> (this.toScope != null &&
>> this.toScope.equals("application")) {
>> +               
>> String originalName = this.field.getOriginalName();
>> +               
>> List<String> currentWidgetTrail =
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>> +               
>> String newKey = "";
>> +                if
>> (currentWidgetTrail != null) {
>> +               
>>     newKey = StringUtil.join(currentWidgetTrail,
>> "|");
>> +                }
>> +                if
>> (UtilValidate.isNotEmpty(newKey)) {
>> +               
>>     newKey += "|";
>> +                }
>> +               
>> newKey += originalName;
>> +               
>> ServletContext servletContext =
>> (ServletContext)context.get("application");
>> +               
>> servletContext.setAttribute(newKey, newValue);
>> +                if
>> (Debug.verboseOn()) Debug.logVerbose("In application setting
>> value for field from [" + this.field.getOriginalName() + "]:
>> " + newValue, module);
>> +            } else {
>> +                //
>> only do this if it is not global, if global ONLY put it in
>> the global context
>> +                if
>> (!global) {
>> +               
>>     if (Debug.verboseOn())
>> Debug.logVerbose("Setting field [" +
>> this.field.getOriginalName() + "] to value: " + newValue,
>> module);
>> +               
>>     this.field.put(context, newValue);
>> +                }
>> +            }
>> +
>> +            if (global) {
>> +               
>> Map<String, Object> globalCtx =
>> UtilGenerics.checkMap(context.get("globalContext"));
>> +                if
>> (globalCtx != null) {
>> +               
>>     this.field.put(globalCtx, newValue);
>> +                }
>> else {
>> +               
>>     this.field.put(context, newValue);
>> +                }
>> +            }
>> +
>> +            // this is a
>> hack for backward compatibility with the JPublish page
>> object
>> +            Map<String,
>> Object> page =
>> UtilGenerics.checkMap(context.get("page"));
>> +            if (page !=
>> null) {
>> +               
>> this.field.put(page, newValue);
>> +            }
>> +        }
>> +
>> +        public Object
>> getInMemoryPersistedFromField(Object storeAgent,
>> Map<String, Object> context) {
>> +            Object newValue
>> = null;
>> +            String
>> originalName = this.fromField.getOriginalName();
>> +           
>> List<String> currentWidgetTrail =
>> UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
>> +           
>> List<String> trailList = new
>> ArrayList<String>();
>> +            if
>> (currentWidgetTrail != null) {
>> +               
>> trailList.addAll(currentWidgetTrail);
>> +            }
>> +
>> +            for (int
>> i=trailList.size(); i >= 0; i--) {
>> +               
>> List<String> subTrail = trailList.subList(0,i);
>> +               
>> String newKey = null;
>> +                if
>> (subTrail.size() > 0)
>> +               
>>     newKey = StringUtil.join(subTrail, "|") + "|"
>> + originalName;
>> +               
>> else
>> +               
>>     newKey = originalName;
>> +
>> +                if
>> (storeAgent instanceof ServletContext) {
>> +               
>>     newValue =
>> ((ServletContext)storeAgent).getAttribute(newKey);
>> +                }
>> else if (storeAgent instanceof HttpSession) {
>> +               
>>     newValue =
>> ((HttpSession)storeAgent).getAttribute(newKey);
>> +                }
>> +                if
>> (newValue != null) {
>> +               
>>     break;
>> +                }
>> +            }
>> +            return
>> newValue;
>> +        }
>> +    }
>> +
>> +    public static class PropertyMap extends
>> ModelWidgetAction {
>> +        protected
>> FlexibleStringExpander resourceExdr;
>> +        protected
>> FlexibleMapAccessor<ResourceBundleMapWrapper>
>> mapNameAcsr;
>> +        protected
>> FlexibleStringExpander globalExdr;
>> +
>> +        public PropertyMap(ModelWidget
>> modelWidget, Element setElement) {
>> +            super
>> (modelWidget, setElement);
>> +           
>> this.resourceExdr =
>> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
>> +            this.mapNameAcsr
>> =
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("map-name"));
>> +            this.globalExdr
>> =
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>> +        }
>> +
>> +        @Override
>> +        public void
>> runAction(Map<String, Object> context) {
>> +            String globalStr
>> = this.globalExdr.expandString(context);
>> +            // default to
>> false
>> +            boolean global =
>> "true".equals(globalStr);
>> +
>> +            Locale locale =
>> (Locale) context.get("locale");
>> +            String resource
>> = this.resourceExdr.expandString(context, locale);
>> +
>> +           
>> ResourceBundleMapWrapper existingPropMap =
>> this.mapNameAcsr.get(context);
>> +            if
>> (existingPropMap == null) {
>> +               
>> this.mapNameAcsr.put(context,
>> UtilProperties.getResourceBundleMap(resource, locale,
>> context));
>> +            } else {
>> +               
>> try {
>> +               
>>    
>> existingPropMap.addBottomResourceBundle(resource);
>> +                }
>> catch (IllegalArgumentException e) {
>> +               
>>     // log the error, but don't let it kill
>> everything just for a typo or bad char in an l10n file
>> +               
>>     Debug.logError(e, "Error adding resource
>> bundle [" + resource + "]: " + e.toString(), module);
>> +                }
>> +            }
>> +
>> +            if (global) {
>> +               
>> Map<String, Object> globalCtx =
>> UtilGenerics.checkMap(context.get("globalContext"));
>> +                if
>> (globalCtx != null) {
>> +               
>>     ResourceBundleMapWrapper globalExistingPropMap
>> = this.mapNameAcsr.get(globalCtx);
>> +               
>>     if (globalExistingPropMap == null) {
>> +               
>>         this.mapNameAcsr.put(globalCtx,
>> UtilProperties.getResourceBundleMap(resource, locale,
>> context));
>> +               
>>     } else {
>> +               
>>         // is it the same object? if not
>> add it in here too...
>> +               
>>         if (existingPropMap !=
>> globalExistingPropMap) {
>> +               
>>             try {
>> +               
>>                
>> globalExistingPropMap.addBottomResourceBundle(resource);
>> +               
>>             } catch
>> (IllegalArgumentException e) {
>> +               
>>                 //
>> log the error, but don't let it kill everything just for a
>> typo or bad char in an l10n file
>> +               
>>                
>> Debug.logError(e, "Error adding resource bundle [" +
>> resource + "]: " + e.toString(), module);
>> +               
>>             }
>> +               
>>         }
>> +               
>>     }
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    public static class PropertyToField extends
>> ModelWidgetAction {
>> +
>> +        protected
>> FlexibleStringExpander resourceExdr;
>> +        protected
>> FlexibleStringExpander propertyExdr;
>> +        protected
>> FlexibleMapAccessor<Object> fieldAcsr;
>> +        protected
>> FlexibleStringExpander defaultExdr;
>> +        protected boolean noLocale;
>> +        protected
>> FlexibleMapAccessor<List<? extends Object>>
>> argListAcsr;
>> +        protected
>> FlexibleStringExpander globalExdr;
>> +
>> +        public
>> PropertyToField(ModelWidget modelWidget, Element setElement)
>> {
>> +            super
>> (modelWidget, setElement);
>> +           
>> this.resourceExdr =
>> FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
>> +           
>> this.propertyExdr =
>> FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
>> +            this.fieldAcsr =
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
>> +            this.defaultExdr
>> =
>> FlexibleStringExpander.getInstance(setElement.getAttribute("default"));
>> +            this.noLocale =
>> "true".equals(setElement.getAttribute("no-locale"));
>> +            this.argListAcsr
>> =
>> FlexibleMapAccessor.getInstance(setElement.getAttribute("arg-list-name"));
>> +            this.globalExdr
>> =
>> FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
>> +        }
>> +
>> +        @Override
>> +        public void
>> runAction(Map<String, Object> context) {
>> +            //String
>> globalStr = this.globalExdr.expandString(context);
>> +            // default to
>> false
>> +            //boolean global
>> = "true".equals(globalStr);
>> +
>> +            Locale locale =
>> (Locale) context.get("locale");
>> +            String resource
>> = this.resourceExdr.expandString(context, locale);
>> +            String property
>> = this.propertyExdr.expandString(context, locale);
>> +
>> +            String value =
>> null;
>> +            if (noLocale) {
>> +               
>> value = UtilProperties.getPropertyValue(resource,
>> property);
>> +            } else {
>> +               
>> value = UtilProperties.getMessage(resource, property,
>> locale);
>> +            }
>> +            if
>> (UtilValidate.isEmpty(value)) {
>> +               
>> value = this.defaultExdr.expandString(context);
>> +            }
>> +
>> +            // note that
>> expanding the value string here will handle defaultValue and
>> the string from
>> +            //  the
>> properties file; if we decide later that we don't want the
>> string from the properties
>> +            //  file to
>> be expanded we should just expand the defaultValue at the
>> beginning of this method.
>> +            value =
>> FlexibleStringExpander.expandString(value, context);
>> +
>> +            if
>> (!argListAcsr.isEmpty()) {
>> +               
>> List<? extends Object> argList =
>> argListAcsr.get(context);
>> +                if
>> (UtilValidate.isNotEmpty(argList)) {
>> +               
>>     value = MessageFormat.format(value,
>> argList.toArray());
>> +                }
>> +            }
>> +           
>> fieldAcsr.put(context, value);
>> +        }
>> +    }
>> +
>> +    public static class Script extends
>> ModelWidgetAction {
>> +        protected static final
>> Object[] EMPTY_ARGS = {};
>> +        protected String location;
>> +        protected String method;
>> +
>> +        public Script(ModelWidget
>> modelWidget, Element scriptElement) {
>> +            super
>> (modelWidget, scriptElement);
>> +            String
>> scriptLocation = scriptElement.getAttribute("location");
>> +            this.location =
>> WidgetWorker.getScriptLocation(scriptLocation);
>> +            this.method =
>> WidgetWorker.getScriptMethodName(scriptLocation);
>> +        }
>> +
>> +        @Override
>> +        public void
>> runAction(Map<String, Object> context) throws
>> GeneralException {
>> +            if
>> (location.endsWith(".bsh")) {
>> +               
>> try {
>> +               
>>     BshUtil.runBshAtLocation(location, context);
>> +                }
>> catch (GeneralException e) {
>> +               
>>     throw new GeneralException("Error running BSH
>> script at location [" + location + "]", e);
>> +                }
>> +            } else if
>> (location.endsWith(".groovy")) {
>> +               
>> try {
>> +               
>>     groovy.lang.Script script =
>> InvokerHelper.createScript(GroovyUtil.getScriptClassFromLocation(location),
>> GroovyUtil.getBinding(context));
>> +               
>>     if (UtilValidate.isEmpty(method)) {
>> +               
>>         script.run();
>> +               
>>     } else {
>> +               
>>         script.invokeMethod(method,
>> EMPTY_ARGS);
>> +               
>>     }
>> +                }
>> catch (GeneralException e) {
>> +               
>>     throw new GeneralException("Error running
>> Groovy script at location [" + location + "]", e);
>> +                }
>> +            } else if
>> (location.endsWith(".xml")) {
>> +               
>> Map<String, Object> localContext =
>> FastMap.newInstance();
>> +               
>> localContext.putAll(context);
>> +               
>> DispatchContext ctx =
>> WidgetWorker.getDispatcher(context).getDispatchContext();
>> +               
>> MethodContext methodContext = new MethodContext(ctx,
>> localContext, null);
>> +               
>> try {
>> +               
>>     SimpleMethod.runSimpleMethod(location, method,
>> methodContext);
>> +               
>>     context.putAll(methodContext.getResults());
>> +                }
>> catch (MiniLangException e) {
>> +               
>>     throw new GeneralException("Error running
>> simple method at location [" + location + "]", e);
>> +                }
>> +            } else {
>> +               
>> throw new GeneralException("For widget script actions the
>> script type is not yet supported for location: [" + location
>> + "]");
>> +            }
>> +        }
>> +    }
>> +
>> +    public static class Service extends
>> ModelWidgetAction {
>> +        protected
>> FlexibleStringExpander serviceNameExdr;
>> +        protected
>> FlexibleMapAccessor<Map<String, Object>>
>> resultMapNameAcsr;
>> +        protected
>> FlexibleStringExpander autoFieldMapExdr;
>> +        protected
>> Map<FlexibleMapAccessor<Object>, Object>
>> fieldMap;
>> +
>> +        public Service(ModelWidget
>> modelWidget, Element serviceElement) {
>> +            super
>> (modelWidget, serviceElement);
>> +           
>> this.serviceNameExdr =
>> FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
>> +           
>> this.resultMapNameAcsr =
>> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
>> +            if
>> (this.resultMapNameAcsr.isEmpty()) this.resultMapNameAcsr =
>> FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
>> +           
>> this.autoFieldMapExdr =
>> FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
>> +            this.fieldMap =
>> EntityFinderUtil.makeFieldMap(serviceElement);
>> +        }
>> +
>> +        @Override
>> +        public void
>> runAction(Map<String, Object> context) {
>> +            String
>> serviceNameExpanded =
>> this.serviceNameExdr.expandString(context);
>> +            if
>> (UtilValidate.isEmpty(serviceNameExpanded)) {
>> +               
>> throw new IllegalArgumentException("Service name was empty,
>> expanded from: " + this.serviceNameExdr.getOriginal());
>> +            }
>> +
>> +            String
>> autoFieldMapString =
>> this.autoFieldMapExdr.expandString(context);
>> +
>> +            try {
>> +               
>> Map<String, Object> serviceContext = null;
>> +                if
>> ("true".equals(autoFieldMapString)) {
>> +               
>>     DispatchContext dc =
>> WidgetWorker.getDispatcher(context).getDispatchContext();
>> +               
>>     // try a map called "parameters", try it first
>> so values from here are overriden by values in the main
>> context
>> +               
>>     Map<String, Object> combinedMap =
>> FastMap.newInstance();
>> +               
>>     Map<String, Object> parametersObj =
>> UtilGenerics.toMap(context.get("parameters"));
>> +               
>>     if (parametersObj != null) {
>> +               
>>        
>> combinedMap.putAll(parametersObj);
>> +               
>>     }
>> +               
>>     combinedMap.putAll(context);
>> +               
>>     serviceContext =
>> dc.makeValidContext(serviceNameExpanded,
>> ModelService.IN_PARAM, combinedMap);
>> +                }
>> else if (UtilValidate.isNotEmpty(autoFieldMapString)
>> && !"false".equals(autoFieldMapString)) {
>> +               
>>     FlexibleMapAccessor<Object> fieldFma =
>> FlexibleMapAccessor.getInstance(autoFieldMapString);
>> +               
>>     Map<String, Object> autoFieldMap =
>> UtilGenerics.toMap(fieldFma.get(context));
>> +               
>>     if (autoFieldMap != null) {
>> +               
>>         serviceContext =
>> WidgetWorker.getDispatcher(context).getDispatchContext().makeValidContext(serviceNameExpanded,
>> ModelService.IN_PARAM, autoFieldMap);
>> +               
>>     }
>> +                }
>> +                if
>> (serviceContext == null) {
>> +               
>>     serviceContext = FastMap.newInstance();
>> +                }
>> +
>> +                if
>> (this.fieldMap != null) {
>> +               
>>    
>> EntityFinderUtil.expandFieldMapToContext(this.fieldMap,
>> context, serviceContext);
>> +                }
>> +
>> +               
>> Map<String, Object> result =
>> WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded,
>> serviceContext);
>> +
>> +                if
>> (!this.resultMapNameAcsr.isEmpty()) {
>> +               
>>     this.resultMapNameAcsr.put(context, result);
>> +               
>>     String queryString =
>> (String)result.get("queryString");
>> +               
>>     context.put("queryString", queryString);
>> +               
>>     context.put("queryStringMap",
>> result.get("queryStringMap"));
>> +               
>>     if (UtilValidate.isNotEmpty(queryString)) {
>> +               
>>         try {
>> +               
>>             String
>> queryStringEncoded = queryString.replaceAll("&",
>> "%26");
>> +               
>>            
>> context.put("queryStringEncoded", queryStringEncoded);
>> +               
>>         } catch (PatternSyntaxException
>> e) {
>> +
>> +               
>>         }
>> +               
>>     }
>> +                }
>> else {
>> +               
>>     context.putAll(result);
>> +                }
>> +            } catch
>> (GenericServiceException e) {
>> +               
>> String errMsg = "Error calling service with name " +
>> serviceNameExpanded + ": " + e.toString();
>> +               
>> Debug.logError(e, errMsg, module);
>> +               
>> throw new IllegalArgumentException(errMsg);
>> +            }
>> +        }
>> +
>> +        public FlexibleStringExpander
>> getServiceNameExdr() {
>> +            return
>> this.serviceNameExdr;
>> +        }
>> +    }
>> +
>> +    public static class EntityOne extends
>> ModelWidgetAction {
>> +        protected PrimaryKeyFinder
>> finder;
>> +
>> +        public EntityOne(ModelWidget
>> modelWidget, Element entityOneElement) {
>> +            super
>> (modelWidget, entityOneElement);
>> +            finder = new
>> PrimaryKeyFinder(entityOneElement);
>> +        }
>> +
>> +        @Override
>> +        public void
>> runAction(Map<String, Object> context) {
>> +            try {
>> +               
>> finder.runFind(context,
>> WidgetWorker.getDelegator(context));
>> +            } catch
>> (GeneralException e) {
>> +               
>> String errMsg = "Error doing entity query by condition: " +
>> e.toString();
>> +               
>> Debug.logError(e, errMsg, module);
>> +               
>> throw new IllegalArgumentException(errMsg);
>> +            }
>> +        }
>> +
>> +        public PrimaryKeyFinder
>> getFinder() {
>> +            return
>> this.finder;
>> +        }
>> +    }
>> +
>> +    public static class EntityAnd extends
>> ModelWidgetAction {
>> +        protected ByAndFinder finder;
>> +
>> +        public EntityAnd(ModelWidget
>> modelWidget, Element entityAndElement) {
>> +            super
>> (modelWidget, entityAndElement);
>> +            finder = new
>> ByAndFinder(entityAndElement);
>> +        }
>> +
>> +        @Override
>> +        public void
>> runAction(Map<String, Object> context) {
>> +            try {
>> +               
>> finder.runFind(context,
>> WidgetWorker.getDelegator(context));
>> +            } catch
>> (GeneralException e) {
>> +               
>> String errMsg = "Error doing entity query by condition: " +
>> e.toString();
>> +               
>> Debug.logError(e, errMsg, module);
>> +               
>> throw new IllegalArgumentException(errMsg);
>> +            }
>> +        }
>> +
>> +        public ByAndFinder getFinder()
>> {
>> +            return
>> this.finder;
>> +        }
>> +    }
>> +
>> +    public static class EntityCondition extends
>> ModelWidgetAction {
>> +        ByConditionFinder finder;
>> +
>> +        public
>> EntityCondition(ModelWidget modelWidget, Element
>> entityConditionElement) {
>> +            super
>> (modelWidget, entityConditionElement);
>> +            finder = new
>> ByConditionFinder(entityConditionElement);
>> +        }
>> +
>> +        @Override
>> +        public void
>> runAction(Map<String, Object> context) {
>> +            try {
>> +               
>> finder.runFind(context,
>> WidgetWorker.getDelegator(context));
>> +            } catch
>> (GeneralException e) {
>> +               
>> String errMsg = "Error doing entity query by condition: " +
>> e.toString();
>> +               
>> Debug.logError(e, errMsg, module);
>> +               
>> throw new IllegalArgumentException(errMsg);
>> +            }
>> +        }
>> +
>> +        public ByConditionFinder
>> getFinder() {
>> +            return
>> this.finder;
>> +        }
>> +    }
>> +
>> +    public static class GetRelatedOne extends
>> ModelWidgetAction {
>> +        protected
>> FlexibleMapAccessor<Object> valueNameAcsr;
>> +        protected
>> FlexibleMapAccessor<Object> toValueNameAcsr;
>> +        protected String
>> relationName;
>> +        protected boolean useCache;
>> +
>> +        public
>> GetRelatedOne(ModelWidget modelWidget, Element
>> getRelatedOneElement) {
>> +            super
>> (modelWidget, getRelatedOneElement);
>> +           
>> this.valueNameAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
>> +            if
>> (this.valueNameAcsr.isEmpty()) this.valueNameAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-name"));
>> +           
>> this.toValueNameAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
>> +            if
>> (this.toValueNameAcsr.isEmpty()) this.toValueNameAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-name"));
>> +           
>> this.relationName =
>> getRelatedOneElement.getAttribute("relation-name");
>> +            this.useCache =
>> "true".equals(getRelatedOneElement.getAttribute("use-cache"));
>> +        }
>> +
>> +        @Override
>> +        public void
>> runAction(Map<String, Object> context) {
>> +            Object
>> valueObject = valueNameAcsr.get(context);
>> +            if (valueObject
>> == null) {
>> +               
>> Debug.logVerbose("Value not found with name: " +
>> valueNameAcsr + ", not getting related...", module);
>> +               
>> return;
>> +            }
>> +            if
>> (!(valueObject instanceof GenericValue)) {
>> +               
>> String errMsg = "Env variable for value-name " +
>> valueNameAcsr.toString() + " is not a GenericValue object;
>> for the relation-name: " + relationName + "]";
>> +               
>> Debug.logError(errMsg, module);
>> +               
>> throw new IllegalArgumentException(errMsg);
>> +            }
>> +            GenericValue
>> value = (GenericValue) valueObject;
>> +            try {
>> +                if
>> (useCache) {
>> +               
>>     toValueNameAcsr.put(context,
>> value.getRelatedOneCache(relationName));
>> +                }
>> else {
>> +               
>>     toValueNameAcsr.put(context,
>> value.getRelatedOne(relationName));
>> +                }
>> +            } catch
>> (GenericEntityException e) {
>> +               
>> String errMsg = "Problem getting related one from entity
>> with name " + value.getEntityName() + " for the
>> relation-name: " + relationName + ": " + e.getMessage();
>> +               
>> Debug.logError(e, errMsg, module);
>> +               
>> throw new IllegalArgumentException(errMsg);
>> +            }
>> +        }
>> +
>> +        public String
>> getRelationName() {
>> +            return
>> this.relationName;
>> +        }
>> +    }
>> +
>> +    public static class GetRelated extends
>> ModelWidgetAction {
>> +        protected
>> FlexibleMapAccessor<Object> valueNameAcsr;
>> +        protected
>> FlexibleMapAccessor<List<GenericValue>>
>> listNameAcsr;
>> +        protected
>> FlexibleMapAccessor<Map<String, Object>>
>> mapAcsr;
>> +        protected
>> FlexibleMapAccessor<List<String>>
>> orderByListAcsr;
>> +        protected String
>> relationName;
>> +        protected boolean useCache;
>> +
>> +        public GetRelated(ModelWidget
>> modelWidget, Element getRelatedElement) {
>> +            super
>> (modelWidget, getRelatedElement);
>> +           
>> this.valueNameAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
>> +            if
>> (this.valueNameAcsr.isEmpty()) this.valueNameAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-name"));
>> +           
>> this.listNameAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
>> +            if
>> (this.listNameAcsr.isEmpty()) this.listNameAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list-name"));
>> +           
>> this.relationName =
>> getRelatedElement.getAttribute("relation-name");
>> +            this.mapAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
>> +            if
>> (this.mapAcsr.isEmpty()) this.mapAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map-name"));
>> +           
>> this.orderByListAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
>> +            if
>> (this.orderByListAcsr.isEmpty()) this.orderByListAcsr =
>> FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list-name"));
>> +            this.useCache =
>> "true".equals(getRelatedElement.getAttribute("use-cache"));
>> +        }
>> +
>> +        @Override
>> +        public void
>> runAction(Map<String, Object> context) {
>> +            Object
>> valueObject = valueNameAcsr.get(context);
>> +            if (valueObject
>> == null) {
>> +               
>> Debug.logVerbose("Value not found with name: " +
>> valueNameAcsr + ", not getting related...", module);
>> +               
>> return;
>> +            }
>> +            if
>> (!(valueObject instanceof GenericValue)) {
>> +               
>> String errMsg = "Env variable for value-name " +
>> valueNameAcsr.toString() + " is not a GenericValue object;
>> for the relation-name: " + relationName + "]";
>> +               
>> Debug.logError(errMsg, module);
>> +               
>> throw new IllegalArgumentException(errMsg);
>> +            }
>> +            GenericValue
>> value = (GenericValue) valueObject;
>> +           
>> List<String> orderByNames = null;
>> +            if
>> (!orderByListAcsr.isEmpty()) {
>> +               
>> orderByNames = orderByListAcsr.get(context);
>> +            }
>> +            Map<String,
>> Object> constraintMap = null;
>> +            if
>> (!mapAcsr.isEmpty()) {
>> +               
>> constraintMap = mapAcsr.get(context);
>> +            }
>> +            try {
>> +                if
>> (useCache) {
>> +               
>>     listNameAcsr.put(context,
>> value.getRelatedCache(relationName, constraintMap,
>> orderByNames));
>> +                }
>> else {
>> +               
>>     listNameAcsr.put(context,
>> value.getRelated(relationName, constraintMap,
>> orderByNames));
>> +                }
>> +            } catch
>> (GenericEntityException e) {
>> +               
>> String errMsg = "Problem getting related from entity with
>> name " + value.getEntityName() + " for the relation-name: "
>> + relationName + ": " + e.getMessage();
>> +               
>> Debug.logError(e, errMsg, module);
>> +               
>> throw new IllegalArgumentException(errMsg);
>> +            }
>> +        }
>> +
>> +        public String
>> getRelationName() {
>> +            return
>> this.relationName;
>> +        }
>> +    }
>> +}
>> 
>> Propchange:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> ------------------------------------------------------------------------------
>>     svn:eol-style = native
>> 
>> Propchange:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> ------------------------------------------------------------------------------
>>     svn:keywords = "Date Rev Author URL Id"
>> 
>> Propchange:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
>> ------------------------------------------------------------------------------
>>     svn:mime-type = text/plain
>> 
>> 
>> 
> 
> 
>