001/* Filter for removing properties. 002 003 Copyright (c) 2004-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; 032import java.util.Map; 033 034import ptolemy.kernel.util.NamedObj; 035import ptolemy.moml.MoMLParser; 036 037/////////////////////////////////////////////////////////////////// 038//// RemoveProperties 039 040/** When this class is registered with the MoMLParser.setMoMLFilter() 041 method, it will cause MoMLParser to filter out the properties included 042 in this classes. 043 044 <p>For example, after Ptolemy II 5.0, the <i>stopTime</i> parameter has a 045 default value as Infinity instead of MaxDouble (a macro with value of 046 Double.MAX_VALUE). What is more, stopTime is not supposed to be stored in 047 the MoML file. Therefore, this filter filters out those stopTime parameters 048 with the old default value, MaxDouble. The new default value for the 049 stopTime parameter will be created automatically by the Java classes and 050 the parameter will not be exported into the MoML file. 051 <p> 052 A typical usage looks like the following. 053 <pre> 054 // stopTime after Ptolemy II 5.0 055 // The stopTime used to have a default value as the Double.MAX_VALUE. 056 // Now the default value is Infinity. 057 HashMap removePropertyStopTime = new HashMap(); 058 059 // Remove properties whose name is "stopTime" if their 060 // class and value properties are in the HashMap. 061 _propertiesToBeRemoved.put("stopTime", removePropertyStopTime); 062 063 // The class must be a Parameter for this to be removed. 064 removePropertyStopTime.put("ptolemy.data.expr.Parameter", null); 065 066 // The value must be one of the following representations of Double.MAX_VALUE. 067 removePropertyStopTime.put("1.7976931348623E308", null); 068 removePropertyStopTime.put("1.797693134862316E308", null); 069 removePropertyStopTime.put("MaxDouble", null); 070 removePropertyStopTime.put(""+Double.MAX_VALUE, null); 071 072 </pre> 073 The removePropertyStopTime HashMap stores all possible matches of the name 074 and class attributes of the MoML entry for this attribute. Given MoML with 075 both a class and a value, then both must match for the property to 076 be removed. 077 078 The _propertiesToBeRemoved HashMap contains all the properties 079 such as the stopTime parameter that will be removed. 080 081 <p> Note that this filter has a limitation. This filter assumes that the 082 property to be removed always has three attributes, name, class, and 083 value, and they are always in this order. 084 085 @author Haiyang Zheng 086 @version $Id$ 087 @since Ptolemy II 4.1 088 @Pt.ProposedRating Red (hyzheng) 089 @Pt.AcceptedRating Red (hyzheng) 090 */ 091public class RemoveProperties extends MoMLFilterSimple { 092 /** Return the old attribute value for properties that are not registered 093 * to be removed. Otherwise, return null to remove the property. 094 * @param container The container for this attribute. 095 * @param element The XML element name. 096 * @param attributeName The name of the attribute. 097 * @param attributeValue The value of the attribute. 098 * @param xmlFile The file currently being parsed. 099 * @return The value of the attributeValue argument. 100 */ 101 @Override 102 public String filterAttributeValue(NamedObj container, String element, 103 String attributeName, String attributeValue, String xmlFile) { 104 //System.out.println("RemoveProperties.filterAttributeValue: " + container + "\t" 105 // + attributeName + "\t" + attributeValue); 106 if (attributeValue == null) { 107 // attributeValue == null is fairly common, so we check for 108 // that first. 109 return null; 110 } 111 112 if (attributeName.equals("name")) { 113 if (_propertiesToBeRemoved.containsKey(attributeValue) 114 && element != null && element.equals("property")) { 115 _foundPropertyToBeRemoved = true; 116 _propertyMap = (HashMap) _propertiesToBeRemoved 117 .get(attributeValue); 118 } else { 119 _foundPropertyToBeRemoved = false; 120 } 121 } 122 123 if (attributeName.equals("class") && _foundPropertyToBeRemoved) { 124 if (_propertyMap.containsKey(attributeValue)) { 125 _propertyToBeRemovedConfirmed = true; 126 } else { 127 _foundPropertyToBeRemoved = false; 128 _propertyToBeRemovedConfirmed = false; 129 } 130 } 131 132 if (attributeName.equals("value") && _propertyToBeRemovedConfirmed) { 133 if (_propertyMap.containsKey(attributeValue)) { 134 String newValue = (String) _propertyMap.get(attributeValue); 135 136 if (!attributeValue.equals(newValue)) { 137 MoMLParser.setModified(true); 138 } 139 140 _foundPropertyToBeRemoved = false; 141 _propertyToBeRemovedConfirmed = false; 142 return newValue; 143 } else { 144 _foundPropertyToBeRemoved = false; 145 _propertyToBeRemovedConfirmed = false; 146 } 147 } 148 149 return attributeValue; 150 } 151 152 /** Reset private variables. 153 * @param container The object created by this element. 154 * @param elementName The element name. 155 * @param currentCharData The character data, which appears 156 * only in the doc and configure elements 157 * @param xmlFile The file currently being parsed. 158 * @exception Exception if there is a problem substituting 159 * in the new value. 160 */ 161 @Override 162 public void filterEndElement(NamedObj container, String elementName, 163 StringBuffer currentCharData, String xmlFile) throws Exception { 164 _foundPropertyToBeRemoved = false; 165 _propertyToBeRemovedConfirmed = false; 166 } 167 168 /** Return a string that describes what the filter does. 169 * @return the description of the filter that ends with a newline. 170 */ 171 @Override 172 public String toString() { 173 StringBuffer results = new StringBuffer( 174 getClass().getName() + ": Remove the properties listed below:"); 175 Iterator propertiesToBeRemoved = _propertiesToBeRemoved.keySet() 176 .iterator(); 177 178 while (propertiesToBeRemoved.hasNext()) { 179 String propertyToBeRemoved = (String) propertiesToBeRemoved.next(); 180 results.append("\t" + propertyToBeRemoved + "\n"); 181 182 HashMap propertyMap = (HashMap) _propertiesToBeRemoved 183 .get(propertyToBeRemoved); 184 Iterator attributeMapEntries = propertyMap.entrySet().iterator(); 185 186 while (attributeMapEntries.hasNext()) { 187 Map.Entry attributes = (Map.Entry) attributeMapEntries.next(); 188 String oldAttribute = (String) attributes.getKey(); 189 String newAttribute = (String) attributes.getValue(); 190 results.append( 191 "\t\t" + oldAttribute + "\t -> " + newAttribute + "\n"); 192 } 193 } 194 195 return results.toString(); 196 } 197 198 /////////////////////////////////////////////////////////////////// 199 //// private variables //// 200 // Map of the properties to be removed. 201 private static HashMap _propertiesToBeRemoved; 202 203 // Flag indicating whether a property to be removed is truly found. 204 private boolean _propertyToBeRemovedConfirmed = false; 205 206 // Flag indicating whether a potential property to be removed is found. 207 private boolean _foundPropertyToBeRemoved = false; 208 209 // Cache of map from the property to be removed to its detailed information. 210 private HashMap _propertyMap; 211 212 static { 213 /////////////////////////////////////////////////////////// 214 // The properties to be removed. 215 _propertiesToBeRemoved = new HashMap(); 216 217 // For the stopTime parameter after Ptolemy II 5.0, if the stop time 218 // parameter has an old default value, remove it. 219 // The stopTime used to have a default value as the Double.MAX_VALUE. 220 // Now the default value is Infinity. 221 HashMap removePropertyStopTime = new HashMap(); 222 223 // Key = attribute name, Value = attribute value 224 removePropertyStopTime.put("1.7976931348623E308", null); 225 removePropertyStopTime.put("1.797693134862316E308", null); 226 removePropertyStopTime.put("MaxDouble", null); 227 removePropertyStopTime.put("" + Double.MAX_VALUE, null); 228 229 removePropertyStopTime.put("ptolemy.data.expr.Parameter", null); 230 231 _propertiesToBeRemoved.put("stopTime", removePropertyStopTime); 232 233 // A property named "directorClass" that is a StringAttribute 234 // or StringParameter with value "ptolemy.domains.fsm.kernel.HSDirector" 235 // will be removed. HSDirector no longer exists, so we revert 236 // to the default. 237 HashMap removePropertyDirectorClass = new HashMap(); 238 239 // Key = attribute name, Value = attribute value 240 removePropertyDirectorClass.put("ptolemy.domains.fsm.kernel.HSDirector", 241 null); 242 removePropertyDirectorClass.put("ptolemy.kernel.util.StringAttribute", 243 null); 244 removePropertyDirectorClass.put("ptolemy.data.expr.StringParameter", 245 null); 246 247 _propertiesToBeRemoved.put("directorClass", 248 removePropertyDirectorClass); 249 } 250}