001/* 002 * Copyright (c) 2008-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2013-05-15 18:43:58 +0000 (Wed, 15 May 2013) $' 007 * '$Revision: 32048 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.kepler; 031 032import java.io.File; 033import java.io.FileNotFoundException; 034import java.io.FileReader; 035import java.io.IOException; 036import java.util.Vector; 037 038import org.kepler.loader.util.ParseWorkflow; 039import org.kepler.util.sql.HSQL; 040 041import ptolemy.actor.CompositeActor; 042import ptolemy.actor.ExecutionListener; 043import ptolemy.actor.Manager; 044import ptolemy.kernel.util.IllegalActionException; 045import ptolemy.kernel.util.KernelException; 046import ptolemy.kernel.util.NamedObj; 047import ptolemy.kernel.util.Workspace; 048import ptolemy.moml.MoMLParser; 049import ptolemy.moml.filter.BackwardCompatibility; 050import ptolemy.util.MessageHandler; 051 052/** 053 * This class is the main entry point for making API calls to the underlying 054 * ptolemy execution engine and moml parser. 055 */ 056public class ExecutionEngine implements ExecutionListener 057{ 058 private static ExecutionEngine instance = null; 059 private Vector<ExecutionListener> exeListeners; 060 061 /** 062 * singleton accessor 063 */ 064 public static ExecutionEngine getInstance() 065 { 066 if(instance == null) 067 { 068 instance = new ExecutionEngine(); 069 } 070 return instance; 071 } 072 073 /** 074 * private constructor 075 */ 076 private ExecutionEngine() 077 { 078 MoMLParser.setMoMLFilters(BackwardCompatibility.allFilters()); 079 MessageHandler.setMessageHandler(new MessageHandler()); 080 exeListeners = new Vector<ExecutionListener>(); 081 } 082 083 /** 084 * run a single model in the current thread 085 * @param model the model to run 086 * @return Manager the manager to control the execution 087 */ 088 public Manager runModel(CompositeActor model) 089 throws IllegalActionException, KernelException 090 { 091 System.out.println("Running model in current thread: " + model.getName()); 092 Manager manager = setupModel(model); 093 runModel(manager, false); 094 return manager; 095 } 096 097 /** 098 * run a model in a new thread. Use the manager to control the thread. 099 * @param model the model to run 100 * @return Manager the manager that controls the new thread 101 */ 102 public Manager runModelInThread(CompositeActor model) 103 throws IllegalActionException, KernelException 104 { 105 System.out.println("Running model in new thread: " + model.getName()); 106 Manager manager = setupModel(model); 107 runModel(manager, true); 108 return manager; 109 } 110 111 /** 112 * add an execution listener 113 * @param exeListener the listener to add 114 */ 115 public void addExecutionListener(ExecutionListener exeListener) 116 { 117 exeListeners.addElement(exeListener); 118 } 119 120 /** 121 * remove an execution listener 122 * @param exeListener the listener to remove 123 */ 124 public void removeExecutionListener(ExecutionListener exeListener) 125 { 126 exeListeners.remove(exeListener); 127 } 128 129 /** 130 * return a vector of all of the registered ExecutionListeners 131 */ 132 public Vector<ExecutionListener> getExecutionListeners() 133 { 134 return exeListeners; 135 } 136 137 /** 138 * static method to parse a moml document and return a NamedObj 139 * @param moml the moml to parse 140 */ 141 public static NamedObj parseMoML(String moml) 142 throws Exception 143 { 144 return parseMoML(moml, null); 145 } 146 147 /** 148 * static method to parse a moml document and return a NamedObj 149 * @param moml the moml to parse 150 * @param workspace the workspace to parse the moml in to. 151 */ 152 public static NamedObj parseMoML(String moml, Workspace workspace) 153 throws Exception 154 { 155 MoMLParser parser; 156 if(workspace == null) 157 { 158 parser = new MoMLParser(); 159 } 160 else 161 { 162 parser = new MoMLParser(workspace); 163 } 164 NamedObj obj = parser.parse(moml); 165 return obj; 166 } 167 168 /** 169 * read a file and return its contents as a string 170 * @param filename the name or path of the file to read 171 */ 172 public static String readFile(String filename) 173 throws FileNotFoundException, IOException 174 { 175 File f = new File(filename); 176 FileReader fr = null; 177 try 178 { 179 fr = new FileReader(f); 180 char[] c = new char[1024]; 181 int numread = fr.read(c, 0, 1024); 182 StringBuffer sb = new StringBuffer(); 183 while(numread != -1) 184 { 185 sb.append(c, 0, numread); 186 numread = fr.read(c, 0, 1024); 187 } 188 return sb.toString(); 189 } 190 finally 191 { 192 if(fr != null) 193 { 194 fr.close(); 195 } 196 } 197 } 198 199 /** 200 * command line interface to this class 201 */ 202 public static void main(String[] args) 203 { 204 if(args.length != 1) 205 { 206 System.out.println("You must provide the path to the workflow to run."); 207 } 208 try 209 { 210 211 Kepler.initialize(); 212 Kepler.setJavaPropertiesAndCopyModuleDirectories(); 213 214 String workflow = args[0]; 215 File workflowFile = new File(workflow); 216 ExecutionEngine engine = ExecutionEngine.getInstance(); 217 CompositeActor model = (CompositeActor) ParseWorkflow.parseWorkflow(workflowFile); 218 if(model == null) { 219 MessageHandler.error("Error loading " + args[0]); 220 } else { 221 engine.runModel(model); 222 } 223 } 224 catch(Exception e) 225 { 226 MessageHandler.error("Error running " + args[0], e); 227 } 228 Kepler.shutdown(); 229 HSQL.shutdownServers(); 230 } 231 232 /** 233 * implements executionError in ExecutionListener 234 */ 235 public void executionError(Manager manager, Throwable throwable) 236 { 237 System.out.println("Execution finished with an error: " + throwable.getMessage()); 238 } 239 240 /** 241 * implements executionFinished in ExecutionListener 242 */ 243 public void executionFinished(Manager manager) 244 { 245 System.out.println("Execution finished successfully."); 246 } 247 248 /** 249 * implements managerStateChanged in ExecutionListener 250 */ 251 public void managerStateChanged(Manager manager) 252 { 253 //System.out.println("Manager state changed to " + manager.getState()); 254 } 255 256 /** 257 * start the execution of the model, either in a new thread or in the 258 * current thread. 259 */ 260 private void runModel(Manager manager, boolean newThread) 261 throws IllegalActionException, KernelException 262 { 263 if(newThread) 264 { 265 manager.startRun(); 266 } 267 else 268 { 269 manager.execute(); 270 } 271 } 272 273 /** 274 * prepare a model for running 275 */ 276 private Manager setupModel(CompositeActor actor) 277 throws IllegalActionException 278 { 279 Manager manager = actor.getManager(); 280 if (manager == null) 281 { 282 manager = new Manager(actor.workspace(), "manager"); 283 actor.setManager(manager); 284 } 285 286 manager.addExecutionListener(this); 287 for(int i=0; i<exeListeners.size(); i++) 288 { 289 ExecutionListener listener = (ExecutionListener)exeListeners.elementAt(i); 290 manager.addExecutionListener(listener); 291 } 292 return manager; 293 } 294}