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.minilang.method.callops;
019:
020: import java.lang.reflect.*;
021: import java.util.*;
022:
023: import org.w3c.dom.*;
024: import org.ofbiz.base.util.*;
025:
026: import org.ofbiz.minilang.*;
027: import org.ofbiz.minilang.method.*;
028:
029: /**
030: * Calls a Java object method using the given fields as parameters
031: */
032: public class CallObjectMethod extends MethodOperation {
033:
034: public static final String module = CallClassMethod.class.getName();
035:
036: ContextAccessor objFieldAcsr;
037: ContextAccessor objMapAcsr;
038: String methodName;
039: ContextAccessor retFieldAcsr;
040: ContextAccessor retMapAcsr;
041:
042: /** A list of MethodObject objects to use as the method call parameters */
043: List parameters;
044:
045: public CallObjectMethod(Element element, SimpleMethod simpleMethod) {
046: super (element, simpleMethod);
047: objFieldAcsr = new ContextAccessor(element
048: .getAttribute("obj-field-name"));
049: objMapAcsr = new ContextAccessor(element
050: .getAttribute("obj-map-name"));
051: methodName = element.getAttribute("method-name");
052: retFieldAcsr = new ContextAccessor(element
053: .getAttribute("ret-field-name"));
054: retMapAcsr = new ContextAccessor(element
055: .getAttribute("ret-map-name"));
056:
057: List parameterElements = UtilXml.childElementList(element);
058: if (parameterElements.size() > 0) {
059: parameters = new ArrayList(parameterElements.size());
060:
061: Iterator parameterIter = parameterElements.iterator();
062: while (parameterIter.hasNext()) {
063: Element parameterElement = (Element) parameterIter
064: .next();
065: MethodObject methodObject = null;
066: if ("string".equals(parameterElement.getNodeName())) {
067: methodObject = new StringObject(parameterElement,
068: simpleMethod);
069: } else if ("field".equals(parameterElement
070: .getNodeName())) {
071: methodObject = new FieldObject(parameterElement,
072: simpleMethod);
073: } else {
074: //whoops, invalid tag here, print warning
075: Debug.logWarning(
076: "Found an unsupported tag under the call-object-method tag: "
077: + parameterElement.getNodeName()
078: + "; ignoring", module);
079: }
080: if (methodObject != null) {
081: parameters.add(methodObject);
082: }
083: }
084: }
085: }
086:
087: public boolean exec(MethodContext methodContext) {
088: String methodName = methodContext.expandString(this .methodName);
089:
090: Object methodObject = null;
091: if (!objMapAcsr.isEmpty()) {
092: Map fromMap = (Map) objMapAcsr.get(methodContext);
093: if (fromMap == null) {
094: Debug
095: .logWarning(
096: "Map not found with name "
097: + objMapAcsr
098: + ", which should contain the object to execute a method on; not executing method, rerturning error.",
099: module);
100:
101: String errMsg = "ERROR: Could not complete the "
102: + simpleMethod.getShortDescription()
103: + " process [Map not found with name "
104: + objMapAcsr
105: + ", which should contain the object to execute a method on]";
106: methodContext.setErrorReturn(errMsg, simpleMethod);
107: return false;
108: }
109: methodObject = objFieldAcsr.get(fromMap, methodContext);
110: } else {
111: // no map name, try the env
112: methodObject = objFieldAcsr.get(methodContext);
113: }
114:
115: if (methodObject == null) {
116: if (Debug.infoOn())
117: Debug
118: .logInfo(
119: "Object not found to execute method on with name "
120: + objFieldAcsr
121: + " in Map with name "
122: + objMapAcsr
123: + ", not executing method, rerturning error.",
124: module);
125:
126: String errMsg = "ERROR: Could not complete the "
127: + simpleMethod.getShortDescription()
128: + " process [Object not found to execute method on with name "
129: + objFieldAcsr + " in Map with name " + objMapAcsr
130: + "]";
131: methodContext.setErrorReturn(errMsg, simpleMethod);
132: return false;
133: }
134:
135: Class methodClass = methodObject.getClass();
136: return CallObjectMethod.callMethod(simpleMethod, methodContext,
137: parameters, methodClass, methodObject, methodName,
138: retFieldAcsr, retMapAcsr);
139: }
140:
141: public static boolean callMethod(SimpleMethod simpleMethod,
142: MethodContext methodContext, List parameters,
143: Class methodClass, Object methodObject, String methodName,
144: ContextAccessor retFieldAcsr, ContextAccessor retMapAcsr) {
145: Object[] args = null;
146: Class[] parameterTypes = null;
147:
148: if (parameters != null) {
149: args = new Object[parameters.size()];
150: parameterTypes = new Class[parameters.size()];
151:
152: Iterator parameterIter = parameters.iterator();
153: int i = 0;
154: while (parameterIter.hasNext()) {
155: MethodObject methodObjectDef = (MethodObject) parameterIter
156: .next();
157: args[i] = methodObjectDef.getObject(methodContext);
158:
159: Class typeClass = methodObjectDef
160: .getTypeClass(methodContext.getLoader());
161: if (typeClass == null) {
162: String errMsg = "ERROR: Could not complete the "
163: + simpleMethod.getShortDescription()
164: + " process [Parameter type not found with name "
165: + methodObjectDef.getTypeName() + "]";
166: Debug.logError(errMsg, module);
167: methodContext.setErrorReturn(errMsg, simpleMethod);
168: return false;
169: }
170:
171: parameterTypes[i] = typeClass;
172: i++;
173: }
174: }
175:
176: try {
177: Method method = methodClass.getMethod(methodName,
178: parameterTypes);
179: try {
180: Object retValue = method.invoke(methodObject, args);
181:
182: //if retFieldAcsr is empty, ignore return value
183: if (!retFieldAcsr.isEmpty()) {
184: if (!retMapAcsr.isEmpty()) {
185: Map retMap = (Map) retMapAcsr
186: .get(methodContext);
187:
188: if (retMap == null) {
189: retMap = new HashMap();
190: retMapAcsr.put(methodContext, retMap);
191: }
192: retFieldAcsr.put(retMap, retValue,
193: methodContext);
194: } else {
195: // no map name, use the env
196: retFieldAcsr.put(methodContext, retValue);
197: }
198: }
199: } catch (IllegalAccessException e) {
200: Debug
201: .logError(
202: e,
203: "Could not access method in call method operation",
204: module);
205: String errMsg = "ERROR: Could not complete the "
206: + simpleMethod.getShortDescription()
207: + " process [Could not access method to execute named "
208: + methodName + ": " + e.toString() + "]";
209: methodContext.setErrorReturn(errMsg, simpleMethod);
210: return false;
211: } catch (IllegalArgumentException e) {
212: Debug
213: .logError(
214: e,
215: "Illegal argument calling method in call method operation",
216: module);
217: String errMsg = "ERROR: Could not complete the "
218: + simpleMethod.getShortDescription()
219: + " process [Illegal argument calling method to execute named "
220: + methodName + ": " + e.toString() + "]";
221: methodContext.setErrorReturn(errMsg, simpleMethod);
222: return false;
223: } catch (InvocationTargetException e) {
224: Debug
225: .logError(
226: e.getTargetException(),
227: "Method in call method operation threw an exception",
228: module);
229: String errMsg = "ERROR: Could not complete the "
230: + simpleMethod.getShortDescription()
231: + " process [Method to execute named "
232: + methodName + " threw an exception: "
233: + e.getTargetException() + "]";
234: methodContext.setErrorReturn(errMsg, simpleMethod);
235: return false;
236: }
237: } catch (NoSuchMethodException e) {
238: Debug
239: .logError(
240: e,
241: "Could not find method to execute in simple-method call method operation",
242: module);
243: String errMsg = "ERROR: Could not complete the "
244: + simpleMethod.getShortDescription()
245: + " process [Could not find method to execute named "
246: + methodName + ": " + e.toString() + "]";
247: methodContext.setErrorReturn(errMsg, simpleMethod);
248: return false;
249: } catch (SecurityException e) {
250: Debug
251: .logError(
252: e,
253: "Security exception finding method to execute in simple-method call method operation",
254: module);
255: String errMsg = "ERROR: Could not complete the "
256: + simpleMethod.getShortDescription()
257: + " process [Security exception finding method to execute named "
258: + methodName + ": " + e.toString() + "]";
259: methodContext.setErrorReturn(errMsg, simpleMethod);
260: return false;
261: }
262:
263: return true;
264: }
265:
266: public String rawString() {
267: // TODO: something more than the empty tag
268: return "<call-object-method/>";
269: }
270:
271: public String expandedString(MethodContext methodContext) {
272: // TODO: something more than a stub/dummy
273: return this.rawString();
274: }
275: }
|