001/* Composite actor with multiple refinements. 002 003 Copyright (c) 2006-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 */ 027package ptolemy.actor.lib.hoc; 028 029import java.util.Iterator; 030import java.util.Set; 031 032import ptolemy.actor.IOPort; 033import ptolemy.actor.TypedCompositeActor; 034import ptolemy.kernel.CompositeEntity; 035import ptolemy.kernel.Port; 036import ptolemy.kernel.util.IllegalActionException; 037import ptolemy.kernel.util.InternalErrorException; 038import ptolemy.kernel.util.NameDuplicationException; 039import ptolemy.kernel.util.Workspace; 040 041/////////////////////////////////////////////////////////////////// 042//// MultiCompositeActor 043 044/** 045 A composite actor that can have several refinements. 046 047 @see Refinement 048 @author Edward A. Lee 049 @version $Id$ 050 @since Ptolemy II 5.2 051 @Pt.ProposedRating Red (eal) 052 @Pt.AcceptedRating Red (reviewmoderator) 053 */ 054public class MultiCompositeActor extends TypedCompositeActor { 055 /** Construct a composite actor in the specified workspace with 056 * no container and an empty string as a name. You can then change 057 * the name with setName(). If the workspace argument is null, then 058 * use the default workspace. 059 * @param workspace The workspace that will list the actor. 060 * @exception IllegalActionException If the name has a period in it, or 061 * the director is not compatible with the specified container. 062 * @exception NameDuplicationException If the container already contains 063 * an entity with the specified name. 064 */ 065 public MultiCompositeActor(Workspace workspace) 066 throws IllegalActionException, NameDuplicationException { 067 super(workspace); 068 _init(); 069 } 070 071 /** Construct a composite actor with a name and a container. 072 * The container argument must not be null, or a 073 * NullPointerException will be thrown. 074 * @param container The container. 075 * @param name The name of this actor. 076 * @exception IllegalActionException If the container is incompatible 077 * with this actor. 078 * @exception NameDuplicationException If the name coincides with 079 * an actor already in the container. 080 */ 081 public MultiCompositeActor(CompositeEntity container, String name) 082 throws IllegalActionException, NameDuplicationException { 083 super(container, name); 084 _init(); 085 } 086 087 /////////////////////////////////////////////////////////////////// 088 //// public methods //// 089 090 /** Mirror a set of container ports in the refinement. 091 * @param refinement The refinement in which to create ports. 092 * @param portsToMirror The ports to mirror in the refinement. 093 * @exception IllegalActionException If the port cannot be set 094 * to a multiport or to an output. 095 * @exception NameDuplicationException If a port cannot be added 096 * to the the refinement. 097 */ 098 public static void mirrorContainerPortsInRefinement(Refinement refinement, 099 Set<Port> portsToMirror) 100 throws IllegalActionException, NameDuplicationException { 101 102 for (Port port : portsToMirror) { 103 try { 104 refinement.setMirrorDisable(true); 105 Port newPort = refinement.newPort(port.getName()); 106 if (newPort instanceof RefinementPort 107 && port instanceof IOPort) { 108 try { 109 ((RefinementPort) newPort).setMirrorDisable(true); 110 111 if (((IOPort) port).isInput()) { 112 ((RefinementPort) newPort).setInput(true); 113 } 114 115 if (((IOPort) port).isOutput()) { 116 ((RefinementPort) newPort).setOutput(true); 117 } 118 119 if (((IOPort) port).isMultiport()) { 120 ((RefinementPort) newPort).setMultiport(true); 121 } 122 } finally { 123 ((RefinementPort) newPort).setMirrorDisable(false); 124 } 125 } 126 } finally { 127 refinement.setMirrorDisable(false); 128 } 129 } 130 } 131 132 /** Create a new port with the specified name in this entity 133 * and all the refinements. Link these ports so that 134 * if the new port is set to be an input, output, or multiport, then 135 * the change is mirrored in the other ports. The new port will be 136 * an instance of MultiCompositePort, which extends TypedIOPort. 137 * This method is write-synchronized on the workspace, and increments 138 * its version number. 139 * @param name The name to assign to the newly created port. 140 * @return The new port. 141 * @exception NameDuplicationException If the entity already has a port 142 * with the specified name. 143 */ 144 @Override 145 public Port newPort(String name) throws NameDuplicationException { 146 try { 147 _workspace.getWriteAccess(); 148 149 MultiCompositePort port = new MultiCompositePort(this, name); 150 151 // Create mirror ports. 152 Iterator entities = entityList(Refinement.class).iterator(); 153 while (entities.hasNext()) { 154 Refinement entity = (Refinement) entities.next(); 155 if (entity.getPort(name) == null) { 156 try { 157 entity._mirrorDisable = true; 158 entity.newPort(name); 159 } finally { 160 entity._mirrorDisable = false; 161 } 162 } 163 } 164 return port; 165 } catch (IllegalActionException ex) { 166 // This exception should not occur, so we throw a runtime 167 // exception. 168 throw new InternalErrorException( 169 "MultiCompositeActor.newPort(): Internal error: " 170 + ex.getMessage()); 171 } finally { 172 _workspace.doneWriting(); 173 } 174 } 175 176 /////////////////////////////////////////////////////////////////// 177 //// private methods //// 178 179 /** Initialize the model. */ 180 private void _init() { 181 // The base class identifies the class name as TypedCompositeActor 182 // irrespective of the actual class name. We override that here. 183 setClassName("ptolemy.actor.lib.hoc.MultiCompositeActor"); 184 185 } 186}