1 /* 2 * Copyright 1999-2001,2004 The Apache Software Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.commons.workflow.demo; 18 19 20 import java.io.File; 21 import org.apache.commons.digester.Digester; 22 import org.apache.commons.workflow.Activity; 23 import org.apache.commons.workflow.Context; 24 import org.apache.commons.workflow.ContextEvent; 25 import org.apache.commons.workflow.ContextListener; 26 import org.apache.commons.workflow.base.BaseContext; 27 import org.apache.commons.workflow.base.BaseRuleSet; 28 import org.apache.commons.workflow.core.CoreRuleSet; 29 import org.apache.commons.workflow.io.IoRuleSet; 30 import org.apache.commons.workflow.web.WebRuleSet; 31 32 33 /** 34 * <p>Demonstration program to illustrate how the Workflow Management System 35 * is utilized. It accepts a command line argument to an XML file that 36 * contains an <code><activity></code> to be parsed and then executed. 37 * If no file is specified, a default XML document will be utilized.</p> 38 * 39 * <p><strong>WARNING</strong> - This program is for illustration only while 40 * the workflow management system is being developed, and it will not be 41 * part of the final package. Indeed, much of its functionality (such as 42 * the parsing of XML files describing activities) will need to be encapsulated 43 * inside the system, in ways that support the per-namespace step definitions 44 * as outlined in the original proposal.</p> 45 * 46 * <p><strong>WARNING</strong> - This code depends on the version of Digester 47 * currently in SVN - the 1.0 released version will not work correctly with 48 * namespace prefixes.</p> 49 * 50 * <p><strong>WARNING</strong> - The namespace URLs in the example XML document 51 * are not official - they are simply used to satisfy the syntax requirements 52 * of the XML parser. Official namespace URIs <em>will</em> be required for a 53 * formal release of this technology, because that is key to the extensibility 54 * of Step implementations.</p> 55 * 56 * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $ 57 * @author Craig R. McClanahan 58 */ 59 60 public class Main implements ContextListener { 61 62 63 // ----------------------------------------------------------- Main Program 64 65 66 /** 67 * The main program for the demo. 68 * 69 * @param args Command line arguments 70 */ 71 public static void main(String args[]) { 72 73 // Make sure there is a filename argument 74 if (args.length != 1) { 75 System.out.println("Usage: java org.apache.commons.workflow.demo.Main {XML-file}"); 76 System.exit(1); 77 } 78 79 // Construct and utilize a new instance of this class 80 Main main = new Main(); 81 main.process(args[0]); 82 83 } 84 85 86 // ----------------------------------------------------- Instance Variables 87 88 89 /** 90 * The Activity constructed by our Digester. 91 */ 92 protected Activity activity = null; 93 94 95 /** 96 * The Digester used to process input files. 97 */ 98 protected Digester digester = null; 99 100 101 // ------------------------------------------------------------ Constructor 102 103 104 /** 105 * Construct a new instance of this class to process input files. 106 */ 107 public Main() { 108 109 super(); 110 digester = createDigester(); 111 112 } 113 114 115 // -------------------------------------------------------- Support Methods 116 117 118 /** 119 * <p>Create a Digester instance that knows how to parse activities using 120 * the <code>core</code> and <code>io</code> built-in Steps.</p> 121 * 122 * <p><strong>WARNING</strong> - This will ultimately be abstracted into 123 * a mechanism to register the set of rule definitions associated with 124 * a namespace.</p> 125 */ 126 protected Digester createDigester() { 127 128 // Construct and configure a new Digester instance 129 Digester digester = new Digester(); 130 // digester.setDebug(999); 131 digester.setNamespaceAware(true); 132 digester.setValidating(false); 133 digester.push(this); 134 135 // Add rules to recognize the built-in steps that we know about 136 BaseRuleSet brs = new BaseRuleSet(); 137 digester.addRuleSet(brs); 138 digester.addRuleSet(new CoreRuleSet()); 139 digester.addRuleSet(new IoRuleSet()); 140 141 // Add a rule to register the Activity being created 142 digester.setRuleNamespaceURI(brs.getNamespaceURI()); 143 digester.addSetNext("activity", "setActivity", 144 "org.apache.commons.workflow.Activity"); 145 146 // Return the completed instance 147 return (digester); 148 149 } 150 151 152 /** 153 * Save the Activity that our Digester has constructed. 154 * 155 * @param activity The newly constructed Activity 156 */ 157 public void setActivity(Activity activity) { 158 159 this.activity = activity; 160 161 } 162 163 164 /** 165 * Process the specified file. 166 * 167 * @param pathname Pathname of the specified XML file containing 168 * an activity definition 169 */ 170 public void process(String pathname) { 171 172 // Parse the activity definition 173 try { 174 System.out.println("Main: Parsing activity file " + pathname); 175 digester.parse(new File(pathname)); 176 } catch (Throwable t) { 177 t.printStackTrace(System.out); 178 return; 179 } 180 181 // Create a context and execute this activity 182 try { 183 System.out.println("Main: Executing parsed activity"); 184 Context context = new BaseContext(); 185 context.setActivity(activity); 186 context.addContextListener(this); 187 context.execute(); 188 } catch (Throwable t) { 189 t.printStackTrace(System.out); 190 return; 191 } 192 193 } 194 195 196 // ------------------------------------------------ ContextListener Methods 197 198 199 /** 200 * Invoked immediately after execution of the related Activity has 201 * been completed normally, been suspended, or been aborted by 202 * the throwing of a StepException. The Step included in this event 203 * will be the last one to be executed. 204 * 205 * @param event The <code>ContextEvent</code> that has occurred 206 */ 207 public void afterActivity(ContextEvent event) { 208 209 System.out.println("CL: afterActivity()"); 210 211 } 212 213 214 /** 215 * Invoked immediately after the specified Step was executed. 216 * 217 * @param event The <code>ContextEvent</code> that has occurred 218 */ 219 public void afterStep(ContextEvent event) { 220 221 System.out.println("CL: afterStep(" + event.getStep().getId() + ")"); 222 223 } 224 225 226 /** 227 * Invoked immediately before execution of the related Activity has 228 * started. The Step included in this event will be the first one 229 * to be executed. 230 * 231 * @param event The <code>ContextEvent</code> that has occurred 232 */ 233 public void beforeActivity(ContextEvent event) { 234 235 System.out.println("CL: beforeActivity()"); 236 237 } 238 239 240 /** 241 * Invoked immediately before the specified Step is executed. 242 * 243 * @param event The <code>ContextEvent</code> that has occurred 244 */ 245 public void beforeStep(ContextEvent event) { 246 247 System.out.println("CL: beforeStep(" + event.getStep().getId() + ")"); 248 249 } 250 251 252 }