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.test;
046:
047: import org.apache.commons.logging.Log;
048: import org.apache.commons.logging.LogFactory;
049: import org.obe.client.api.WMClient;
050: import org.obe.client.api.repository.ObjectAlreadyExistsException;
051: import org.obe.engine.WorkflowEngine;
052: import org.obe.spi.service.ProcessRepository;
053: import org.obe.spi.service.ServiceManager;
054: import org.obe.xpdl.model.pkg.XPDLPackage;
055: import org.obe.xpdl.parser.XPDLParser;
056: import org.obe.xpdl.parser.dom4j.Dom4JXPDLParser;
057: import org.obe.xpdl.serializer.XPDLSerializer;
058: import org.obe.xpdl.serializer.dom4j.Dom4JXPDLSerializer;
059:
060: import java.io.*;
061: import java.util.*;
062:
063: /**
064: * OBETest is a command-line application that can be used to execute OBE
065: * Workflows.
066: * <p>To use the OBETest application, change to the directory with the
067: * obetest.jar and type:
068: * <p/>
069: * <code>java -jar obetest.jar</code>
070: * <p>This command will execute the OBETest application using the file
071: * tests/config/processes/test.xpdl in the current working directory as the XPDL
072: * document to test. You can also specify the -h flag with the command to
073: * find out about the other command line switches which are available.
074: * <p/>
075: * <em>WARNING!!! This code is not intended as an example of client code.<br/>
076: * In particular, please note that you should <b>never</b> call WorkflowEngine
077: * directly as this program does. <b>Always</b> use {@link WMClient} instead.
078: * </em>
079: *
080: * @author Anthony Eden
081: * @author Adrian Price
082: */
083: public class OBETest {
084: private static final File DEFAULT_FILE = new File(
085: "tests/config/processes/test.xpdl");
086: private static final File DEFAULT_PROP_FILE = new File(
087: "tests/config/resources/test.properties");
088: private static final Log log = LogFactory.getLog(OBETest.class);
089:
090: /**
091: * Main entry point for the OBETest application. Invoke as
092: * <code>java -Dobe.config.dir=$OBE_DEV_HOME/obe/obeengine org.obetest.OBETest</code>
093: * to pick up the standard repository configurations for the standalone
094: * engine.
095: *
096: * @param args Command line arguments
097: */
098: public static void main(String[] args) {
099: try {
100: // Since commons-logging provides no means to configure the loggers,
101: // we must configure the underlying logger implementation directly.
102: // org.apache.log4j.BasicConfigurator.resetConfiguration();
103: // org.apache.log4j.BasicConfigurator.configure();
104: // org.apache.log4j.Logger obeRootLogger = org.apache.log4j.Logger.getLogger("org.obe");
105: // obeRootLogger.setLevel(org.apache.log4j.Level.DEBUG);
106: // org.apache.log4j.Layout layout = new org.apache.log4j.PatternLayout("%-4r %-5p [%t] [%c{1}] %x - %m%n");
107: // Enumeration appenders = org.apache.log4j.Logger.getRootLogger().getAllAppenders();
108: // while (appenders.hasMoreElements()) {
109: // ((org.apache.log4j.Appender)appenders.nextElement()).setLayout(layout);
110: // }
111:
112: // Load the services & repositories.
113: ServiceManager svcMgr = new ServiceManager();
114:
115: File xpdlFile = DEFAULT_FILE;
116: File propFile = DEFAULT_PROP_FILE;
117: File outfile = null;
118: boolean outfileOnly = false;
119: boolean serialize = false;
120: List ids = new ArrayList();
121:
122: int i = 0;
123: while (i < args.length) {
124: if (args[i].equals("-f")) {
125: xpdlFile = new File(args[++i]);
126: } else if (args[i].equals("-h")) {
127: usage();
128: return;
129: } else if (args[i].equals("-o")) {
130: outfile = new File(args[++i]);
131: } else if (args[i].equals("-O")) {
132: outfile = new File(args[++i]);
133: outfileOnly = true;
134: } else if (args[i].equals("-p")) {
135: propFile = new File(args[++i]);
136: } else if (args[i].equals("-r")) {
137: svcMgr = (ServiceManager) Class.forName(args[++i])
138: .newInstance();
139: } else if (args[i].equals("-s")) {
140: serialize = true;
141: } else {
142: ids.add(args[i]);
143: }
144: i++;
145: }
146:
147: if (ids.size() == 0) {
148: ids.add("test1:wfp-5");
149: }
150:
151: // instantiate the workflow engine instance
152: log.info("Instantiating workflow engine");
153: WorkflowEngine engine = new WorkflowEngine(svcMgr);
154:
155: // create an XPDL parser
156: XPDLParser parser = new Dom4JXPDLParser();
157:
158: // open the stream to the XPDL data
159: log.info("Opening stream for " + xpdlFile);
160: FileInputStream in = new FileInputStream(xpdlFile);
161:
162: // parse the XPDL into a XPDLPackage object
163: log.info("Parsing " + xpdlFile);
164: XPDLPackage pkg = null;
165: try {
166: pkg = parser.parse(in);
167: } catch (Exception e) {
168: log.fatal("Error parsing configuration: "
169: + e.getMessage());
170: e.printStackTrace();
171: System.exit(1);
172: }
173:
174: // If a Java Object Serialization test is required, serialize then
175: // deserialize the package.
176: if (serialize) {
177: try {
178: ByteArrayOutputStream bos = new ByteArrayOutputStream();
179: ObjectOutputStream oos = new ObjectOutputStream(bos);
180: oos.writeObject(pkg);
181: oos.close();
182: byte[] buf = bos.toByteArray();
183:
184: ByteArrayInputStream bis = new ByteArrayInputStream(
185: buf);
186: ObjectInputStream ois = new ObjectInputStream(bis);
187: pkg = (XPDLPackage) ois.readObject();
188: ois.close();
189: } catch (Exception e) {
190: log.fatal("Error in Java Object Serialization: "
191: + e.getMessage());
192: e.printStackTrace();
193: System.exit(1);
194: }
195: }
196:
197: FileOutputStream out = null;
198: if (outfile != null) {
199: try {
200: out = new FileOutputStream(outfile);
201: // serialize the XPDL back to test the Serializer
202: log.info("Serializing " + outfile);
203: XPDLSerializer serializer = new Dom4JXPDLSerializer();
204: serializer.serialize(pkg, out);
205: } catch (Exception e) {
206: log.error("Error serializing XPDL: "
207: + e.getMessage());
208: e.printStackTrace();
209: System.exit(1);
210: } finally {
211: if (out != null) {
212: try {
213: out.close();
214: } catch (Exception ex) {
215: // Ignore exceptions on close.
216: }
217: }
218: }
219: }
220:
221: if (outfileOnly) {
222: return;
223: }
224:
225: Properties parms = new Properties();
226: if (propFile != null) {
227: in = new FileInputStream(propFile);
228: parms.load(in);
229: in.close();
230: }
231:
232: log.info("Adding package to the engine");
233: // add the package to the engine
234: ProcessRepository processRepository = svcMgr
235: .getProcessRepository();
236: try {
237: processRepository.createPackage(pkg);
238: } catch (ObjectAlreadyExistsException e) {
239: // Ignore this exception, just use the existing package.
240: }
241:
242: log.info("Executing package");
243: Iterator iter = ids.iterator();
244: while (iter.hasNext()) {
245: String id = (String) iter.next();
246:
247: String packageId = id.substring(0, id.indexOf(":"));
248: String processId = id.substring(id.indexOf(":") + 1);
249:
250: try {
251: log.info("Executing workflow process " + packageId
252: + ":" + processId);
253:
254: // Create the process instance.
255: String processInstanceId = engine
256: .createProcessInstance(
257: processId,
258: "OBETest-"
259: + System
260: .currentTimeMillis());
261:
262: // Set process parameters.
263: for (Iterator iter2 = parms.entrySet().iterator(); iter2
264: .hasNext();) {
265:
266: Map.Entry entry = (Map.Entry) iter2.next();
267: engine.assignProcessInstanceAttribute(
268: processInstanceId, (String) entry
269: .getKey(), entry.getValue());
270: }
271:
272: // Start the process.
273: engine.startProcess(processInstanceId);
274: } catch (Exception e) {
275: log.error("Error executing workflow process "
276: + processId + " in package " + packageId);
277: e.printStackTrace();
278: }
279: }
280:
281: System.out.println("Press the Enter key to finish");
282: try {
283: System.in.read();
284: } catch (IOException e) {
285: // We don't care about exceptions.
286: }
287: } catch (Throwable t) {
288: log.fatal("Error executing test: " + t.getMessage());
289: t.printStackTrace();
290: System.exit(1);
291: }
292: System.exit(0);
293: }
294:
295: /**
296: * Display a usage or "help" message.
297: */
298: public static void usage() {
299: System.out.println();
300: System.out
301: .println("java -jar obetest.jar [-f filename] [-p propfile] [-r classname ] [-h] [pkgid:wfid]");
302: System.out.println();
303: System.out
304: .println(" Execute a specific XPDL file in the Open Business Engine.");
305: System.out
306: .println(" If no file is specified then test.xml is used by default.");
307: System.out
308: .println(" Any arguments without a switch are package:process identifiers.");
309: System.out
310: .println(" If no identifiers are specified then the default pkg-1:wp-1 is");
311: System.out.println(" used.");
312: System.out.println();
313: System.out
314: .println(" -f filename Use the specified XPDL file (default = test.xml)");
315: System.out.println(" -h Display this message");
316: System.out
317: .println(" -o outfile Serialize the package to outfile");
318: System.out
319: .println(" -O outfile Serialize the package to outfile and exit");
320: System.out
321: .println(" -p propfile Set workflow input parameters from property file");
322: System.out
323: .println(" -r classname The class to use as the Repository Manager");
324: System.out
325: .println(" -s Serialize/Deserialize using Java Object Serialization");
326: System.out
327: .println(" (Only in conjunction with -o or -O)");
328: }
329:
330: protected static void printReturnValues(List returnValues) {
331: Iterator iter = returnValues.iterator();
332: System.out.println("Return values: ");
333: while (iter.hasNext()) {
334: System.out.println(" " + iter.next().toString());
335: }
336: }
337: }
|