001: /*--
002:
003: Copyright (C) 2002-2005 Adrian Price.
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: 1. Redistributions of source code must retain the above copyright
011: notice, this list of conditions, and the following disclaimer.
012:
013: 2. Redistributions in binary form must reproduce the above copyright
014: notice, this list of conditions, and the disclaimer that follows
015: these conditions in the documentation and/or other materials
016: provided with the distribution.
017:
018: 3. The names "OBE" and "Open Business Engine" must not be used to
019: endorse or promote products derived from this software without prior
020: written permission. For written permission, please contact
021: adrianprice@sourceforge.net.
022:
023: 4. Products derived from this software may not be called "OBE" or
024: "Open Business Engine", nor may "OBE" or "Open Business Engine"
025: appear in their name, without prior written permission from
026: Adrian Price (adrianprice@users.sourceforge.net).
027:
028: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
029: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
030: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
031: DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
032: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
033: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
034: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
035: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
036: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
037: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
038: POSSIBILITY OF SUCH DAMAGE.
039:
040: For more information on OBE, please see
041: <http://obe.sourceforge.net/>.
042:
043: */
044:
045: package org.obe.runtime.tool;
046:
047: import org.apache.commons.logging.Log;
048: import org.apache.commons.logging.LogFactory;
049: import org.obe.OBERuntimeException;
050: import org.obe.client.api.repository.JavaApplicationMetaData;
051: import org.obe.client.api.tool.ToolInvocation;
052:
053: import java.io.File;
054: import java.io.IOException;
055: import java.io.Writer;
056: import java.lang.reflect.InvocationTargetException;
057:
058: /**
059: * A tool agent that invokes the main() method of a Java class.
060: *
061: * @author Adrian Price
062: */
063: public final class JavaApplication extends JavaMethod {
064: private static final long serialVersionUID = -4275190002750466569L;
065: private static final Log _logger = LogFactory
066: .getLog(JavaApplication.class);
067: private static final String JAVA_EXECUTABLE;
068:
069: private final JavaApplicationMetaData _metadata;
070:
071: static {
072: File javaHome = new File(System.getProperty("java.home"));
073: File java = new File(new File(javaHome, "bin"), "java");
074: try {
075: JAVA_EXECUTABLE = java.getCanonicalPath();
076: } catch (IOException e) {
077: throw new OBERuntimeException(e);
078: }
079: }
080:
081: public JavaApplication(JavaApplicationMetaData metadata)
082: throws NoSuchMethodException, ClassNotFoundException {
083:
084: super (metadata);
085: _metadata = metadata;
086: }
087:
088: // TODO: consider re-writing this method as a JNLP client.
089: protected int _invokeApplication(ToolInvocation ti)
090: throws InterruptedException, InvocationTargetException {
091:
092: // Check whether the tool definition or workflow specifies a fork.
093: boolean fork = _metadata.isFork();
094:
095: // If forking, spawn a new JVM and launch the specified class.
096: if (fork) {
097: // Build the argument array for the java executable.
098: String[] args = new String[ti.parameters.length + 3];
099: args[0] = JAVA_EXECUTABLE;
100: args[1] = "-cp";
101: args[2] = System.getProperty("java.class.path");
102: for (int i = 3; i < ti.parameters.length; i++) {
103: Object value = ti.parameters[i].getValue();
104: if (value != null)
105: args[i] = value.toString();
106: }
107:
108: if (_logger.isDebugEnabled()) {
109: StringBuffer sb = new StringBuffer();
110: sb.append("Command:");
111: for (int i = 0; i < args.length; i++)
112: sb.append(' ').append(args[i]);
113: _logger.debug(sb.toString());
114: }
115:
116: // Spawn the new JVM and wait for it to exit.
117: try {
118: _status = ACTIVE;
119: Process process = Runtime.getRuntime().exec(args);
120: process.waitFor();
121: return process.exitValue();
122: } catch (IOException e) {
123: throw new InvocationTargetException(e);
124: }
125: } else {
126: // Otherwise, invoke the main() method in-process.
127: return super ._invokeApplication(ti);
128: }
129: }
130:
131: public void renderInvocationScript(ToolInvocation ti, Writer writer)
132: throws IOException {
133:
134: String href = _metadata.getHref();
135: if (href == null) {
136: throw new UnsupportedOperationException(
137: "The JavaApplication tool agent requires a JNLP href to "
138: + "support invocation from a browser");
139: }
140: if (href.lastIndexOf(".jnlp") == -1)
141: throw new IllegalArgumentException(
142: "JNLP href must end with '.jnlp'");
143:
144: writer.write("window.location=\"");
145: writer.write(href);
146: writer.write("?_title=");
147: writer.write(ti.workItemName);
148: writer.write("&_procInstId=");
149: writer.write(ti.procInstId);
150: writer.write("&_workItemId=");
151: writer.write(ti.workItemId);
152: writer.write("&_toolId=");
153: writer.write(ti.toolId);
154: int n = ti.parameters.length;
155: if (n > 0) {
156: for (int i = 0; i < n; i++) {
157: writer.write("&");
158: writer.write(ti.parameters[i].getFormalParm().getId());
159: Object value = ti.parameters[i].getValue();
160: if (value != null) {
161: writer.write("=");
162: writer.write(value.toString());
163: }
164: }
165: }
166: writer.write("\";");
167: }
168: }
|