001: /*
002: * $Id: BeanShellEngine.java,v 1.1 2003/08/17 05:12:39 ajzeneski Exp $
003: *
004: * Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
005: *
006: * Permission is hereby granted, free of charge, to any person obtaining a
007: * copy of this software and associated documentation files (the "Software"),
008: * to deal in the Software without restriction, including without limitation
009: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
010: * and/or sell copies of the Software, and to permit persons to whom the
011: * Software is furnished to do so, subject to the following conditions:
012: *
013: * The above copyright notice and this permission notice shall be included
014: * in all copies or substantial portions of the Software.
015: *
016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
017: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
018: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
019: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
020: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
021: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
022: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023: *
024: */
025: package org.ofbiz.service.engine;
026:
027: import java.net.URL;
028: import java.util.Map;
029:
030: import org.ofbiz.service.DispatchContext;
031: import org.ofbiz.service.GenericServiceException;
032: import org.ofbiz.service.ModelService;
033: import org.ofbiz.service.ServiceDispatcher;
034: import org.ofbiz.base.util.HttpClient;
035: import org.ofbiz.base.util.HttpClientException;
036: import org.ofbiz.base.util.UtilCache;
037: import org.ofbiz.base.util.UtilURL;
038:
039: import bsh.EvalError;
040: import bsh.Interpreter;
041:
042: /**
043: * BeanShell Script Service Engine
044: *
045: * @author <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
046: * @version $Revision: 1.1 $
047: * @since 2.0
048: */
049: public final class BeanShellEngine extends GenericAsyncEngine {
050:
051: public static UtilCache scriptCache = new UtilCache(
052: "BeanShellScripts", 0, 0);
053:
054: public BeanShellEngine(ServiceDispatcher dispatcher) {
055: super (dispatcher);
056: }
057:
058: /**
059: * @see org.ofbiz.service.engine.GenericEngine#runSyncIgnore(java.lang.String, org.ofbiz.service.ModelService, java.util.Map)
060: */
061: public void runSyncIgnore(String localName,
062: ModelService modelService, Map context)
063: throws GenericServiceException {
064: Map result = runSync(localName, modelService, context);
065: }
066:
067: /**
068: * @see org.ofbiz.service.engine.GenericEngine#runSync(java.lang.String, org.ofbiz.service.ModelService, java.util.Map)
069: */
070: public Map runSync(String localName, ModelService modelService,
071: Map context) throws GenericServiceException {
072: Object result = serviceInvoker(localName, modelService, context);
073:
074: if (result == null || !(result instanceof Map))
075: throw new GenericServiceException(
076: "Service did not return expected result");
077: return (Map) result;
078: }
079:
080: // Invoke the BeanShell Script.
081: private Object serviceInvoker(String localName,
082: ModelService modelService, Map context)
083: throws GenericServiceException {
084: if (modelService.location == null
085: || modelService.invoke == null)
086: throw new GenericServiceException(
087: "Cannot locate service to invoke");
088:
089: // get the DispatchContext from the localName and ServiceDispatcher
090: DispatchContext dctx = dispatcher.getLocalContext(localName);
091:
092: // get the classloader to use
093: ClassLoader cl = null;
094:
095: if (dctx == null)
096: cl = this .getClass().getClassLoader();
097: else
098: cl = dctx.getClassLoader();
099:
100: // source the script into a string
101: String script = (String) scriptCache.get(localName + "_"
102: + modelService.location);
103:
104: if (script == null) {
105: synchronized (this ) {
106: script = (String) scriptCache.get(localName + "_"
107: + modelService.location);
108: if (script == null) {
109: URL scriptUrl = UtilURL.fromResource(
110: modelService.location, cl);
111:
112: if (scriptUrl != null) {
113: try {
114: HttpClient http = new HttpClient(scriptUrl);
115: script = http.get();
116: } catch (HttpClientException e) {
117: throw new GenericServiceException(
118: "Cannot read script from resource",
119: e);
120: }
121: } else {
122: throw new GenericServiceException(
123: "Cannot read script, resource ["
124: + modelService.location
125: + "] not found");
126: }
127: if (script == null || script.length() < 2) {
128: throw new GenericServiceException(
129: "Null or empty script");
130: }
131: scriptCache.put(localName + "_"
132: + modelService.location, script);
133: }
134: }
135: }
136:
137: Interpreter bsh = new Interpreter();
138:
139: Map result = null;
140:
141: try {
142: bsh.set("dctx", dctx); // set the dispatch context
143: bsh.set("context", context); // set the parameter context used for both IN and OUT
144: bsh.eval(script);
145: Object bshResult = bsh.get("result");
146:
147: if ((bshResult != null) && (bshResult instanceof Map))
148: context.putAll((Map) bshResult);
149: result = modelService.makeValid(context,
150: ModelService.OUT_PARAM);
151: } catch (EvalError e) {
152: throw new GenericServiceException(
153: "BeanShell script threw an exception", e);
154: }
155: return result;
156: }
157:
158: }
|