001/** 002 A filter for backward compatibility with 7.2.devel or earlier models for width inference. 003 004 Copyright (c) 2008-2015 The Regents of the University of California. 005 All rights reserved. 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the above 009 copyright notice and the following two paragraphs appear in all copies 010 of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION_2 026 COPYRIGHTENDKEY 027 028 */ 029package ptolemy.moml.filter; 030 031import java.io.File; 032import java.io.FileWriter; 033import java.io.InputStream; 034import java.net.URL; 035import java.util.Locale; 036 037import ptolemy.actor.IORelation; 038import ptolemy.data.IntToken; 039import ptolemy.kernel.util.NamedObj; 040import ptolemy.moml.MoMLParser; 041 042/////////////////////////////////////////////////////////////////// 043//// ChangeFixedWidth1ToAuto 044 045/** When this class is registered with the MoMLParser.setMoMLFilter() 046 method, it will cause MoMLParser to filter so that models from 047 earlier releases will run in the current release. 048 This class will filter for relations that have a fixed width of 1. 049 The width value will be changed to AUto, which is the new default 050 for width inference. 051 052 @author Bert Rodiers 053 @version $Id$ 054 @since Ptolemy II 8.0 055 @Pt.ProposedRating Red (rodiers) 056 @Pt.AcceptedRating Red (rodiers) 057 */ 058public class ChangeFixedWidth1ToAuto extends MoMLFilterSimple { 059 060 /////////////////////////////////////////////////////////////////// 061 //// public methods //// 062 063 /** This method doesn't do anything. 064 * @param container The container for XML element. 065 * @param element The XML element name. 066 * @param attributeName The name of the attribute. 067 * @param attributeValue The value of the attribute. 068 * @param xmlFile The file currently being parsed. 069 * @return A new value for the attribute, or the same value 070 * to leave it unchanged, or null to cause the current element 071 * to be ignored (unless the attributeValue argument is null). 072 */ 073 @Override 074 public String filterAttributeValue(NamedObj container, String element, 075 String attributeName, String attributeValue, String xmlFile) { 076 return attributeValue; 077 } 078 079 /** Filter relations widths and change 1 to "Auto" and make sure still value 080 * is not not stored (if not changed). 081 * 082 * @param container The object defined by the element that this 083 * is the end of. 084 * @param elementName The element name. 085 * @param currentCharData The character data, which appears 086 * only in the doc and configure elements 087 * @param xmlFile The file currently being parsed. 088 * @exception Exception If there is a problem modifying the 089 * specified container. 090 */ 091 @Override 092 public void filterEndElement(NamedObj container, String elementName, 093 StringBuffer currentCharData, String xmlFile) throws Exception { 094 if (container instanceof IORelation) { 095 IORelation relation = (IORelation) container; 096 IntToken t = (IntToken) relation.width.getToken(); 097 098 if (t != null) { 099 int width = t.intValue(); 100 101 if (width == 1) { 102 madeModification = true; 103 relation.width.setToken("Auto"); 104 relation.width.setDerivedLevel(1); 105 // Make it derived to make sure it is not 106 // saved if not changed. 107 } 108 } 109 } 110 } 111 112 /** Main function. Changes fixed relation width equal to 1 to "Auto" and save the model. The resulting width 113 * won't be saved in practice. 114 * @param args The arguments of the main function. 115 * @exception Exception If the model can't be converted. 116 */ 117 public static void main(String[] args) throws Exception { 118 String errorMessage = "Usage: \n\tConvert one model:\n\t\tjava -classpath $PTII " 119 + "ptolemy.moml.filter.ChangeFixedWidth1ToAuto model.xml\n\tConvert all models in a folder:\n\t" 120 + "\tjava -classpath $PTII " 121 + "ptolemy.moml.filter.ChangeFixedWidth1ToAuto -all path\n\tConvert all models in a demo folder:\n\t\tjava -classpath $PTII " 122 + "ptolemy.moml.filter.ChangeFixedWidth1ToAuto -demo path"; 123 if (args.length != 1 && args.length != 2) { 124 System.err.println(errorMessage); 125 return; 126 } 127 128 if (args.length == 1) { 129 _updateFile(args[0]); 130 } 131 132 if (args.length == 2) { 133 if (!args[0].equals("-all") && !args[0].equals("-demo")) { 134 System.err.println(errorMessage); 135 return; 136 } 137 _updateXMLFiles(new File(args[1]), 138 args[0].equals("-demo") ? "demo" : null); 139 } 140 } 141 142 /** Return a string that describes what the filter does. 143 * @return A description of the filter (ending with a newline). 144 */ 145 @Override 146 public String toString() { 147 return Integer.toHexString(hashCode()); 148 } 149 150 /////////////////////////////////////////////////////////////////// 151 //// private methods //// 152 153 /** Convert the models in the folder. 154 * @param folder The folder in which models need to be converted. 155 * @param filter If null, no filter will be applied. On models for which 156 * the path contains "/" + filter + "/" are converted. 157 */ 158 private static void _updateXMLFiles(File folder, String filter) { 159 File[] files = folder.listFiles(); 160 161 if (files != null) { 162 for (File file : files) { 163 if (file.isFile()) { 164 String filename = file.getName(); 165 int length = filename.length(); 166 if (length > 3 && filename.substring(length - 4, length) 167 .toLowerCase(Locale.getDefault()).equals(".xml")) { 168 try { 169 if (filter == null || file.toURI().toString() 170 .toLowerCase(Locale.getDefault()) 171 .contains("/" + filter + "/")) { 172 _updateFile(file.toString()); 173 } 174 } catch (Exception e) { 175 continue; 176 } 177 } 178 } else if (file.isDirectory()) { 179 _updateXMLFiles(file, filter); 180 } 181 } 182 } else { 183 throw new NullPointerException( 184 "Getting the files of \"" + folder + "\" returned null?"); 185 } 186 } 187 188 /** Convert the model with name fileName. 189 * @param fileName The name (and path) of the model 190 * @exception Exception If the model can't be converted 191 */ 192 private static void _updateFile(String fileName) throws Exception { 193 MoMLParser parser = new MoMLParser(); 194 MoMLParser.setMoMLFilters(null); 195 MoMLParser.addMoMLFilters(BackwardCompatibility.allFilters()); 196 ChangeFixedWidth1ToAuto filter = new ChangeFixedWidth1ToAuto(); 197 MoMLParser.addMoMLFilter(filter); 198 199 URL xmlFile = ChangeFixedWidth1ToAuto.class.getClassLoader() 200 .getResource(fileName); 201 202 if (xmlFile != null) { 203 InputStream input = xmlFile.openStream(); 204 NamedObj model = parser.parse(null, fileName, input); 205 input.close(); 206 if (model != null && filter.madeModification) { 207 System.out.println("Start updating " + fileName); 208 FileWriter file = null; 209 try { 210 file = new FileWriter(fileName); 211 model.exportMoML(file, 0); 212 } finally { 213 if (file != null) { 214 file.close(); 215 } 216 } 217 System.out.println("End updating " + fileName); 218 } 219 } 220 } 221 222 /////////////////////////////////////////////////////////////////// 223 //// private variables //// 224 225 /** Keep track of modifications.*/ 226 private boolean madeModification = false; 227 228}