001/* Refinement for modal models. 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 ptolemy.actor.TypedCompositeActor; 030import ptolemy.kernel.CompositeEntity; 031import ptolemy.kernel.Entity; 032import ptolemy.kernel.Port; 033import ptolemy.kernel.Relation; 034import ptolemy.kernel.util.IllegalActionException; 035import ptolemy.kernel.util.InternalErrorException; 036import ptolemy.kernel.util.NameDuplicationException; 037import ptolemy.kernel.util.Workspace; 038 039/////////////////////////////////////////////////////////////////// 040//// Refinement 041 042/** 043 This typed composite actor supports mirroring of its ports in its container 044 (which is required to be a MultiCompositeActor), which in turn assures 045 mirroring of ports in each of the refinements and the controller. 046 047 @author Edward A. Lee 048 @version $Id$ 049 @since Ptolemy II 5.2 050 @Pt.ProposedRating Yellow (eal) 051 @Pt.AcceptedRating Red (reviewmoderator) 052 */ 053public class Refinement extends TypedCompositeActor { 054 /** Construct a modal controller with a name and a container. 055 * The container argument must not be null, or a 056 * NullPointerException will be thrown. 057 * @param container The container. 058 * @param name The name of this actor. 059 * @exception IllegalActionException If the container is incompatible 060 * with this actor. 061 * @exception NameDuplicationException If the name coincides with 062 * an actor already in the container. 063 */ 064 public Refinement(CompositeEntity container, String name) 065 throws IllegalActionException, NameDuplicationException { 066 super(container, name); 067 068 // The base class identifies the class name as TypedCompositeActor 069 // irrespective of the actual class name. We override that here. 070 setClassName("ptolemy.actor.lib.hoc.Refinement"); 071 } 072 073 /** Construct a Refinement in the specified workspace with 074 * no container and an empty string as a name. You can then change 075 * the name with setName(). If the workspace argument is null, then 076 * use the default workspace. 077 * @param workspace The workspace that will list the refinement. 078 */ 079 public Refinement(Workspace workspace) { 080 super(workspace); 081 082 // The base class identifies the class name as TypedCompositeActor 083 // irrespective of the actual class name. We override that here. 084 setClassName("ptolemy.actor.lib.hoc.Refinement"); 085 } 086 087 /////////////////////////////////////////////////////////////////// 088 //// public methods //// 089 090 /** Create a new port with the specified name in the container of 091 * this refinement, which in turn creates a port in this refinement 092 * all other refinements, and the controller. 093 * This method is write-synchronized on the workspace. 094 * @param name The name to assign to the newly created port. 095 * @return The new port. 096 * @exception NameDuplicationException If the entity already has a port 097 * with the specified name. 098 */ 099 @Override 100 public Port newPort(String name) throws NameDuplicationException { 101 try { 102 _workspace.getWriteAccess(); 103 104 if (_mirrorDisable || getContainer() == null) { 105 // Have already called newPort() in the container. 106 // This time, process the request. 107 RefinementPort port = new RefinementPort(this, name); 108 109 // NOTE: Changed RefinementPort so mirroring 110 // is enabled by default. This means mirroring 111 // will occur during MoML parsing, but this 112 // is harmless. EAL 12/04. 113 // port._mirrorDisable = false; 114 // Create the appropriate links. 115 MultiCompositeActor container = (MultiCompositeActor) getContainer(); 116 117 if (container != null) { 118 String relationName = name + "Relation"; 119 Relation relation = container.getRelation(relationName); 120 121 if (relation == null) { 122 relation = container.newRelation(relationName); 123 124 Port containerPort = container.getPort(name); 125 containerPort.link(relation); 126 } 127 128 port.link(relation); 129 } 130 131 return port; 132 } else { 133 _mirrorDisable = true; 134 ((MultiCompositeActor) getContainer()).newPort(name); 135 return getPort(name); 136 } 137 } catch (IllegalActionException ex) { 138 // This exception should not occur, so we throw a runtime 139 // exception. 140 throw new InternalErrorException( 141 "Refinement.newPort: Internal error: " + ex.getMessage()); 142 } finally { 143 _mirrorDisable = false; 144 _workspace.doneWriting(); 145 } 146 } 147 148 /** Control whether adding a port should be mirrored in the modal 149 * model and the mode controller. 150 * This is added to allow control by the UI. 151 * @param disable True if mirroring should not occur. 152 */ 153 public void setMirrorDisable(boolean disable) { 154 _mirrorDisable = disable; 155 } 156 157 /////////////////////////////////////////////////////////////////// 158 //// protected methods //// 159 160 /** Override the base class to ensure that the proposed container 161 * is a MultiCompositeActor or null. 162 * @param container The proposed container. 163 * @exception IllegalActionException If the proposed container is not a 164 * TypedActor, or if the base class throws it. 165 */ 166 protected void _checkContainer(Entity container) 167 throws IllegalActionException { 168 if (!(container instanceof MultiCompositeActor) && container != null) { 169 throw new IllegalActionException(container, this, 170 "Refinement can only be contained by " 171 + "MultiCompositeActor objects."); 172 } 173 } 174 175 /////////////////////////////////////////////////////////////////// 176 //// protected variables //// 177 // These are protected to be accessible to MultiCompositeActor. 178 179 /** Indicator that we are processing a newPort request. */ 180 protected boolean _mirrorDisable = false; 181}