001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.widget.menu;
019:
020: import java.text.MessageFormat;
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.LinkedList;
024: import java.util.List;
025: import java.util.Locale;
026: import java.util.Map;
027:
028: import org.ofbiz.base.util.BshUtil;
029: import org.ofbiz.base.util.Debug;
030: import org.ofbiz.base.util.GeneralException;
031: import org.ofbiz.base.util.ObjectType;
032: import org.ofbiz.base.util.UtilFormatOut;
033: import org.ofbiz.base.util.UtilProperties;
034: import org.ofbiz.base.util.UtilValidate;
035: import org.ofbiz.base.util.UtilXml;
036: import org.ofbiz.base.util.collections.FlexibleMapAccessor;
037: import org.ofbiz.base.util.string.FlexibleStringExpander;
038: import org.ofbiz.entity.finder.ByAndFinder;
039: import org.ofbiz.entity.finder.ByConditionFinder;
040: import org.ofbiz.entity.finder.PrimaryKeyFinder;
041: import org.ofbiz.service.GenericServiceException;
042: import org.ofbiz.service.ModelService;
043:
044: import org.w3c.dom.Element;
045: import javax.servlet.*;
046: import javax.servlet.http.*;
047:
048: /**
049: * Widget Library - Screen model class
050: */
051: public abstract class ModelMenuAction {
052: public static final String module = ModelMenuAction.class.getName();
053:
054: protected ModelMenu modelMenu;
055: protected ModelMenuItem modelMenuItem;
056:
057: public ModelMenuAction(ModelMenu modelMenu, Element actionElement) {
058: this .modelMenu = modelMenu;
059: if (Debug.verboseOn())
060: Debug.logVerbose("Reading Screen action with name: "
061: + actionElement.getNodeName(), module);
062: }
063:
064: public ModelMenuAction(ModelMenuItem modelMenuItem,
065: Element actionElement) {
066: this .modelMenuItem = modelMenuItem;
067: this .modelMenu = modelMenuItem.getModelMenu();
068: if (Debug.verboseOn())
069: Debug.logVerbose("Reading Screen action with name: "
070: + actionElement.getNodeName(), module);
071: }
072:
073: public abstract void runAction(Map context);
074:
075: public static List readSubActions(ModelMenuItem modelMenuItem,
076: Element parentElement) {
077: return readSubActions(modelMenuItem.getModelMenu(),
078: parentElement);
079: }
080:
081: public static List readSubActions(ModelMenu modelMenu,
082: Element parentElement) {
083: List actions = new LinkedList();
084:
085: List actionElementList = UtilXml
086: .childElementList(parentElement);
087: Iterator actionElementIter = actionElementList.iterator();
088: while (actionElementIter.hasNext()) {
089: Element actionElement = (Element) actionElementIter.next();
090: if ("set".equals(actionElement.getNodeName())) {
091: actions.add(new SetField(modelMenu, actionElement));
092: } else if ("property-map".equals(actionElement
093: .getNodeName())) {
094: actions.add(new PropertyMap(modelMenu, actionElement));
095: } else if ("property-to-field".equals(actionElement
096: .getNodeName())) {
097: actions.add(new PropertyToField(modelMenu,
098: actionElement));
099: } else if ("script".equals(actionElement.getNodeName())) {
100: actions.add(new Script(modelMenu, actionElement));
101: } else if ("service".equals(actionElement.getNodeName())) {
102: actions.add(new Service(modelMenu, actionElement));
103: } else if ("entity-one".equals(actionElement.getNodeName())) {
104: actions.add(new EntityOne(modelMenu, actionElement));
105: } else if ("entity-and".equals(actionElement.getNodeName())) {
106: actions.add(new EntityAnd(modelMenu, actionElement));
107: } else if ("entity-condition".equals(actionElement
108: .getNodeName())) {
109: actions.add(new EntityCondition(modelMenu,
110: actionElement));
111: } else {
112: throw new IllegalArgumentException(
113: "Action element not supported with name: "
114: + actionElement.getNodeName());
115: }
116: }
117:
118: return actions;
119: }
120:
121: public static void runSubActions(List actions, Map context) {
122: if (actions == null)
123: return;
124:
125: Iterator actionIter = actions.iterator();
126: while (actionIter.hasNext()) {
127: ModelMenuAction action = (ModelMenuAction) actionIter
128: .next();
129: if (Debug.verboseOn())
130: Debug.logVerbose("Running screen action "
131: + action.getClass().getName(), module);
132: action.runAction(context);
133: }
134: }
135:
136: public static class SetField extends ModelMenuAction {
137: protected FlexibleMapAccessor field;
138: protected FlexibleMapAccessor fromField;
139: protected FlexibleStringExpander valueExdr;
140: protected FlexibleStringExpander defaultExdr;
141: protected FlexibleStringExpander globalExdr;
142: protected String type;
143: protected String toScope;
144: protected String fromScope;
145:
146: public SetField(ModelMenu modelMenu, Element setElement) {
147: super (modelMenu, setElement);
148: this .field = new FlexibleMapAccessor(setElement
149: .getAttribute("field"));
150: this .fromField = UtilValidate.isNotEmpty(setElement
151: .getAttribute("from-field")) ? new FlexibleMapAccessor(
152: setElement.getAttribute("from-field"))
153: : null;
154: this .valueExdr = UtilValidate.isNotEmpty(setElement
155: .getAttribute("value")) ? new FlexibleStringExpander(
156: setElement.getAttribute("value"))
157: : null;
158: this .defaultExdr = UtilValidate.isNotEmpty(setElement
159: .getAttribute("default-value")) ? new FlexibleStringExpander(
160: setElement.getAttribute("default-value"))
161: : null;
162: this .globalExdr = new FlexibleStringExpander(setElement
163: .getAttribute("global"));
164: this .type = setElement.getAttribute("type");
165: this .toScope = setElement.getAttribute("to-scope");
166: this .fromScope = setElement.getAttribute("from-scope");
167: if (this .fromField != null && this .valueExdr != null) {
168: throw new IllegalArgumentException(
169: "Cannot specify a from-field ["
170: + setElement.getAttribute("from-field")
171: + "] and a value ["
172: + setElement.getAttribute("value")
173: + "] on the set action in a screen widget");
174: }
175: }
176:
177: public void runAction(Map context) {
178: String globalStr = this .globalExdr.expandString(context);
179: // default to false
180: boolean global = "true".equals(globalStr);
181:
182: Object newValue = null;
183: if (this .fromScope != null && this .fromScope.equals("user")) {
184: if (this .fromField != null) {
185: String originalName = this .fromField
186: .getOriginalName();
187: String currentWidgetTrail = (String) context
188: .get("_WIDGETTRAIL_");
189: String newKey = currentWidgetTrail + "|"
190: + originalName;
191: HttpSession session = (HttpSession) context
192: .get("session");
193: newValue = session.getAttribute(newKey);
194: if (Debug.verboseOn())
195: Debug.logVerbose(
196: "In user getting value for field from ["
197: + this .fromField
198: .getOriginalName()
199: + "]: " + newValue, module);
200: } else if (this .valueExdr != null) {
201: newValue = this .valueExdr.expandString(context);
202: }
203:
204: } else if (this .fromScope != null
205: && this .fromScope.equals("application")) {
206: if (this .fromField != null) {
207: String originalName = this .fromField
208: .getOriginalName();
209: String currentWidgetTrail = (String) context
210: .get("_WIDGETTRAIL_");
211: String newKey = currentWidgetTrail + "|"
212: + originalName;
213: ServletContext servletContext = (ServletContext) context
214: .get("application");
215: newValue = servletContext.getAttribute(newKey);
216: if (Debug.verboseOn())
217: Debug.logVerbose(
218: "In application getting value for field from ["
219: + this .fromField
220: .getOriginalName()
221: + "]: " + newValue, module);
222: } else if (this .valueExdr != null) {
223: newValue = this .valueExdr.expandString(context);
224: }
225:
226: } else {
227: if (this .fromField != null) {
228: newValue = this .fromField.get(context);
229: if (Debug.verboseOn())
230: Debug.logVerbose(
231: "In screen getting value for field from ["
232: + this .fromField
233: .getOriginalName()
234: + "]: " + newValue, module);
235: } else if (this .valueExdr != null) {
236: newValue = this .valueExdr.expandString(context);
237: }
238: }
239:
240: // If newValue is still empty, use the default value
241: if (this .defaultExdr != null) {
242: if (ObjectType.isEmpty(newValue)) {
243: newValue = this .defaultExdr.expandString(context);
244: }
245: }
246:
247: if (UtilValidate.isNotEmpty(this .type)) {
248: try {
249: newValue = ObjectType.simpleTypeConvert(newValue,
250: this .type, null, null);
251: } catch (GeneralException e) {
252: String errMsg = "Could not convert field value for the field: ["
253: + this .field.getOriginalName()
254: + "] to the ["
255: + this .type
256: + "] type for the value ["
257: + newValue
258: + "]: " + e.toString();
259: Debug.logError(e, errMsg, module);
260: throw new IllegalArgumentException(errMsg);
261: }
262:
263: }
264: if (this .toScope != null && this .toScope.equals("user")) {
265: String originalName = this .field.getOriginalName();
266: String currentWidgetTrail = (String) context
267: .get("_WIDGETTRAIL_");
268: String newKey = currentWidgetTrail + "|" + originalName;
269: HttpSession session = (HttpSession) context
270: .get("session");
271: session.setAttribute(newKey, newValue);
272: if (Debug.verboseOn())
273: Debug.logVerbose(
274: "In user setting value for field from ["
275: + this .field.getOriginalName()
276: + "]: " + newValue, module);
277:
278: } else if (this .toScope != null
279: && this .toScope.equals("application")) {
280: String originalName = this .field.getOriginalName();
281: String currentWidgetTrail = (String) context
282: .get("_WIDGETTRAIL_");
283: String newKey = currentWidgetTrail + "|" + originalName;
284: ServletContext servletContext = (ServletContext) context
285: .get("application");
286: servletContext.setAttribute(newKey, newValue);
287: if (Debug.verboseOn())
288: Debug.logVerbose(
289: "In application setting value for field from ["
290: + this .field.getOriginalName()
291: + "]: " + newValue, module);
292:
293: } else {
294: if (Debug.verboseOn())
295: Debug.logVerbose("In screen setting field ["
296: + this .field.getOriginalName()
297: + "] to value: " + newValue, module);
298: this .field.put(context, newValue);
299: }
300:
301: if (global) {
302: Map globalCtx = (Map) context.get("globalContext");
303: if (globalCtx != null) {
304: this .field.put(globalCtx, newValue);
305: }
306: }
307:
308: // this is a hack for backward compatibility with the JPublish page object
309: Map page = (Map) context.get("page");
310: if (page != null) {
311: this .field.put(page, newValue);
312: }
313: }
314: }
315:
316: public static class PropertyMap extends ModelMenuAction {
317: protected FlexibleStringExpander resourceExdr;
318: protected FlexibleMapAccessor mapNameAcsr;
319: protected FlexibleStringExpander globalExdr;
320:
321: public PropertyMap(ModelMenu modelMenu, Element setElement) {
322: super (modelMenu, setElement);
323: this .resourceExdr = new FlexibleStringExpander(setElement
324: .getAttribute("resource"));
325: this .mapNameAcsr = new FlexibleMapAccessor(setElement
326: .getAttribute("map-name"));
327: this .globalExdr = new FlexibleStringExpander(setElement
328: .getAttribute("global"));
329: }
330:
331: public void runAction(Map context) {
332: String globalStr = this .globalExdr.expandString(context);
333: // default to false
334: boolean global = "true".equals(globalStr);
335:
336: Locale locale = (Locale) context.get("locale");
337: String resource = this .resourceExdr.expandString(context,
338: locale);
339: Map propertyMap = UtilProperties.getResourceBundleMap(
340: resource, locale);
341: this .mapNameAcsr.put(context, propertyMap);
342:
343: if (global) {
344: Map globalCtx = (Map) context.get("globalContext");
345: if (globalCtx != null) {
346: this .mapNameAcsr.put(globalCtx, propertyMap);
347: }
348: }
349: }
350: }
351:
352: public static class PropertyToField extends ModelMenuAction {
353:
354: protected FlexibleStringExpander resourceExdr;
355: protected FlexibleStringExpander propertyExdr;
356: protected FlexibleMapAccessor fieldAcsr;
357: protected FlexibleStringExpander defaultExdr;
358: protected boolean noLocale;
359: protected FlexibleMapAccessor argListAcsr;
360: protected FlexibleStringExpander globalExdr;
361:
362: public PropertyToField(ModelMenu modelMenu, Element setElement) {
363: super (modelMenu, setElement);
364: this .resourceExdr = new FlexibleStringExpander(setElement
365: .getAttribute("resource"));
366: this .propertyExdr = new FlexibleStringExpander(setElement
367: .getAttribute("property"));
368: this .fieldAcsr = new FlexibleMapAccessor(setElement
369: .getAttribute("field"));
370: this .defaultExdr = new FlexibleStringExpander(setElement
371: .getAttribute("default"));
372: noLocale = "true".equals(setElement
373: .getAttribute("no-locale"));
374: this .argListAcsr = new FlexibleMapAccessor(setElement
375: .getAttribute("arg-list-name"));
376: this .globalExdr = new FlexibleStringExpander(setElement
377: .getAttribute("global"));
378: }
379:
380: public void runAction(Map context) {
381: // default to false
382:
383: Locale locale = (Locale) context.get("locale");
384: String resource = this .resourceExdr.expandString(context,
385: locale);
386: String property = this .propertyExdr.expandString(context,
387: locale);
388:
389: String value = null;
390: if (noLocale) {
391: value = UtilProperties.getPropertyValue(resource,
392: property);
393: } else {
394: value = UtilProperties.getMessage(resource, property,
395: locale);
396: }
397: if (value == null || value.length() == 0) {
398: value = this .defaultExdr.expandString(context);
399: }
400:
401: // note that expanding the value string here will handle defaultValue and the string from
402: // the properties file; if we decide later that we don't want the string from the properties
403: // file to be expanded we should just expand the defaultValue at the beginning of this method.
404: value = FlexibleStringExpander.expandString(value, context);
405:
406: if (!argListAcsr.isEmpty()) {
407: List argList = (List) argListAcsr.get(context);
408: if (argList != null && argList.size() > 0) {
409: value = MessageFormat.format(value, argList
410: .toArray());
411: }
412: }
413:
414: fieldAcsr.put(context, value);
415: }
416: }
417:
418: public static class Script extends ModelMenuAction {
419: protected String location;
420:
421: public Script(ModelMenu modelMenu, Element scriptElement) {
422: super (modelMenu, scriptElement);
423: this .location = scriptElement.getAttribute("location");
424: }
425:
426: public void runAction(Map context) {
427: if (location.endsWith(".bsh")) {
428: try {
429: BshUtil.runBshAtLocation(location, context);
430: } catch (GeneralException e) {
431: String errMsg = "Error running BSH script at location ["
432: + location + "]: " + e.toString();
433: Debug.logError(e, errMsg, module);
434: throw new IllegalArgumentException(errMsg);
435: }
436: } else {
437: throw new IllegalArgumentException(
438: "For screen script actions the script type is not yet support for location:"
439: + location);
440: }
441: }
442: }
443:
444: public static class Service extends ModelMenuAction {
445: protected FlexibleStringExpander serviceNameExdr;
446: protected FlexibleMapAccessor resultMapNameAcsr;
447: protected FlexibleStringExpander autoFieldMapExdr;
448: protected Map fieldMap;
449:
450: public Service(ModelMenu modelMenu, Element serviceElement) {
451: super (modelMenu, serviceElement);
452: this .serviceNameExdr = new FlexibleStringExpander(
453: serviceElement.getAttribute("service-name"));
454: this .resultMapNameAcsr = UtilValidate
455: .isNotEmpty(serviceElement
456: .getAttribute("result-map-name")) ? new FlexibleMapAccessor(
457: serviceElement.getAttribute("result-map-name"))
458: : null;
459: this .autoFieldMapExdr = new FlexibleStringExpander(
460: serviceElement.getAttribute("auto-field-map"));
461:
462: List fieldMapElementList = UtilXml.childElementList(
463: serviceElement, "field-map");
464: if (fieldMapElementList.size() > 0) {
465: this .fieldMap = new HashMap();
466: Iterator fieldMapElementIter = fieldMapElementList
467: .iterator();
468: while (fieldMapElementIter.hasNext()) {
469: Element fieldMapElement = (Element) fieldMapElementIter
470: .next();
471: // set the env-name for each field-name, noting that if no field-name is specified it defaults to the env-name
472: this .fieldMap
473: .put(
474: new FlexibleMapAccessor(
475: UtilFormatOut
476: .checkEmpty(
477: fieldMapElement
478: .getAttribute("field-name"),
479: fieldMapElement
480: .getAttribute("env-name"))),
481: new FlexibleMapAccessor(
482: fieldMapElement
483: .getAttribute("env-name")));
484: }
485: }
486: }
487:
488: public void runAction(Map context) {
489: String serviceNameExpanded = this .serviceNameExdr
490: .expandString(context);
491: if (UtilValidate.isEmpty(serviceNameExpanded)) {
492: throw new IllegalArgumentException(
493: "Service name was empty, expanded from: "
494: + this .serviceNameExdr.getOriginal());
495: }
496:
497: String autoFieldMapString = this .autoFieldMapExdr
498: .expandString(context);
499: boolean autoFieldMapBool = !"false"
500: .equals(autoFieldMapString);
501:
502: try {
503: Map serviceContext = null;
504: if (autoFieldMapBool) {
505: serviceContext = this .modelMenu.getDispacher()
506: .getDispatchContext().makeValidContext(
507: serviceNameExpanded,
508: ModelService.IN_PARAM, context);
509: } else {
510: serviceContext = new HashMap();
511: }
512:
513: if (this .fieldMap != null) {
514: Iterator fieldMapEntryIter = this .fieldMap
515: .entrySet().iterator();
516: while (fieldMapEntryIter.hasNext()) {
517: Map.Entry entry = (Map.Entry) fieldMapEntryIter
518: .next();
519: FlexibleMapAccessor serviceContextFieldAcsr = (FlexibleMapAccessor) entry
520: .getKey();
521: FlexibleMapAccessor contextEnvAcsr = (FlexibleMapAccessor) entry
522: .getValue();
523: serviceContextFieldAcsr.put(serviceContext,
524: contextEnvAcsr.get(context));
525: }
526: }
527:
528: Map result = this .modelMenu.getDispacher().runSync(
529: serviceNameExpanded, serviceContext);
530:
531: if (this .resultMapNameAcsr != null) {
532: this .resultMapNameAcsr.put(context, result);
533: } else {
534: context.putAll(result);
535: }
536: } catch (GenericServiceException e) {
537: String errMsg = "Error calling service with name "
538: + serviceNameExpanded + ": " + e.toString();
539: Debug.logError(e, errMsg, module);
540: throw new IllegalArgumentException(errMsg);
541: }
542: }
543: }
544:
545: public static class EntityOne extends ModelMenuAction {
546: protected PrimaryKeyFinder finder;
547:
548: public EntityOne(ModelMenu modelMenu, Element entityOneElement) {
549: super (modelMenu, entityOneElement);
550: finder = new PrimaryKeyFinder(entityOneElement);
551: }
552:
553: public void runAction(Map context) {
554: try {
555: finder.runFind(context, this .modelMenu.getDelegator());
556: } catch (GeneralException e) {
557: String errMsg = "Error doing entity query by condition: "
558: + e.toString();
559: Debug.logError(e, errMsg, module);
560: throw new IllegalArgumentException(errMsg);
561: }
562: }
563: }
564:
565: public static class EntityAnd extends ModelMenuAction {
566: protected ByAndFinder finder;
567:
568: public EntityAnd(ModelMenu modelMenu, Element entityAndElement) {
569: super (modelMenu, entityAndElement);
570: finder = new ByAndFinder(entityAndElement);
571: }
572:
573: public void runAction(Map context) {
574: try {
575: finder.runFind(context, this .modelMenu.getDelegator());
576: } catch (GeneralException e) {
577: String errMsg = "Error doing entity query by condition: "
578: + e.toString();
579: Debug.logError(e, errMsg, module);
580: throw new IllegalArgumentException(errMsg);
581: }
582: }
583: }
584:
585: public static class EntityCondition extends ModelMenuAction {
586: ByConditionFinder finder;
587:
588: public EntityCondition(ModelMenu modelMenu,
589: Element entityConditionElement) {
590: super (modelMenu, entityConditionElement);
591: finder = new ByConditionFinder(entityConditionElement);
592: }
593:
594: public void runAction(Map context) {
595: try {
596: finder.runFind(context, this .modelMenu.getDelegator());
597: } catch (GeneralException e) {
598: String errMsg = "Error doing entity query by condition: "
599: + e.toString();
600: Debug.logError(e, errMsg, module);
601: throw new IllegalArgumentException(errMsg);
602: }
603: }
604: }
605: }
|