|
Thanks! That duplication always bothered me.
-Adrian --- On Thu, 7/1/10, [hidden email] <[hidden email]> wrote: > From: [hidden email] <[hidden email]> > Subject: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java > To: [hidden email] > 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 > > > |
|
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, [hidden email] <[hidden email]> wrote: > >> From: [hidden email] <[hidden email]> >> Subject: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java >> To: [hidden email] >> 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 >> >> >> > > > |
|
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 <[hidden email]> wrote: > From: Scott Gray <[hidden email]> > Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java > To: [hidden email] > 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, [hidden email] > <[hidden email]> > wrote: > > > >> From: [hidden email] > <[hidden email]> > >> Subject: svn commit: r959875 - > /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java > >> To: [hidden email] > >> 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 > >> > >> > >> > > > > > > > > |
|
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 <[hidden email]> wrote: > >> From: Scott Gray <[hidden email]> >> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java >> To: [hidden email] >> 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, [hidden email] >> <[hidden email]> >> wrote: >>> >>>> From: [hidden email] >> <[hidden email]> >>>> Subject: svn commit: r959875 - >> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java >>>> To: [hidden email] >>>> 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 >>>> >>>> >>>> >>> >>> >>> >> >> > > > |
|
In reply to this post by Adrian Crum-2
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 |
|
In reply to this post by Adrian Crum-2
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 <[hidden email]> wrote: > >> From: Scott Gray <[hidden email]> >> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java >> To: [hidden email] >> 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, [hidden email] >> <[hidden email]> >> wrote: >>> >>>> From: [hidden email] >> <[hidden email]> >>>> Subject: svn commit: r959875 - >> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java >>>> To: [hidden email] >>>> 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 >>>> >>>> >>>> >>> >>> >>> >> >> > > > |
|
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 <[hidden email]> wrote: > From: David E Jones <[hidden email]> > Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java > To: [hidden email] > 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 <[hidden email]> > wrote: > > > >> From: Scott Gray <[hidden email]> > >> Subject: Re: svn commit: r959875 - > /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java > >> To: [hidden email] > >> 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, [hidden email] > >> <[hidden email]> > >> wrote: > >>> > >>>> From: [hidden email] > >> <[hidden email]> > >>>> Subject: svn commit: r959875 - > >> > /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java > >>>> To: [hidden email] > >>>> 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 > >>>> > >>>> > >>>> > >>> > >>> > >>> > >> > >> > > > > > > > > |
|
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 <[hidden email]> wrote: > >> From: David E Jones <[hidden email]> >> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java >> To: [hidden email] >> 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 <[hidden email]> >> wrote: >>> >>>> From: Scott Gray <[hidden email]> >>>> Subject: Re: svn commit: r959875 - >> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java >>>> To: [hidden email] >>>> 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, [hidden email] >>>> <[hidden email]> >>>> wrote: >>>>> >>>>>> From: [hidden email] >>>> <[hidden email]> >>>>>> Subject: svn commit: r959875 - >>>> >> /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java >>>>>> To: [hidden email] >>>>>> 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 >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> >>>> >>>> >>> >>> >>> >> >> > > > |
|
--- On Fri, 7/2/10, David E Jones <[hidden email]> 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 <[hidden email]> > wrote: > > > >> From: David E Jones <[hidden email]> > >> Subject: Re: svn commit: r959875 - > /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java > >> To: [hidden email] > >> 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 <[hidden email]> > >> wrote: > >>> > >>>> From: Scott Gray <[hidden email]> > >>>> Subject: Re: svn commit: r959875 - > >> > /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java > >>>> To: [hidden email] > >>>> 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, [hidden email] > >>>> <[hidden email]> > >>>> wrote: > >>>>> > >>>>>> From: [hidden email] > >>>> <[hidden email]> > >>>>>> Subject: svn commit: r959875 - > >>>> > >> > /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java > >>>>>> To: [hidden email] > >>>>>> 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 > >>>>>> > >>>>>> > >>>>>> > >>>>> > >>>>> > >>>>> > >>>> > >>>> > >>> > >>> > >>> > >> > >> > > > > > > > > |
|
On 3/07/2010, at 2:13 PM, Adrian Crum wrote:
> --- On Fri, 7/2/10, David E Jones <[hidden email]> 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. 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 |
|
Scott Gray wrote:
> On 3/07/2010, at 2:13 PM, Adrian Crum wrote: > >> --- On Fri, 7/2/10, David E Jones <[hidden email]> 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. |
|
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 <[hidden email]> 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; > } > } > == 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. > |
|
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 <[hidden email]> 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). |
|
In reply to this post by Adrian Crum-2
--- On Fri, 7/2/10, Scott Gray <[hidden email]> wrote: From: Scott Gray <[hidden email]> Subject: Re: svn commit: r959875 - /ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java To: [hidden email] Date: Friday, July 2, 2010, 8:36 PM 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 <[hidden email]> 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. ----------------------------------------------- In Adam's example, it is entirely possible that object = new Result(foo, bar); will be executed before Object foo = getFoo(); Object bar = getBar(); ----------------------------------------------- > > 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. > |
|
In reply to this post by Scott Gray-2
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. |
|
In reply to this post by Adrian Crum-2
Adrian Crum wrote:
> ----------------------------------------------- > In Adam's example, it is entirely possible that > > object = new Result(foo, bar); > > will be executed before > > Object foo = getFoo(); > Object bar = getBar(); > > ----------------------------------------------- To restate this: original: ===== Object foo = getFoo(); Object bar = getBar(); object = new Result(foo, bar); class Result { Result(Object foo, Object bar) { this.foo = foo; this.bar = bar; } String doSomething() { return foo.toString(); } } ===== jvm optimized: ===== object = [new memory block with type of Result] object.bar = getBar() object.foo = getFoo() ===== Note how object is no longer null after the first commmand, so the outer check will think everything is happy. The outer code could even call doSomething on the uninitialized block, which then tries to dereference foo, which hasn't been assigned to yet. |
|
In reply to this post by Adam Heath-2
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 <[hidden email]> 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. 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). |
|
--- On Fri, 7/2/10, Scott Gray <[hidden email]> 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. |
|
In reply to this post by Scott Gray-2
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. |
|
Administrator
|
In reply to this post by Adrian Crum-2
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" <[hidden email]> > --- On Fri, 7/2/10, Scott Gray <[hidden email]> 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. |
| Free forum by Nabble | Edit this page |
