001/* 002 * Copyright (c) 2007-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2012-07-11 22:13:03 +0000 (Wed, 11 Jul 2012) $' 007 * '$Revision: 30175 $' 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 org.jdom.Document; 033import org.jdom.Element; 034import org.jdom.input.DOMBuilder; 035import org.jdom.output.XMLOutputter; 036 037import ptolemy.actor.TypedAtomicActor; 038import ptolemy.actor.TypedIOPort; 039import ptolemy.data.StringToken; 040import ptolemy.data.Token; 041import ptolemy.data.XMLToken; 042import ptolemy.data.type.ArrayType; 043import ptolemy.data.type.BaseType; 044import ptolemy.data.type.Type; 045import ptolemy.kernel.CompositeEntity; 046import ptolemy.kernel.util.IllegalActionException; 047import ptolemy.kernel.util.NameDuplicationException; 048 049////////////////////////////////////////////////////////////////////////// 050//// XMLUpdater class name 051/** 052 * On each firing, read an XML token from port <i>input</i>, one token from each 053 * additional input port, and output the original XML updated with new values. 054 * This actor is similar to RecordUpdater. 055 * 056 * @author Daniel Crawl 057 * @version $Id: XMLUpdater.java 30175 2012-07-11 22:13:03Z crawl $ 058 */ 059 060public class XMLUpdater extends TypedAtomicActor { 061 062 /** 063 * Construct an XMLUpdater source with the given container and name. 064 * 065 * @param name 066 * The name of this actor. 067 * @exception IllegalActionException 068 * If the entity cannot be contained by the proposed 069 * container. 070 * @exception NameDuplicationException 071 * If the container already has an actor with this name. 072 */ 073 public XMLUpdater(CompositeEntity container, String name) 074 throws NameDuplicationException, IllegalActionException { 075 super(container, name); 076 077 input = new TypedIOPort(this, XML_IN_PORT_NAME, true, false); 078 input.setTypeEquals(BaseType.XMLTOKEN); 079 080 output = new TypedIOPort(this, "output", false, true); 081 output.setTypeEquals(BaseType.XMLTOKEN); 082 083 _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" " 084 + "width=\"60\" height=\"20\" " + "style=\"fill:white\"/>\n" 085 + "</svg>\n"); 086 087 _domBuilder = new DOMBuilder(); 088 _xo = new XMLOutputter(); 089 } 090 091 // ///////////////////////////////////////////////////////////////// 092 // // ports and parameters //// 093 094 /** The input port that reads the XML document. */ 095 public TypedIOPort input = null; 096 097 /** The output port that writes the XML document. */ 098 public TypedIOPort output = null; 099 100 // ///////////////////////////////////////////////////////////////// 101 // // public methods //// 102 103 /** 104 * Send the token in the value parameter to the output. 105 * 106 * @exception IllegalActionException 107 * If it is thrown by the send() method sending out the 108 * token. 109 */ 110 public void fire() throws IllegalActionException { 111 super.fire(); 112 113 XMLToken token = (XMLToken) input.get(0); 114 org.w3c.dom.Document d = token.getDomTree(); 115 Document doc = _domBuilder.build(d); 116 Element root = doc.getRootElement(); 117 118 Object[] inPortArray = inputPortList().toArray(); 119 for (int i = 0; i < inPortArray.length; i++) { 120 TypedIOPort port = (TypedIOPort) inPortArray[i]; 121 String name = port.getName(); 122 123 if (!name.equals(XML_IN_PORT_NAME) && port.getWidth() > 0) { 124 _appendToDoc(root, port); 125 } 126 } 127 128 XMLToken outToken = null; 129 130 try { 131 outToken = new XMLToken(_xo.outputString(doc)); 132 } catch (Exception e) { 133 throw new IllegalActionException(this, 134 "Exception creating XMLToken: " + e.getMessage()); 135 } 136 137 output.broadcast(outToken); 138 } 139 140 // ///////////////////////////////////////////////////////////////// 141 // // private methods //// 142 143 private void _appendToDoc(Element root, TypedIOPort port) 144 throws IllegalActionException { 145 Token token = port.get(0); 146 147 if (port.getType() instanceof ArrayType) { 148 throw new IllegalActionException(this, "Arrays not yet supported"); 149 } else { 150 _appendOneToken(root, port.getName(), token); 151 } 152 } 153 154 private void _appendOneToken(Element root, String name, Token token) 155 throws IllegalActionException { 156 Type type = token.getType(); 157 String str = null; 158 159 if (type == BaseType.XMLTOKEN) { 160 throw new IllegalActionException(this, "xml not supported"); 161 } else if (type == BaseType.STRING) { 162 str = ((StringToken) token).stringValue(); 163 } else { 164 str = token.toString(); 165 } 166 167 Element child = new Element(name); 168 child.setText(str); 169 root.addContent(child); 170 } 171 172 // ///////////////////////////////////////////////////////////////// 173 // // private variables //// 174 175 private final static String XML_IN_PORT_NAME = "input"; 176 177 private DOMBuilder _domBuilder; 178 private XMLOutputter _xo; 179}