001/* This port mirrors properties of associated parameter ports. 002 003@Copyright (c) 2008-2015 The Regents of the University of California. 004All rights reserved. 005 006Permission is hereby granted, without written agreement and without 007license or royalty fees, to use, copy, modify, and distribute this 008software and its documentation for any purpose, provided that the 009above copyright notice and the following two paragraphs appear in all 010copies of this software. 011 012IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016SUCH DAMAGE. 017 018THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION_2 026 COPYRIGHTENDKEY 027 028 029 */ 030package ptolemy.actor.parameters; 031 032import ptolemy.kernel.ComponentEntity; 033import ptolemy.kernel.Entity; 034import ptolemy.kernel.util.IllegalActionException; 035import ptolemy.kernel.util.NameDuplicationException; 036import ptolemy.kernel.util.Workspace; 037import ptolemy.moml.MoMLChangeRequest; 038 039/** This port mirrors properties of associated parameter ports. 040 * 041 @author Patricia Derler 042 @version $Id$ 043 @since Ptolemy II 10.0 044 @Pt.ProposedRating Yellow (derler) 045 @Pt.AcceptedRating Red (derler) 046 */ 047public class ParameterMirrorPort extends ParameterPort { 048 049 /** Construct a new input port in the specified container with the 050 * specified name. The specified container 051 * must implement the Actor interface, or an exception will be thrown. 052 * @param container The container. 053 * @param name The name of the port. 054 * @exception IllegalActionException If the port is not of an acceptable 055 * class for the container, or if the container does not implement the 056 * Actor interface. 057 * @exception NameDuplicationException If the name coincides with 058 * a port already in the container. 059 */ 060 public ParameterMirrorPort(ComponentEntity container, String name) 061 throws IllegalActionException, NameDuplicationException { 062 super(container, name); 063 } 064 065 /////////////////////////////////////////////////////////////////// 066 //// public methods //// 067 068 /** Clone the object into the specified workspace. This overrides 069 * the base class to unset the associated port. Users of this 070 * class are responsible for resetting it in their clone methods. 071 * @param workspace The workspace for the new object. 072 * @return A new NamedObj. 073 * @exception CloneNotSupportedException If any of the attributes 074 * cannot be cloned. 075 * @see #exportMoML(java.io.Writer, int, String) 076 */ 077 @Override 078 public Object clone(Workspace workspace) throws CloneNotSupportedException { 079 ParameterMirrorPort result = (ParameterMirrorPort) super.clone( 080 workspace); 081 result._associatedPort = null; 082 return result; 083 } 084 085 /** Return the associated port, or null if there is none. 086 * @return The associated port, or null if there is none. 087 * @see #setAssociatedPort(ParameterMirrorPort) 088 */ 089 public ParameterMirrorPort getAssociatedPort() { 090 return _associatedPort; 091 } 092 093 /** Specify an associated port. Once this is specified, 094 * then any changes made to this port (its name, whether it 095 * is an input or output, and whether it is a multiport) are 096 * mirrored in the associated port, and any changes made in 097 * the associated port are mirrored here. 098 * @param port The associated port. 099 * @see #getAssociatedPort() 100 */ 101 public void setAssociatedPort(ParameterMirrorPort port) { 102 _associatedPort = port; 103 port._associatedPort = this; 104 105 // NOTE: The association is not propagated to derived 106 // objects because we explicitly propagate all the changes. 107 } 108 109 /** Override the base class so that if the container is being 110 * set to null, then the associated port is also deleted 111 * (via a change request). Note that if the container 112 * of this port is changed to something other than null, 113 * there is no reasonable basis for changing the container 114 * of the associated port, so it is left unchanged. 115 * @param container The proposed container. 116 * @exception IllegalActionException If the proposed container is not a 117 * ComponentEntity, doesn't implement Actor, or has no name, 118 * or the port and container are not in the same workspace. Or 119 * it's not null 120 * @exception NameDuplicationException If the container already has 121 * a port with the name of this port. 122 */ 123 @Override 124 public void setContainer(Entity container) 125 throws IllegalActionException, NameDuplicationException { 126 super.setContainer(container); 127 128 if (container == null && _associatedPort != null 129 && _associatedPort.getContainer() != null) { 130 // Use a MoML change request to ensure propagation. 131 // Note that when that change request is executed, 132 // this port will be the associated port, but no 133 // change request will be issued because its container 134 // is already null. 135 MoMLChangeRequest request = new MoMLChangeRequest(this, 136 _associatedPort.getContainer(), 137 "<deletePort name=\"" + _associatedPort.getName() + "\"/>"); 138 _associatedPort.getContainer().requestChange(request); 139 } 140 } 141 142 /** Override the base class to also set the associated port, 143 * if there is one. 144 * @param isInput True to make this an input port. 145 * @exception IllegalActionException If changing the port status is 146 * not permitted. 147 */ 148 @Override 149 public void setInput(boolean isInput) throws IllegalActionException { 150 super.setInput(isInput); 151 152 if (_associatedPort != null && _associatedPort.isInput() != isInput) { 153 // Use a MoML change request to ensure propagation. 154 // Note that when that change request is executed, 155 // this port will be the associated port, but no 156 // change request will be issued because it already 157 // has matching status. 158 String value = isInput ? "true" : "false"; 159 MoMLChangeRequest request = new MoMLChangeRequest(this, 160 _associatedPort.getContainer(), 161 "<property name=\"input\" value=\"" + value + "\"/>"); 162 _associatedPort.getContainer().requestChange(request); 163 } 164 } 165 166 /** Override the base class to also set the associated port, 167 * if there is one. 168 * @param name The name of the port. 169 * @exception IllegalActionException If name cannot be set. 170 * @exception NameDuplicationException If port with the name already exists. 171 */ 172 @Override 173 public void setName(String name) 174 throws IllegalActionException, NameDuplicationException { 175 super.setName(name); 176 177 if (_associatedPort != null 178 && !_associatedPort.getName().equals(name)) { 179 // Use a MoML change request to ensure propagation. 180 // Note that when that change request is executed, 181 // this port will be the associated port, but no 182 // change request will be issued because it already 183 // has matching status. 184 MoMLChangeRequest request = new MoMLChangeRequest(this, 185 _associatedPort, "<rename name=\"" + name + "\"/>"); 186 _associatedPort.requestChange(request); 187 } 188 } 189 190 /////////////////////////////////////////////////////////////////// 191 //// private variables //// 192 193 /** The associated port, if there is one. */ 194 private ParameterMirrorPort _associatedPort = null; 195}