001/* A composite that contain one actor and mirror the ports and parameters of that actor. 002 003 Copyright (c) 2007-2015 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.actor.lib.hoc; 029 030import ptolemy.actor.parameters.ParameterMirrorPort; 031import ptolemy.actor.parameters.ParameterPort; 032import ptolemy.kernel.ComponentPort; 033import ptolemy.kernel.CompositeEntity; 034import ptolemy.kernel.Port; 035import ptolemy.kernel.util.IllegalActionException; 036import ptolemy.kernel.util.NameDuplicationException; 037import ptolemy.kernel.util.Workspace; 038 039/////////////////////////////////////////////////////////////////// 040//// MirrorComposite 041 042/** 043 A composite that contains one actor and mirrors the ports and 044 parameters of that actor. This is identical to the base class 045 except that it requires its ports to be of type MirrorPort or 046 ParameterMirrorPort. That is, every port of this composite is 047 mirrored in the inside model, whereas the base class tolerates ports 048 that are not mirrored (typically instances of TypedIOPort). 049 050 @author Ilge Akkaya, Edward A. Lee 051 @version $Id$ 052 @since Ptolemy II 6.1 053 @Pt.ProposedRating Yellow (eal) 054 @Pt.AcceptedRating Red (neuendor) 055 */ 056public class MirrorComposite extends ReflectComposite { 057 058 /** Create an actor with a name and a container. 059 * The container argument must not be null, or a 060 * NullPointerException will be thrown. This actor will use the 061 * workspace of the container for synchronization and version counts. 062 * If the name argument is null, then the name is set to the empty string. 063 * Increment the version of the workspace. 064 * @param container The container actor. 065 * @param name The name of this actor. 066 * @exception IllegalActionException If the container is incompatible 067 * with this actor. 068 * @exception NameDuplicationException If the name coincides with 069 * an actor already in the container. 070 */ 071 public MirrorComposite(CompositeEntity container, String name) 072 throws IllegalActionException, NameDuplicationException { 073 super(container, name); 074 _init(); 075 } 076 077 /** Construct a MirrorComposite in the specified workspace with 078 * no container and an empty string as a name. You can then change 079 * the name with setName(). If the workspace argument is null, then 080 * use the default workspace. You should set the local director or 081 * executive director before attempting to send data to the actor 082 * or to execute it. Add the actor to the workspace directory. 083 * Increment the version number of the workspace. 084 * @param workspace The workspace that will list the actor. 085 */ 086 public MirrorComposite(Workspace workspace) { 087 super(workspace); 088 _init(); 089 } 090 091 /** Create an actor with a name and a container that optionally 092 * mirrors the ports that are instances of ParameterPort. 093 * The container argument must not be null, or a 094 * NullPointerException will be thrown. This actor will use the 095 * workspace of the container for synchronization and version counts. 096 * If the name argument is null, then the name is set to the empty string. 097 * Increment the version of the workspace. 098 * @param container The container actor. 099 * @param name The name of this actor. 100 * @param mirrorParameterPorts If false, then ports that are instances of 101 * ParameterPort are not mirrored. 102 * @exception IllegalActionException If the container is incompatible 103 * with this actor. 104 * @exception NameDuplicationException If the name coincides with 105 * an actor already in the container. 106 */ 107 public MirrorComposite(CompositeEntity container, String name, 108 boolean mirrorParameterPorts) 109 throws IllegalActionException, NameDuplicationException { 110 super(container, name, mirrorParameterPorts); 111 _init(); 112 } 113 114 /////////////////////////////////////////////////////////////////// 115 //// protected methods //// 116 117 /** Add a port to this actor. This overrides the base class to 118 * throw an exception if the port is not an instance of MirrorPort 119 * or ParameterMirrorPort. 120 * @param port The TypedIOPort to add to this actor. 121 * @exception IllegalActionException If the port is not an instance 122 * of IteratePort, or the port has no name. 123 * @exception NameDuplicationException If the port name collides with a 124 * name already in the actor. 125 */ 126 @Override 127 protected void _addPort(Port port) 128 throws IllegalActionException, NameDuplicationException { 129 130 if (!(port instanceof MirrorPort 131 || port instanceof ParameterMirrorPort)) { 132 throw new IllegalActionException(this, 133 "MirrorComposite ports are required to be " 134 + "instances of MirrorPort"); 135 } 136 137 super._addPort(port); 138 } 139 140 private void _init() { 141 setClassName("ptolemy.actor.lib.hoc.MirrorComposite"); 142 } 143 144 /** Return true if the specified inside port should be mirrored. 145 * This overrides the base class to return true for all ports 146 * unless the port is an instance of ParameterPort and the 147 * constructor specified that parameter ports should not be mirrored. 148 * @param insidePort The port that may be mirrored. 149 * @return True if the inside port should be mirrored. 150 */ 151 @Override 152 protected boolean _mirrorPort(ComponentPort insidePort) { 153 // do not mirror ports that are not instances of MirrorPort 154 if (!_mirrorParameterPorts && insidePort instanceof ParameterPort) { 155 return false; 156 } 157 return true; 158 } 159 160 /////////////////////////////////////////////////////////////////// 161 //// inner classes //// 162 163 /////////////////////////////////////////////////////////////////// 164 //// MirrorCompositeContents 165 166 /** This is a specialized composite actor for use in MirrorComposite. 167 * In particular, it ensures that if ports are added or deleted 168 * locally, then corresponding ports will be added or deleted 169 * in the container. That addition will result in appropriate 170 * connections being made. 171 */ 172 public static class MirrorCompositeContents 173 extends ReflectCompositeContents { 174 // NOTE: This has to be a static class so that MoML can 175 // instantiate it. 176 177 /** Construct an actor with a name and a container. 178 * @param container The container. 179 * @param name The name of this actor. 180 * @exception IllegalActionException If the container is incompatible 181 * with this actor. 182 * @exception NameDuplicationException If the name coincides with 183 * an actor already in the container. 184 */ 185 public MirrorCompositeContents(CompositeEntity container, String name) 186 throws IllegalActionException, NameDuplicationException { 187 super(container, name); 188 } 189 190 /** Add a port to this actor. This overrides the base class to 191 * add a corresponding port to the container using a change 192 * request, if that port does not already exist. 193 * @param port The TypedIOPort to add to this actor. 194 * @exception IllegalActionException If the port is not an instance of 195 * MirrorPort, or the port has no name. 196 * @exception NameDuplicationException If the port name 197 * collides with a name already in the actor. 198 */ 199 @Override 200 protected void _addPort(final Port port) 201 throws IllegalActionException, NameDuplicationException { 202 203 if (!(port instanceof MirrorPort 204 || port instanceof ParameterMirrorPort)) { 205 throw new IllegalActionException(this, 206 "Ports in MirrorComposiMirrorCompositeContentsite must be MirrorPort."); 207 } 208 209 super._addPort(port); 210 } 211 } 212}