001 /* 002 * Copyright 1999-2001,2004 The Apache Software Foundation. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.apache.commons.workflow.demo; 018 019 020 import java.io.File; 021 import org.apache.commons.digester.Digester; 022 import org.apache.commons.workflow.Activity; 023 import org.apache.commons.workflow.Context; 024 import org.apache.commons.workflow.ContextEvent; 025 import org.apache.commons.workflow.ContextListener; 026 import org.apache.commons.workflow.base.BaseContext; 027 import org.apache.commons.workflow.base.BaseRuleSet; 028 import org.apache.commons.workflow.core.CoreRuleSet; 029 import org.apache.commons.workflow.io.IoRuleSet; 030 import org.apache.commons.workflow.web.WebRuleSet; 031 032 033 /** 034 * <p>Demonstration program to illustrate how the Workflow Management System 035 * is utilized. It accepts a command line argument to an XML file that 036 * contains an <code><activity></code> to be parsed and then executed. 037 * If no file is specified, a default XML document will be utilized.</p> 038 * 039 * <p><strong>WARNING</strong> - This program is for illustration only while 040 * the workflow management system is being developed, and it will not be 041 * part of the final package. Indeed, much of its functionality (such as 042 * the parsing of XML files describing activities) will need to be encapsulated 043 * inside the system, in ways that support the per-namespace step definitions 044 * as outlined in the original proposal.</p> 045 * 046 * <p><strong>WARNING</strong> - This code depends on the version of Digester 047 * currently in SVN - the 1.0 released version will not work correctly with 048 * namespace prefixes.</p> 049 * 050 * <p><strong>WARNING</strong> - The namespace URLs in the example XML document 051 * are not official - they are simply used to satisfy the syntax requirements 052 * of the XML parser. Official namespace URIs <em>will</em> be required for a 053 * formal release of this technology, because that is key to the extensibility 054 * of Step implementations.</p> 055 * 056 * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $ 057 * @author Craig R. McClanahan 058 */ 059 060 public class Main implements ContextListener { 061 062 063 // ----------------------------------------------------------- Main Program 064 065 066 /** 067 * The main program for the demo. 068 * 069 * @param args Command line arguments 070 */ 071 public static void main(String args[]) { 072 073 // Make sure there is a filename argument 074 if (args.length != 1) { 075 System.out.println("Usage: java org.apache.commons.workflow.demo.Main {XML-file}"); 076 System.exit(1); 077 } 078 079 // Construct and utilize a new instance of this class 080 Main main = new Main(); 081 main.process(args[0]); 082 083 } 084 085 086 // ----------------------------------------------------- Instance Variables 087 088 089 /** 090 * The Activity constructed by our Digester. 091 */ 092 protected Activity activity = null; 093 094 095 /** 096 * The Digester used to process input files. 097 */ 098 protected Digester digester = null; 099 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 }