001/* 002 * Copyright (c) 2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2015-06-18 22:21:04 +0000 (Thu, 18 Jun 2015) $' 007 * '$Revision: 33484 $' 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 030 031package org.kepler.provenance; 032 033import java.io.BufferedWriter; 034import java.io.FileWriter; 035import java.io.IOException; 036import java.io.StringWriter; 037import java.text.SimpleDateFormat; 038import java.util.Date; 039 040import javax.xml.parsers.DocumentBuilder; 041import javax.xml.parsers.DocumentBuilderFactory; 042import javax.xml.transform.OutputKeys; 043import javax.xml.transform.Transformer; 044import javax.xml.transform.TransformerConfigurationException; 045import javax.xml.transform.TransformerException; 046import javax.xml.transform.TransformerFactory; 047import javax.xml.transform.dom.DOMSource; 048import javax.xml.transform.stream.StreamResult; 049 050import org.w3c.dom.Comment; 051import org.w3c.dom.Document; 052import org.w3c.dom.Element; 053 054import ptolemy.actor.Actor; 055import ptolemy.actor.Director; 056import ptolemy.actor.FiringEvent; 057import ptolemy.actor.IOPortEvent; 058import ptolemy.actor.IORelation; 059import ptolemy.actor.TypedIOPort; 060import ptolemy.data.StringToken; 061import ptolemy.data.expr.FileParameter; 062import ptolemy.data.expr.Parameter; 063import ptolemy.kernel.util.AbstractSettableAttribute; 064import ptolemy.kernel.util.IllegalActionException; 065import ptolemy.kernel.util.NameDuplicationException; 066import ptolemy.kernel.util.NamedObj; 067 068/** Provenance recording that outputs to an XML file. 069 * 070 * @author Faraaz Sareshwala 071 * @version $Id: XMLRecording.java 33484 2015-06-18 22:21:04Z crawl $ 072 * @deprecated This no longer works. For XML output, use ProvRecording. 073 */ 074@Deprecated 075public class XMLRecording extends Recording 076{ 077 public XMLRecording() throws RecordingException 078 { 079 super(); 080 081 try 082 { 083 // We need a Document 084 DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); 085 DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); 086 xmldoc = docBuilder.newDocument(); 087 088 // create the root element and add it to the document 089 xmlroot = xmldoc.createElement("run"); 090 Comment comment = xmldoc.createComment("Parameters and ports are given in their display name form only." 091 + " Constructing the full name is simply the entity full name + \".\" + displayname"); 092 xmlroot.appendChild(comment); 093 xmldoc.appendChild(xmlroot); 094 } 095 catch(Exception e) 096 { 097 e.printStackTrace(); 098 } 099 } 100 101 public boolean regActor(Actor actor) throws RecordingException 102 { 103 xmlactor = xmldoc.createElement("actor"); 104 xmlactor.setAttribute("name", actor.getFullName()); 105 xmlroot.appendChild(xmlactor); 106 107 return true; 108 } 109 110 public boolean regDirector(Director director) throws RecordingException 111 { 112 // create director child element, add an attribute, and add to root 113 xmldirector = xmldoc.createElement("director"); 114 xmldirector.setAttribute("name", director.getFullName()); 115 xmlroot.appendChild(xmldirector); 116 117 return true; 118 } 119 120 /** Register a link between two endpoints. */ 121 public boolean regLink(NamedObj endPoint1, NamedObj endPoint2) throws RecordingException 122 { 123 // TODO: Monitor this. 124 125 return true; 126 } 127 128 /** Register a port or portparameter. */ 129 public boolean regPort(TypedIOPort port) throws RecordingException 130 { 131 xmlport = xmldoc.createElement("port"); 132 xmlport.setAttribute("name", port.getFullName()); 133 xmlactor.appendChild(xmlport); 134 135 return true; 136 } 137 138 /** Register a relation. */ 139 public boolean regRelation(IORelation relation) throws RecordingException 140 { 141 // TODO: Monitor this. 142 143 return true; 144 } 145 146 public boolean regParameter(NamedObj parameter) throws RecordingException 147 { 148 Element xmlparameter = xmldoc.createElement("parameter"); 149 xmlparameter.setAttribute("name", parameter.getDisplayName()); 150 xmlparameter.setAttribute("class", parameter.getClassName()); 151 152 if(parameter instanceof AbstractSettableAttribute) 153 xmlparameter.setTextContent(((AbstractSettableAttribute) parameter).getValueAsString()); 154 155 if(xmldirector != null && parameter.getContainer().getFullName().equals(xmldirector.getAttribute("name"))) 156 xmldirector.appendChild(xmlparameter); // are we working with a director? 157 else if(xmlactor != null && parameter.getContainer().getFullName().equals(xmlactor.getAttribute("name"))) 158 xmlactor.appendChild(xmlparameter); // are we working with an actor? 159 else if(xmlport != null && parameter.getContainer().getFullName().equals(xmlport.getAttribute("name"))) 160 xmlport.appendChild(xmlparameter); // are we working with a port? 161 162 return true; 163 } 164 165 /** 166 * Record the stopping of workflow execution. 167 */ 168 public void executionStop() throws RecordingException 169 { 170 try 171 { 172 FileParameter fp = _params.getFileParameter(); 173 String name = ((StringToken) fp.getToken()).stringValue(); 174 175 // remove possible "file:" prefix 176 if(name.startsWith("file:")) 177 name = name.substring("file:".length()); 178 179 // save the name 180 _outputName = name; 181 182 TransformerFactory transfac = TransformerFactory.newInstance(); 183 Transformer trans = transfac.newTransformer(); 184 trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 185 trans.setOutputProperty(OutputKeys.INDENT, "yes"); 186 187 // create string from xml tree 188 StringWriter sw = new StringWriter(); 189 StreamResult result = new StreamResult(sw); 190 DOMSource source = new DOMSource(xmldoc); 191 trans.transform(source, result); 192 String xmlString = sw.toString(); 193 194 BufferedWriter output = new BufferedWriter(new FileWriter(name)); 195 196 output.write(xmlString); 197 output.close(); 198 } 199 catch(TransformerConfigurationException e) 200 { 201 e.printStackTrace(); 202 } 203 catch(TransformerException e) 204 { 205 e.printStackTrace(); 206 } 207 catch(IllegalActionException e) 208 { 209 e.printStackTrace(); 210 } 211 catch(IOException e) 212 { 213 e.printStackTrace(); 214 } 215 } 216 217 /** Record starting an actor fire event. */ 218 public void actorFire(FiringEvent event) throws RecordingException 219 { 220 221 if(event.getType() == event.AFTER_FIRE) 222 { 223 // create actor event element, add an attribute, and add to root 224 Element xmlevent = xmldoc.createElement("event"); 225 xmlevent.setAttribute("timestamp", Long.toString(new Date().getTime())); 226 xmlevent.setAttribute("type", "actorFire"); 227 xmlevent.setAttribute("entity", event.getActor().getFullName()); 228 xmlroot.appendChild(xmlevent); 229 } 230 } 231 232 /** Record a port event. */ 233 public void portEvent(IOPortEvent event) throws RecordingException 234 { 235 // create port event element, add an attribute, and add to root 236 Element xmlevent = xmldoc.createElement("event"); 237 xmlevent.setAttribute("timestamp", Long.toString(new Date().getTime())); 238 xmlevent.setAttribute("type", "portEvent"); 239 xmlevent.setAttribute("entity", event.getPort().getFullName()); 240 241 Element xmltoken = xmldoc.createElement("token"); 242 xmltoken.setTextContent(event.getToken().toString()); 243 xmlevent.appendChild(xmltoken); 244 245 xmlroot.appendChild(xmlevent); 246 } 247 248 /** Add Parameters for ProvenanceListener. */ 249 public RecordingParameters generateParameters(NamedObj no) throws IllegalActionException, NameDuplicationException 250 { 251 _params = new XMLRecordingParameters(no); 252 return _params; 253 } 254 255 /* Adapted from TextFileRecording to perform the same actions. 256 * Can be extended later. 257 * Configuration Parameters for TextFileRecording. */ 258 protected class XMLRecordingParameters extends RecordingParameters 259 { 260 XMLRecordingParameters(NamedObj no) throws IllegalActionException, NameDuplicationException 261 { 262 super(no); 263 addBooleanParameter(_recordSpecStr, _recordSpecVal); 264 addFileParameter(_filenameStr, "System.out"); 265 } 266 267 /** Get the "Record Specification" check-box value. */ 268 boolean getRecordSpecValue() throws IllegalActionException 269 { 270 return getBooleanValue(_recordSpecStr); 271 } 272 273 /** Get the output FileParameter. */ 274 FileParameter getFileParameter() throws IllegalActionException 275 { 276 return (FileParameter) _params.get(_filenameStr); 277 } 278 279 /** Replace a Parameter. */ 280 public void replaceParameter(String name, Parameter parameter) throws IllegalActionException 281 { 282 // if replacing the filename, close the file. 283 if(name.equals(_filenameStr)) 284 { 285 FileParameter p = (FileParameter) _params.get(_filenameStr); 286 p.close(); 287 } 288 289 super.replaceParameter(name, parameter); 290 } 291 292 private static final String _recordSpecStr = "Record Specification"; 293 private static final String _filenameStr = "Filename"; 294 } 295 296 // ////////////////////////////////////////////////////////////////////// 297 // // protected variables //// 298 299 /** Whether to record workflow specification. */ 300 protected boolean _recordSpecVal = true; 301 302 /** Whether to always flush after writing to output. */ 303 protected boolean _alwaysFlushVal = false; 304 305 /** Format timestamps. */ 306 protected SimpleDateFormat _dFormat = null; 307 308 /** Parameters for TextFileRecording */ 309 protected XMLRecordingParameters _params = null; 310 311 /** Output name. */ 312 protected String _outputName = null; 313 314 /** XML Document **/ 315 Document xmldoc = null; 316 317 /** XML Root **/ 318 Element xmlroot = null; 319 320 /** XML Actor currently being edited **/ 321 Element xmlactor = null; 322 323 /** XML Director currently being edited **/ 324 Element xmldirector = null; 325 326 /** XML Port currently being edited **/ 327 Element xmlport = null; 328}