001: /**
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2005 Danet GmbH (www.danet.de), BU BTS.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * $Id: JSExecutor2.java,v 1.6 2007/02/27 14:34:22 drmlipp Exp $
021: *
022: * $Log: JSExecutor2.java,v $
023: * Revision 1.6 2007/02/27 14:34:22 drmlipp
024: * Some refactoring to reduce cyclic dependencies.
025: *
026: * Revision 1.5 2006/11/19 21:53:47 mlipp
027: * Finished support for native Java types.
028: *
029: * Revision 1.4 2006/09/29 12:32:13 drmlipp
030: * Consistently using WfMOpen as projct name now.
031: *
032: * Revision 1.3 2006/07/18 13:18:14 drmlipp
033: * Merged changes from wfmopen-1.3.x branch up to 1.3.4.
034: *
035: * Revision 1.1.2.7 2006/03/15 10:46:07 drmlipp
036: * Fixed problems with E4X and empty input/output documents.
037: *
038: * Revision 1.1.2.6 2006/03/14 16:45:01 drmlipp
039: * Fixed loop.
040: *
041: * Revision 1.2 2006/03/08 14:46:44 drmlipp
042: * Synchronized with 1.3.3p5.
043: *
044: * Revision 1.1.2.5 2006/02/08 19:29:46 drmlipp
045: * Added E4X support.
046: *
047: * Revision 1.1.2.4 2005/12/20 22:05:31 drmlipp
048: * Removed deprecated exceptions and completed argument convertion.
049: *
050: * Revision 1.1.2.3 2005/12/19 22:52:16 drmlipp
051: * Continuing.
052: *
053: * Revision 1.1.2.2 2005/12/19 16:17:17 drmlipp
054: * Analysed XML problem.
055: *
056: * Revision 1.1.2.1 2005/12/15 22:55:54 drmlipp
057: * Continued XML support for JS tool.
058: *
059: */package de.danet.an.workflow.tools.rhino;
060:
061: import java.util.Date;
062: import java.util.HashMap;
063: import java.util.Map;
064:
065: import org.apache.xmlbeans.XmlCursor;
066: import org.apache.xmlbeans.XmlException;
067: import org.apache.xmlbeans.XmlObject;
068: import org.apache.xmlbeans.XmlSaxHandler;
069: import org.mozilla.javascript.Context;
070: import org.mozilla.javascript.JavaScriptException;
071: import org.mozilla.javascript.Scriptable;
072: import org.mozilla.javascript.ScriptableObject;
073: import org.xml.sax.SAXException;
074:
075: import de.danet.an.workflow.api.ExternalReference;
076: import de.danet.an.workflow.api.FormalParameter;
077: import de.danet.an.workflow.api.SAXEventBuffer;
078: import de.danet.an.workflow.spis.aii.XMLArgumentTypeProvider;
079: import de.danet.an.workflow.util.XPDLUtil;
080:
081: /**
082: * A variant of the <code>JSExecutor</code> that provides all
083: * <code>SchemaType</code> arguments as JavaScript E4X XML objects.
084: *
085: * @author lipp
086: */
087: public class JSExecutor2 extends JSExecutor implements
088: XMLArgumentTypeProvider {
089:
090: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
091: .getLog(JSExecutor2.class);
092:
093: /**
094: *
095: * @see JSExecutor#prepareArguments
096: */
097: protected void prepareArguments(Context cx, Scriptable scope,
098: FormalParameter[] formPars, Map map) {
099: for (int i = 0; i < formPars.length; i++) {
100: String fp = formPars[i].id();
101: ((ScriptableObject) scope)
102: .defineProperty(
103: fp,
104: formPars[i].mode() == FormalParameter.Mode.OUT ? null
105: : convertArgument(cx, scope,
106: formPars[i].type(), map
107: .get(fp)),
108: ScriptableObject.PERMANENT
109: | (formPars[i].mode() == FormalParameter.Mode.IN ? ScriptableObject.READONLY
110: : 0));
111: }
112: }
113:
114: /**
115: * Additionally convert SchemaType arguments
116: * @see JSExecutor#convertArgument
117: */
118: protected Object convertArgument(Context cx, Scriptable scope,
119: Object argType, Object argument) {
120: if (argType instanceof ExternalReference) {
121: if (XPDLUtil.isJavaType((ExternalReference) argType)) {
122: return Context.javaToJS(argument, scope);
123: }
124: }
125: if (argument instanceof Date) {
126: return cx.newObject(scope, "Date", new Object[] { new Long(
127: ((Date) argument).getTime()) });
128: }
129: if (argument instanceof SAXEventBuffer) {
130: try {
131: XmlSaxHandler sh = XmlObject.Factory.newXmlSaxHandler();
132: ((SAXEventBuffer) argument)
133: .emit(sh.getContentHandler());
134: XmlObject xo = sh.getObject();
135: XmlCursor cur = xo.newCursor();
136: while (!cur.isStart()) {
137: if (cur.isEnddoc()) {
138: return cx.evaluateString(scope, "<></>",
139: "<script>", 1, null);
140: }
141: cur.toNextToken();
142: }
143: xo = cur.getObject();
144: Object wxo = Context.javaToJS(xo, scope);
145: return cx.newObject(scope, "XML", new Object[] { wxo });
146: } catch (SAXException e) {
147: throw (IllegalStateException) (new IllegalStateException(
148: e.getMessage()).initCause(e));
149: } catch (XmlException e) {
150: throw (IllegalStateException) (new IllegalStateException(
151: e.getMessage()).initCause(e));
152: }
153: }
154: return argument;
155: }
156:
157: /**
158: * Convert the result.
159: * @param cx the context.
160: * @param scope the scope.
161: * @param formPars the formal parameter definitons.
162: * @return
163: * @throws JavaScriptException
164: * @throws SAXException
165: */
166: protected Map convertResult(Context cx, Scriptable scope,
167: FormalParameter[] fps) throws JavaScriptException,
168: SAXException {
169: Map resData = new HashMap();
170: for (int i = 0; i < fps.length; i++) {
171: if (fps[i].mode() == FormalParameter.Mode.IN) {
172: continue;
173: }
174: String fpn = fps[i].id();
175: Object v = ScriptableObject.getProperty(scope, fps[i].id());
176: v = convertResultValue(cx, scope, fps[i], v);
177: resData.put(fpn, v);
178: }
179: return resData;
180: }
181:
182: /**
183: * Request arguments as SAX.
184: * @return the requested type.
185: * @see XMLArgumentTypeProvider#requestedXMLArgumentType()
186: */
187: public int requestedXMLArgumentType() {
188: return XMLArgumentTypeProvider.XML_AS_SAX;
189: }
190:
191: }
|