/**
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2005 Danet GmbH (www.danet.de), BU BTS.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: JSExecutor2.java 2284 2007-02-27 14:34:23Z drmlipp $
*
* $Log$
* Revision 1.5 2006/11/19 21:53:47 mlipp
* Finished support for native Java types.
*
* Revision 1.4 2006/09/29 12:32:13 drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.3 2006/07/18 13:18:14 drmlipp
* Merged changes from wfmopen-1.3.x branch up to 1.3.4.
*
* Revision 1.1.2.7 2006/03/15 10:46:07 drmlipp
* Fixed problems with E4X and empty input/output documents.
*
* Revision 1.1.2.6 2006/03/14 16:45:01 drmlipp
* Fixed loop.
*
* Revision 1.2 2006/03/08 14:46:44 drmlipp
* Synchronized with 1.3.3p5.
*
* Revision 1.1.2.5 2006/02/08 19:29:46 drmlipp
* Added E4X support.
*
* Revision 1.1.2.4 2005/12/20 22:05:31 drmlipp
* Removed deprecated exceptions and completed argument convertion.
*
* Revision 1.1.2.3 2005/12/19 22:52:16 drmlipp
* Continuing.
*
* Revision 1.1.2.2 2005/12/19 16:17:17 drmlipp
* Analysed XML problem.
*
* Revision 1.1.2.1 2005/12/15 22:55:54 drmlipp
* Continued XML support for JS tool.
*
*/
package de.danet.an.workflow.tools.rhino;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlSaxHandler;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.xml.sax.SAXException;
import de.danet.an.workflow.api.ExternalReference;
import de.danet.an.workflow.api.FormalParameter;
import de.danet.an.workflow.api.SAXEventBuffer;
import de.danet.an.workflow.spis.aii.XMLArgumentTypeProvider;
import de.danet.an.workflow.util.XPDLUtil;
/**
* A variant of the <code>JSExecutor</code> that provides all
* <code>SchemaType</code> arguments as JavaScript E4X XML objects.
*
* @author lipp
*/
public class JSExecutor2 extends JSExecutor
implements XMLArgumentTypeProvider {
private static final org.apache.commons.logging.Log logger
= org.apache.commons.logging.LogFactory.getLog(JSExecutor2.class);
/**
*
* @see JSExecutor#prepareArguments
*/
protected void prepareArguments
(Context cx, Scriptable scope, FormalParameter[] formPars, Map map) {
for (int i = 0; i < formPars.length; i++) {
String fp = formPars[i].id();
((ScriptableObject)scope).defineProperty
(fp,
formPars[i].mode() == FormalParameter.Mode.OUT
? null
: convertArgument(cx, scope, formPars[i].type(), map.get(fp)),
ScriptableObject.PERMANENT
| (formPars[i].mode() == FormalParameter.Mode.IN
? ScriptableObject.READONLY : 0));
}
}
/**
* Additionally convert SchemaType arguments
* @see JSExecutor#convertArgument
*/
protected Object convertArgument
(Context cx, Scriptable scope, Object argType, Object argument) {
if (argType instanceof ExternalReference) {
if (XPDLUtil.isJavaType((ExternalReference)argType)) {
return Context.javaToJS(argument, scope);
}
}
if (argument instanceof Date) {
return cx.newObject
(scope, "Date", new Object[]
{ new Long(((Date)argument).getTime()) });
}
if (argument instanceof SAXEventBuffer) {
try {
XmlSaxHandler sh = XmlObject.Factory.newXmlSaxHandler();
((SAXEventBuffer)argument).emit(sh.getContentHandler());
XmlObject xo = sh.getObject();
XmlCursor cur = xo.newCursor();
while (!cur.isStart()) {
if (cur.isEnddoc()) {
return cx.evaluateString
(scope, "<></>", "<script>", 1, null);
}
cur.toNextToken();
}
xo = cur.getObject();
Object wxo = Context.javaToJS (xo, scope);
return cx.newObject (scope, "XML", new Object[] { wxo });
} catch (SAXException e) {
throw (IllegalStateException)
(new IllegalStateException (e.getMessage()).initCause(e));
} catch (XmlException e) {
throw (IllegalStateException)
(new IllegalStateException (e.getMessage()).initCause(e));
}
}
return argument;
}
/**
* Convert the result.
* @param cx the context.
* @param scope the scope.
* @param formPars the formal parameter definitons.
* @return
* @throws JavaScriptException
* @throws SAXException
*/
protected Map convertResult
(Context cx, Scriptable scope, FormalParameter[] fps)
throws JavaScriptException, SAXException {
Map resData = new HashMap ();
for (int i = 0; i < fps.length; i++) {
if (fps[i].mode() == FormalParameter.Mode.IN) {
continue;
}
String fpn = fps[i].id();
Object v = ScriptableObject.getProperty (scope, fps[i].id());
v = convertResultValue(cx, scope, fps[i], v);
resData.put (fpn, v);
}
return resData;
}
/**
* Request arguments as SAX.
* @return the requested type.
* @see XMLArgumentTypeProvider#requestedXMLArgumentType()
*/
public int requestedXMLArgumentType() {
return XMLArgumentTypeProvider.XML_AS_SAX;
}
}