001/* 002 * Copyright (c) 2004-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 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.sdm.spa; 031 032import java.io.File; 033import java.io.IOException; 034import java.io.StringReader; 035import java.io.StringWriter; 036 037import javax.xml.transform.Result; 038import javax.xml.transform.Source; 039import javax.xml.transform.Transformer; 040import javax.xml.transform.TransformerException; 041import javax.xml.transform.TransformerFactory; 042import javax.xml.transform.dom.DOMSource; 043import javax.xml.transform.stream.StreamResult; 044import javax.xml.transform.stream.StreamSource; 045 046import org.w3c.dom.Document; 047 048import ptolemy.actor.TypedAtomicActor; 049import ptolemy.actor.TypedIOPort; 050import ptolemy.data.StringToken; 051import ptolemy.data.Token; 052import ptolemy.data.XMLToken; 053import ptolemy.data.expr.FileParameter; 054import ptolemy.data.type.BaseType; 055import ptolemy.kernel.CompositeEntity; 056import ptolemy.kernel.util.Attribute; 057import ptolemy.kernel.util.IllegalActionException; 058import ptolemy.kernel.util.NameDuplicationException; 059 060/** 061 * <p> 062 * Given an XSL transformation file, performs the specified transformation on 063 * the input XML doc. 064 * 065 * </p> 066 * <p> 067 * XSLT is designed for use as part of XSL, which is a stylesheet language for 068 * XML. In addition to XSLT, XSL includes an XML vocabulary for specifying 069 * formatting. XSL specifies the styling of an XML document by using XSLT to 070 * describe how the document is transformed into another XML document that uses 071 * the formatting vocabulary. (ref: http://www.w3.org/TR/xslt) 072 * 073 * </p> 074 * <p> 075 * Given an xml stream as input, XSLTTransformer is used for for linking (almost 076 * but not quite fitting) output port and input port data formats together. The 077 * actor produces an html stream that can be viewed or queried using the 078 * BrowserUI actor. 079 * 080 * </p> 081 * <p> 082 * The configuration window for the XSLTTransformer actor can be viewed by 083 * double-clicking on the actor or by selecting 'Configure' from the right-click 084 * context menu. The window displays a GUI for browsing the XSL script which 085 * will be used to perform the transformation. 086 * </p> 087 * 088 * @author Ilkay Altintas 089 * @version $Id: XSLTActor.java 24234 2010-05-06 05:21:26Z welker $ 090 * 091 */ 092 093public class XSLTActor extends TypedAtomicActor { 094 095 /** 096 * This parameter is to provide the path for the xsl file in user's 097 * computer. 098 * <P> 099 * This parameter can be filled in by specifying the file using the browse 100 * interface or by typing in the file. <i>The actor has <b>NO</b> default 101 * value. </i> Please double click on the actor to set it. 102 */ 103 public FileParameter xslFileName; 104 105 /** 106 * String representation of the XML or HTMl input stream that needs to be 107 * transformed. 108 */ 109 public TypedIOPort xmlIn; 110 111 /** 112 * String representation of the output of the transformation. 113 */ 114 public TypedIOPort htmlOut; 115 116 public XSLTActor(CompositeEntity container, String name) 117 throws NameDuplicationException, IllegalActionException { 118 119 super(container, name); 120 121 xmlIn = new TypedIOPort(this, "xmlIn", true, false); 122 htmlOut = new TypedIOPort(this, "htmlOut", false, true); 123 124 htmlOut.setTypeEquals(BaseType.STRING); 125 126 xslFileName = new FileParameter(this, "XSLT File Path"); 127 128 new Attribute(xmlIn, "_showName"); 129 new Attribute(htmlOut, "_showName"); 130 131 _factory = TransformerFactory.newInstance();; 132 133 _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" " 134 + "width=\"60\" height=\"30\" " + "style=\"fill:white\"/>\n" 135 + "<text x=\"10\" y=\"25\" " 136 + "style=\"font-size:16; fill:blue; font-family:SansSerif\">" 137 + "XSLT</text>\n" + "</svg>\n"); 138 139 } 140 141 public void fire() throws IllegalActionException { 142 super.fire(); 143 144 Source xmlSource; 145 StringReader xmlReader = null; 146 147 Token token = xmlIn.get(0); 148 149 // see what kind of input 150 if(token instanceof StringToken) 151 { 152 String xmlStr = ((StringToken)token).stringValue(); 153 System.out.println(xmlStr); 154 xmlReader = new StringReader(xmlStr); 155 xmlSource = new StreamSource(xmlReader); 156 } 157 else if(token instanceof XMLToken) 158 { 159 Document doc = ((XMLToken)token).getDomTree(); 160 xmlSource = new DOMSource(doc); 161 } 162 else 163 { 164 throw new IllegalActionException(this, "Unsupported type of " + 165 "input token: " + token.getType()); 166 } 167 168 StringWriter writer = new StringWriter(); 169 Result result = new StreamResult(writer); 170 171 // read the xsl file 172 File xslFile = xslFileName.asFile(); 173 if(xslFile == null) 174 { 175 throw new IllegalActionException(this, "XSL file required. "); 176 } 177 178 Source xslSource = new StreamSource(xslFile); 179 180 // perform the transformation 181 try 182 { 183 Transformer transformer = _factory.newTransformer(xslSource); 184 transformer.transform(xmlSource, result); 185 } 186 catch(TransformerException e) 187 { 188 throw new IllegalActionException(this, "Error transforming: " + 189 e.getMessage()); 190 } 191 192 // output the result 193 htmlOut.broadcast(new StringToken(writer.toString())); 194 195 // close resources 196 try 197 { 198 if(xmlReader != null) 199 { 200 xmlReader.close(); 201 } 202 writer.close(); 203 } 204 catch(IOException e) 205 { 206 throw new IllegalActionException(this, "Error closing " + 207 " string writer: " + e.getMessage()); 208 } 209 } 210 211 ///////////////////////////////////////////////////////////////////////// 212 //// private variables //// 213 214 /** Factory for xsl transformers. */ 215 private TransformerFactory _factory; 216}