001/* Remove classes not compatible with Ptiny 002 003 Copyright (c) 2009-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.moml.filter; 029 030import java.util.HashMap; 031import java.util.Iterator; 032 033import ptolemy.kernel.util.NamedObj; 034import ptolemy.moml.MoMLParser; 035import ptolemy.util.StringUtilities; 036 037/////////////////////////////////////////////////////////////////// 038//// RemoveNonPtinyClasses 039 040/** 041 Remove classes such as code generators that are not present in Ptiny. 042 043 <p> When this class is registered with the MoMLParser.setMoMLFilter() 044 method, it will cause MoMLParser to filter out classes that are 045 not present in the Ptiny configuration. 046 047 @author Christopher Hylands 048 @version $Id$ 049 @since Ptolemy II 8.0 050 @Pt.ProposedRating Red (cxh) 051 @Pt.AcceptedRating Red (cxh) 052 */ 053public class RemoveNonPtinyClasses extends MoMLFilterSimple { 054 /** Clear the map of graphical classes to be removed. 055 */ 056 public static void clear() { 057 _nonPtinyClasses = new HashMap(); 058 } 059 060 /** Filter for graphical classes and return new values if 061 * a graphical class is found. 062 * An internal HashMap maps names of graphical entities to 063 * new names. The HashMap can also map a graphical entity 064 * to null, which means the entity is removed from the model. 065 * All class attributeValues that start with "ptolemy.domains.gr" 066 * are deemed to be graphical elements and null is always returned. 067 * For example, if the attributeValue is "ptolemy.vergil.icon.ValueIcon", 068 * or "ptolemy.vergil.basic.NodeControllerFactory" 069 * then return "ptolemy.kernel.util.Attribute"; if the attributeValue 070 * is "ptolemy.vergil.icon.AttributeValueIcon" or 071 * "ptolemy.vergil.icon.BoxedValueIcon" then return null, which 072 * will cause the MoMLParser to skip the rest of the element; 073 * otherwise return the original value of the attributeValue. 074 * 075 * @param container The container for this attribute, ignored 076 * in this method. 077 * @param element The XML element name. 078 * @param attributeName The name of the attribute, ignored 079 * in this method. 080 * @param attributeValue The value of the attribute. 081 * @param xmlFile The file currently being parsed. 082 * @return the filtered attributeValue. 083 */ 084 @Override 085 public String filterAttributeValue(NamedObj container, String element, 086 String attributeName, String attributeValue, String xmlFile) { 087 // If the nightly build is failing with messages like: 088 // " X connection to foo:0 broken (explicit kill or server shutdown)." 089 // Try uncommenting the next lines to see what is being 090 // expanding before the error: 091 //System.out.println("filterAttributeValue: " + container + "\t" 092 // + attributeName + "\t" + attributeValue); 093 if (attributeValue == null) { 094 return null; 095 } else if (_nonPtinyClasses.containsKey(attributeValue)) { 096 return (String) _nonPtinyClasses.get(attributeValue); 097 } 098 099 return attributeValue; 100 } 101 102 /** In this class, do nothing. 103 * @param container The object created by this element. 104 * @param elementName The element name. 105 * @param currentCharData The character data, which appears 106 * only in the doc and configure elements 107 * @param xmlFile The file currently being parsed. 108 * @exception Exception Not thrown in this base class. 109 */ 110 @Override 111 public void filterEndElement(NamedObj container, String elementName, 112 StringBuffer currentCharData, String xmlFile) throws Exception { 113 } 114 115 /** Read in a MoML file, remove graphical classes and 116 * write the results to standard out. 117 * <p> For example, to remove the graphical classes from 118 * a file called <code>RemoveGraphicalClasses.xml</code> 119 * <pre> 120 * java -classpath "$PTII" ptolemy.moml.filter.RemoveGraphicalClasses test/RemoveGraphicalClasses.xml > output.xml 121 * </pre> 122 * @param args An array of one string 123 * <br> The name of the MoML file to be cleaned. 124 * @exception Exception If there is a problem reading or writing 125 * a file. 126 */ 127 public static void main(String[] args) throws Exception { 128 try { 129 MoMLParser parser = new MoMLParser(); 130 131 // The list of filters is static, so we reset it in case there 132 // filters were already added. 133 MoMLParser.setMoMLFilters(null); 134 135 // Add the backward compatibility filters. 136 MoMLParser.setMoMLFilters(BackwardCompatibility.allFilters()); 137 138 MoMLParser.addMoMLFilter(new RemoveGraphicalClasses()); 139 MoMLParser.addMoMLFilter(new HideAnnotationNames()); 140 MoMLParser.addMoMLFilter(new RemoveNonPtinyClasses()); 141 NamedObj topLevel = parser.parseFile(args[0]); 142 System.out.println(topLevel.exportMoML()); 143 } catch (Throwable throwable) { 144 System.err.println("Failed to filter \"" + args[0] + "\""); 145 throwable.printStackTrace(); 146 StringUtilities.exit(1); 147 } 148 } 149 150 /** Remove a class to be filtered. 151 * @param className The name of the class to be filtered 152 * out, for example "ptolemy.copernicus.kernel.GeneratorAttribute". 153 * @see #put(String, String) 154 */ 155 public void remove(String className) { 156 // ptolemy.copernicus.kernel.MakefileGenerator 157 // so as to filter out the GeneratorAttribute 158 _nonPtinyClasses.remove(className); 159 } 160 161 /** Add a class to be filtered for and its replacement if the class 162 * is found. If the replacement is null, then the rest of the 163 * attribute is skipped. Note that if you add a class with 164 * this method, then you must remove it with {@link #remove(String)}, 165 * calling 'new RemoveNonPtinyClasses' will not remove a class 166 * that was added with this method. 167 * @param className The name of the class to be filtered 168 * out, for example "ptolemy.copernicus.kernel.GeneratorAttribute". 169 * @param replacement The name of the class to be used if 170 * className is found. If this argument is null then the 171 * rest of the attribute is skipped. 172 * @see #remove(String) 173 */ 174 public void put(String className, String replacement) { 175 // ptolemy.copernicus.kernel.KernelMain call this method 176 // so as to filter out the GeneratorAttribute 177 _nonPtinyClasses.put(className, replacement); 178 } 179 180 /** Return a string that describes what the filter does. 181 * @return the description of the filter that ends with a newline. 182 */ 183 @Override 184 public String toString() { 185 StringBuffer results = new StringBuffer(getClass().getName() 186 + ": Remove classes such as code generators that are " 187 + "not present in Ptiny."); 188 Iterator classNames = _nonPtinyClasses.keySet().iterator(); 189 190 while (classNames.hasNext()) { 191 String oldClassName = (String) classNames.next(); 192 String newClassName = (String) _nonPtinyClasses.get(oldClassName); 193 194 if (newClassName == null) { 195 results.append(oldClassName + " will be removed\n"); 196 } else { 197 results.append(oldClassName + " will be replaced by " 198 + newClassName + "\n"); 199 } 200 } 201 202 return results.toString(); 203 } 204 205 /////////////////////////////////////////////////////////////////// 206 //// private variables //// 207 208 /** Map of actor names a HashMap of non-ptiny classes to their 209 * counterparts, usually either ptolemy.kernel.util.Attribute or 210 * null. 211 */ 212 private static HashMap _nonPtinyClasses; 213 214 static { 215 _nonPtinyClasses = new HashMap(); 216 217 // Alphabetical by key class 218 // We can convert any graphical classes that have a port named "input" to 219 // a Discard actor. However, classes like XYPlot have ports named "X" and Y", 220 // so XYPlot cannot be converted. 221 _nonPtinyClasses.put( 222 "ptolemy.codegen.kernel.StaticSchedulingCodeGenerator", null); 223 } 224}