001/* Remove classes
002
003 Copyright (c) 1998-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;
035
036///////////////////////////////////////////////////////////////////
037//// RemoveClasses
038
039/** When this class is registered with the MoMLParser.addMoMLFilter()
040 method, it will cause MoMLParser to remove or replace classes.
041
042<p>Note that that in the default, this class has an empty list
043of classes to be removed or replaced.  To add classes to be removed,
044call put("my.class.to.be.removed", null).
045
046<p>This class is not added to the list of filters in
047BackwardCompatibility, it must be added by calling
048{#link ptolemy.moml.MoMLParser.addMoMLFilter(MoMLFilter)
049
050 @author  Edward A. Lee, Christopher Hylands
051 @version $Id$
052 @since Ptolemy II 8.0
053 @Pt.ProposedRating Red (cxh)
054 @Pt.AcceptedRating Red (cxh)
055 */
056public class RemoveClasses extends MoMLFilterSimple {
057    /** Clear the map of graphical classes to be removed.
058     */
059    public static void clear() {
060        _graphicalClasses = new HashMap();
061    }
062
063    /** Filter for graphical classes and return new values if
064     *  a graphical class is found.
065     *  An internal HashMap maps names of graphical entities to
066     *  new names.  The HashMap can also map a graphical entity
067     *  to null, which means the entity is removed from the model.
068     *  All class attributeValues that start with "ptolemy.domains.gr"
069     *  are deemed to be graphical elements and null is always returned.
070     *  For example, if the attributeValue is "ptolemy.vergil.icon.ValueIcon",
071     *  or "ptolemy.vergil.basic.NodeControllerFactory"
072     *  then return "ptolemy.kernel.util.Attribute"; if the attributeValue
073     *  is "ptolemy.vergil.icon.AttributeValueIcon" or
074     *  "ptolemy.vergil.icon.BoxedValueIcon" then return null, which
075     *  will cause the MoMLParser to skip the rest of the element;
076     *  otherwise return the original value of the attributeValue.
077     *
078     *  @param container  The container for this attribute, ignored
079     *  in this method.
080     *  @param element The XML element name.
081     *  @param attributeName The name of the attribute, ignored
082     *   in this method.
083     *  @param attributeValue The value of the attribute.
084     *  @param xmlFile The file currently being parsed.
085     *  @return the filtered attributeValue.
086     */
087    @Override
088    public String filterAttributeValue(NamedObj container, String element,
089            String attributeName, String attributeValue, String xmlFile) {
090        // If the nightly build is failing with messages like:
091        // " X connection to foo:0 broken (explicit kill or server shutdown)."
092        // Try uncommenting the next lines to see what is being
093        // expanding before the error:
094        //System.out.println("filterAttributeValue: " + container + "\t"
095        //       +  attributeName + "\t" + attributeValue);
096        if (attributeValue == null) {
097            return null;
098        } else if (_graphicalClasses.containsKey(attributeValue)) {
099            MoMLParser.setModified(true);
100            return (String) _graphicalClasses.get(attributeValue);
101        }
102
103        return attributeValue;
104    }
105
106    /** In this class, do nothing.
107     *  @param container The object created by this element.
108     *  @param elementName The element name.
109     *  @param currentCharData The character data, which appears
110     *   only in the doc and configure elements
111     *  @param xmlFile The file currently being parsed.
112     *  @exception Exception Not thrown in this base class.
113     */
114    @Override
115    public void filterEndElement(NamedObj container, String elementName,
116            StringBuffer currentCharData, String xmlFile) throws Exception {
117    }
118
119    /** Remove a class to be filtered.
120     *  @param className The name of the class to be filtered
121     *  out, for example "ptolemy.copernicus.kernel.GeneratorAttribute".
122     *  @see #put(String, String)
123     */
124    public void remove(String className) {
125        // ptolemy.copernicus.kernel.MakefileGenerator
126        // so as to filter out the GeneratorAttribute
127        _graphicalClasses.remove(className);
128    }
129
130    /** Add a class to be filtered for and its replacement if the class
131     *  is found.  If the replacement is null, then the rest of the
132     *  attribute is skipped.  Note that if you add a class with
133     *  this method, then you must remove it with {@link #remove(String)},
134     *  calling 'new RemoveClasses' will not remove a class
135     *  that was added with this method.
136     *  @param className The name of the class to be filtered
137     *  out, for example "ptolemy.copernicus.kernel.GeneratorAttribute".
138     *  @param replacement The name of the class to be used if
139     *  className is found.  If this argument is null then the
140     *  rest of the attribute is skipped.
141     *  @see #remove(String)
142     */
143    public void put(String className, String replacement) {
144        // ptolemy.copernicus.kernel.KernelMain call this method
145        // so as to filter out the GeneratorAttribute
146        _graphicalClasses.put(className, replacement);
147    }
148
149    /** Return a string that describes what the filter does.
150     *  @return the description of the filter that ends with a newline.
151     */
152    @Override
153    public String toString() {
154        StringBuffer results = new StringBuffer(
155                getClass().getName() + ": Remove or replace classes.\n"
156                        + "The following actors are affected:\n");
157        Iterator classNames = _graphicalClasses.keySet().iterator();
158
159        while (classNames.hasNext()) {
160            String oldClassName = (String) classNames.next();
161            String newClassName = (String) _graphicalClasses.get(oldClassName);
162
163            if (newClassName == null) {
164                results.append(oldClassName + " will be removed\n");
165            } else {
166                results.append(oldClassName + " will be replaced by "
167                        + newClassName + "\n");
168            }
169        }
170
171        return results.toString();
172    }
173
174    ///////////////////////////////////////////////////////////////////
175    ////                         private variables                 ////
176
177    /** Map of actor names a HashMap of graphical classes to their
178     *  non-graphical counterparts, usually either
179     *  ptolemy.kernel.util.Attribute or null.
180     */
181    private static HashMap _graphicalClasses;
182
183    static {
184        _graphicalClasses = new HashMap();
185    }
186}