001/* 002 * Copyright (c) 2013 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2017-08-24 05:17:26 +0000 (Thu, 24 Aug 2017) $' 007 * '$Revision: 34620 $' 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 */ 029package org.kepler.loader.util; 030 031import java.io.File; 032import java.io.FileInputStream; 033import java.io.InputStream; 034import java.util.Map; 035 036import org.apache.commons.io.FileUtils; 037import org.kepler.Kepler; 038import org.kepler.build.util.Version; 039import org.kepler.kar.KAREntry; 040import org.kepler.kar.KARFile; 041import org.kepler.kar.handlers.ActorMetadataKAREntryHandler; 042import org.kepler.objectmanager.ActorMetadata; 043import org.kepler.util.sql.HSQL; 044 045import ptolemy.kernel.CompositeEntity; 046import ptolemy.kernel.util.NamedObj; 047import ptolemy.moml.MoMLParser; 048import ptolemy.moml.filter.BackwardCompatibility; 049import ptolemy.util.MessageHandler; 050 051/** A utility class to load workflows. This is used by 052 * org.kepler.build.RunTestWorkflows to test loading demo workflows. 053 * 054 * @author Daniel Crawl 055 * @version $Id: ParseWorkflow.java 34620 2017-08-24 05:17:26Z crawl $ 056 */ 057public class ParseWorkflow { 058 059 /** Load workflows and exit. 060 * @param args A list of workflow files to load. 061 */ 062 public static void main(String[] args) { 063 064 System.setProperty("java.awt.headless", "true"); 065 MoMLParser.setMoMLFilters(BackwardCompatibility.allFilters()); 066 MessageHandler.setMessageHandler(new MessageHandler()); 067 try { 068 // initialize Kepler to load the kepler-specific backward-compatible 069 // moml filters 070 Kepler.initialize(); 071 Kepler.setJavaPropertiesAndCopyModuleDirectories(); 072 } catch (Exception e) { 073 MessageHandler.error("Error initializing Kepler.", e); 074 } 075 076 try { 077 ParseWorkflow parse = new ParseWorkflow(); 078 parse.parseWorkflows(args); 079 } catch(Throwable t) { 080 System.err.println("Error: " + t.getMessage()); 081 t.printStackTrace(); 082 } 083 084 Kepler.shutdown(); 085 HSQL.shutdownServers(); 086 } 087 088 /** Parse an actor's XML definition. */ 089 public static NamedObj parseActor(File file) throws Exception { 090 091 if(!file.exists()) { 092 throw new Exception("Actor file does not exist: " + file.getAbsolutePath()); 093 } 094 095 FileInputStream stream = null; 096 try { 097 stream = new FileInputStream(file); 098 ActorMetadata metadata = new ActorMetadata(stream); 099 NamedObj metadataNamedObj = metadata.getActorAsNamedObj(null); 100 String metadataString = metadataNamedObj.exportMoMLPlain(); 101 102 MoMLParser parser = new MoMLParser(); 103 parser.resetAll(); 104 CompositeEntity container = new CompositeEntity(); 105 parser.setContext(container); 106 parser.parse(metadataString); 107 return container.getEntity(metadata.getName()); 108 109 } finally { 110 if(stream != null) { 111 stream.close(); 112 } 113 } 114 115 } 116 117 /** Load workflows. */ 118 public void parseWorkflows(String[] args) throws Exception { 119 for(int i = 0; i < args.length; i++) { 120 boolean isActor = false; 121 if(args[i].equals("-a")) { 122 isActor = true; 123 i++; 124 } 125 String path = args[i]; 126 File file = new File(path); 127 if(isActor) { 128 parseActor(file); 129 } else { 130 parseWorkflow(file); 131 } 132 } 133 } 134 135 /** Parse a workflow MoML XML or KAR file. 136 * @return the constructed NamedObj 137 */ 138 public static NamedObj parseWorkflow(File file) throws Exception { 139 140 if(!file.exists()) { 141 throw new Exception("File does not exist " + file.getAbsolutePath()); 142 } 143 144 if(file.getName().endsWith(".xml")) { 145 return _parseXML(file); 146 } else if(file.getName().endsWith(".kar")) { 147 return parseKAR(file, false); 148 } else { 149 throw new Exception("Unknown type of workflow: " + file.getAbsolutePath()); 150 } 151 } 152 153 /** Parse a workflow KAR file. 154 * @return the constructed NamedObj 155 */ 156 public static NamedObj parseKAR(File file, boolean ignoreDependencies) throws Exception { 157 158 // FIXME most of this method is duplicated from the 159 // KeplerConfigurationApplication constructor. 160 161 try(KARFile karFile = new KARFile(file)) { 162 163 if(!karFile.isOpenable() && !ignoreDependencies) { 164 165 // check dependencies. 166 Map<String, Version> missingDeps = karFile.getMissingDependencies(); 167 if(!missingDeps.isEmpty()) { 168 169 // print out the missing dependencies 170 System.out.println("ERROR: Missing module dependencies:"); 171 for(Map.Entry<String, Version> entry : missingDeps.entrySet()) { 172 System.out.println(" " + entry.getKey()); 173 } 174 } 175 } else { 176 177 // For each Actor in the KAR open the MOML 178 for (KAREntry entry : karFile.karEntries()) { 179 180 if (!ActorMetadataKAREntryHandler.handlesClass(entry.getType())) { 181 //WARNING - using null TableauFrame here 182 karFile.open(entry, null); 183 } else { 184 // extract MOML to temp file 185 File tmpFile = null; 186 try { 187 tmpFile = File.createTempFile("moml", ".xml"); 188 try(InputStream inputStream = karFile.getInputStream(entry);) { 189 FileUtils.copyInputStreamToFile(inputStream, tmpFile); 190 } 191 return _parseXML(tmpFile); 192 } finally { 193 // delete file when done. 194 if(tmpFile != null && !tmpFile.delete()) { 195 System.err.println("Could not delete " + tmpFile.getAbsolutePath()); 196 } 197 } 198 } 199 } 200 } 201 } 202 return null; 203 } 204 205 /** Parse a MoML string. */ 206 public static NamedObj parseMoML(String momlStr) throws Exception { 207 // MoMLParser is not thread-safe 208 synchronized(_lock) { 209 return new MoMLParser().parse(momlStr); 210 } 211 } 212 213 /** Parse a workflow MoML file. */ 214 private static NamedObj _parseXML(File file) throws Exception { 215 // MoMLParser is not thread-safe 216 synchronized(_lock) { 217 return new MoMLParser().parse(null, file.toURI().toURL()); 218 } 219 } 220 221 private final static Object _lock = new Object(); 222 223}