001/* Filter that adds _hideName to annotations
002
003 Copyright (c) 2002-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 ptolemy.data.BooleanToken;
031import ptolemy.data.expr.SingletonParameter;
032import ptolemy.kernel.util.NameDuplicationException;
033import ptolemy.kernel.util.NamedObj;
034import ptolemy.kernel.util.Settable;
035import ptolemy.moml.MoMLParser;
036
037///////////////////////////////////////////////////////////////////
038//// HideAnnotationNames
039
040/** When this class is registered with the MoMLParser.addMoMLFilter()
041 method, it will cause MoMLParser to add a _hideName property
042 property for any annotations.
043
044 @author Christopher Hylands
045 @version $Id$
046 @since Ptolemy II 2.0
047 @Pt.ProposedRating Red (cxh)
048 @Pt.AcceptedRating Red (cxh)
049 */
050public class HideAnnotationNames extends MoMLFilterSimple {
051    /** Hide annotation names.
052     *  If the attributeName is "name" and attributeValue ends
053     *  with "annotation", then
054     *  <pre>
055     *   &lt;property name="_hideName" class="ptolemy.data.expr.SingletonParameter" value="true"&gt;
056     *   &lt;/property&gt;
057     *  </pre>
058     *  is added if it is not yet present.
059     *
060     *  @param container  The container for this attribute.
061     *  in this method.
062     *  @param element The XML element name.
063     *  @param attributeName The name of the attribute.
064     *  @param attributeValue The value of the attribute.
065     *  @param xmlFile The file currently being parsed.
066     *  @return the value of the attributeValue argument.
067     */
068    @Override
069    public String filterAttributeValue(NamedObj container, String element,
070            String attributeName, String attributeValue, String xmlFile) {
071        if (attributeValue == null) {
072            // attributeValue == null is fairly common, so we check for
073            // that first
074            return null;
075        }
076
077        if (attributeName.equals("name")) {
078            if (attributeValue.endsWith("annotation1")) {
079                // We found a line like
080                // <property name="13:0:0:annotation1"
081                //          class="ptolemy.kernel.util.Attribute">
082                _currentlyProcessingAnnotation = true;
083                // Coverity says that container could be null.
084                _currentAnnotationFullName = (container == null ? ""
085                        : container.getFullName()) + "." + attributeValue;
086            } else if (_currentlyProcessingAnnotation
087                    && attributeValue.equals("_hideName")) {
088                // We are processing an annotation and it already
089                // has _hideName
090                _currentlyProcessingAnnotation = false;
091                _currentAnnotationFullName = null;
092            }
093        }
094
095        if (_currentlyProcessingAnnotation) {
096            if (container != null) {
097                if (!container.getFullName()
098                        .equals(_currentAnnotationFullName)) {
099                    if (_currentAnnotationFullName == null
100                            || (!_currentAnnotationFullName
101                                    .startsWith(container.getFullName())
102                                    && !container.getFullName().startsWith(
103                                            _currentAnnotationFullName))) {
104                        // We found another class in a different container
105                        // while handling an annotation.
106                        _currentlyProcessingAnnotation = false;
107                        _currentAnnotationFullName = null;
108                    }
109                }
110            }
111        }
112
113        return attributeValue;
114    }
115
116    /** Make modifications to the specified container, which is
117     *  defined in a MoML element with the specified name.
118     *  @param container The object created by this element.
119     *  @param elementName The element name.
120     *  @param currentCharData The character data, which appears
121     *   only in the doc and configure elements
122     *  @param xmlFile The file currently being parsed.
123     *  @exception Exception if there is a problem substituting
124     *  in the new value.
125     */
126    @Override
127    public void filterEndElement(NamedObj container, String elementName,
128            StringBuffer currentCharData, String xmlFile) throws Exception {
129        if (!elementName.equals("property")) {
130            return;
131        }
132
133        if (_currentlyProcessingAnnotation && container != null
134                && container.getFullName().equals(_currentAnnotationFullName)) {
135            _currentlyProcessingAnnotation = false;
136            _currentAnnotationFullName = null;
137
138            try {
139                SingletonParameter hide = new SingletonParameter(container,
140                        "_hideName");
141                hide.setToken(BooleanToken.TRUE);
142                hide.setVisibility(Settable.EXPERT);
143
144                MoMLParser.setModified(true);
145            } catch (NameDuplicationException ex) {
146                // Ignore, the container already has a _hideName.
147                // The Network model has this problem.
148            }
149        }
150    }
151
152    /** Return a string that describes what the filter does.
153     *  @return the description of the filter that ends with a newline.
154     */
155    @Override
156    public String toString() {
157        return getClass().getName() + ": If an annotation name ends with\n"
158                + "'annotation1', then add _hideName if necessary.\n";
159    }
160
161    ///////////////////////////////////////////////////////////////////
162    ////                         private variables                 ////
163    // True if we are currently processing an annotation.
164    private boolean _currentlyProcessingAnnotation = false;
165
166    // The the full name of the annotation we are currently processing
167    private String _currentAnnotationFullName;
168}