001/* UnitEquation visitor that substitutes any portname with their full portname.
002
003 Copyright (c) 2003-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_3
025 COPYRIGHTENDKEY
026 */
027package ptolemy.moml.unit;
028
029import java.util.Iterator;
030import java.util.List;
031
032import ptolemy.actor.IOPort;
033import ptolemy.kernel.ComponentEntity;
034import ptolemy.kernel.util.IllegalActionException;
035
036///////////////////////////////////////////////////////////////////
037//// ExpandPortNames
038
039/**
040 Visit a UnitEquation and for each contained variable that represents a port
041 substitute it with a variable that represents the port from
042 the perspective of the model that contains the actor that contains the port.
043
044 For example, the variable representing the value of the plus port
045 of an actor named AddSubtract22 would originally have the variable
046 label plus which would be substituted with AddSubtract22.plus.
047
048 The reason for doing this is that a ComponentEntity will have
049 constraints on units specified as a set of UnitEquations. Within
050 each UnitEquation a variable of the form $PortName is used to
051 represent the Unit value at that port. Since a CompositeEntity will
052 have several ComponentEntities, each with a set of ports, it is
053 possible that port names will be duplicated.
054
055 @author Rowland R Johnson
056 @version $Id$
057 @since Ptolemy II 8.0
058 @Pt.ProposedRating Red (rowland)
059 @Pt.AcceptedRating Red (rowland)
060 */
061public class ExpandPortNames extends EquationVisitor {
062    ///////////////////////////////////////////////////////////////////
063    ////                         public methods                    ////
064
065    /** The method is the entry point to the class.
066     * @param equation The UnitEquation to be visited.
067     * @param actor The ComponentEntity that contains ports that may be
068     * referenced in the equation.
069     */
070    public void expand(UnitEquation equation, ComponentEntity actor)
071            throws IllegalActionException {
072        _actorPorts = actor.portList();
073        equation.visit(this);
074    }
075
076    ///////////////////////////////////////////////////////////////////
077    ////                         protected methods                 ////
078
079    /** The method that actually does the substitution of a variable with
080     *  the model name of the port.
081     * @see ptolemy.moml.unit.EquationVisitor#_visitUnitTerm(UnitTerm)
082     */
083    @Override
084    protected Object _visitUnitTerm(UnitTerm uTerm)
085            throws IllegalActionException {
086        if (uTerm.isVariable()) {
087            String portName = uTerm.getVariable();
088
089            if (portName == null) {
090                throw new IllegalActionException(uTerm + " is not a variable");
091            }
092
093            Iterator iter = _actorPorts.iterator();
094
095            while (iter.hasNext()) {
096                IOPort actorPort = (IOPort) iter.next();
097
098                if (actorPort.getName().equals(portName)) {
099                    uTerm.setVariable(actorPort
100                            .getName(actorPort.getContainer().getContainer()));
101                    return null;
102                }
103            }
104
105            throw new IllegalActionException(
106                    "Can't find Model port " + portName);
107        }
108
109        return null;
110    }
111
112    ///////////////////////////////////////////////////////////////////
113    ////                         private variables                 ////
114    List _actorPorts;
115}