001/* 002 * Copyright (c) 2005-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.kepler.sms; 031 032import java.util.Iterator; 033import java.util.Vector; 034 035import ptolemy.actor.IOPort; 036import ptolemy.actor.TypedIOPort; 037import ptolemy.data.type.BaseType; 038import ptolemy.data.type.RecordType; 039import ptolemy.data.type.Type; 040import ptolemy.kernel.util.IllegalActionException; 041import ptolemy.kernel.util.NameDuplicationException; 042import ptolemy.kernel.util.NamedObj; 043 044/** 045 * A compoiste port is a virtual port that encapsulates a set of underlying 046 * ports (both ptolemy ports and other virtual ports). A composite port (and 047 * virtual ports in general) can be annotated using semantic types. For example, 048 * given an actor with a 'lat' and 'lon' port, a port generalization 'pg' can be 049 * constructed that encapsulates both 'lat' and 'lon'; and a semantic type such 050 * as "Location" can be assigned to 'pg', stating that 'lat' and 'lon' values 051 * combined form a location value. 052 * <p> 053 * A compoiste port may <b>only</b> be contained within an entity (e.g., an 054 * actor). A virtual port must have a name. 055 * 056 * @author Shawn Bowers 057 * @created June 16, 2005 058 */ 059 060public class KeplerCompositeIOPort extends KeplerVirtualIOPort { 061 062 /** 063 * Constructor 064 * 065 * @param container 066 * Description of the Parameter 067 * @param name 068 * The value of the property 069 * @exception IllegalActionException 070 * Description of the Exception 071 * @exception NameDuplicationException 072 * Description of the Exception 073 */ 074 public KeplerCompositeIOPort(NamedObj container, String name) 075 throws IllegalActionException, NameDuplicationException { 076 super(container, name); 077 if (name == null) { 078 String msg = "Port generalization must have a non-null name"; 079 throw new IllegalActionException(this, msg); 080 } 081 } 082 083 public void setName(String name) throws IllegalActionException, 084 NameDuplicationException { 085 if (name == null) { 086 String msg = "Port generalization must have a non-null name"; 087 throw new IllegalActionException(this, msg); 088 } 089 super.setName(name); 090 } 091 092 /** 093 * @return The list of encapsulated port references for this port 094 * generalization. Each returned reference can be called to obtain 095 * the actual port. 096 */ 097 public Vector getEncapsulatedPortReferences() { 098 return new Vector(attributeList(KeplerIOPortReference.class)); 099 } 100 101 /** 102 * Assigns the given ptolemy port reference to the current set of 103 * encapsulated ports. Creates a new reference for the port and adds to the 104 * generalization. 105 * 106 * @param port 107 * The ptolemy port to encapsulate. 108 */ 109 public void addEncapsulatedPort(IOPort port) throws IllegalActionException, 110 NameDuplicationException { 111 _addPort(port); 112 } 113 114 /** 115 * Assigns the given virtual port to the current set of encapsulated ports. 116 * This operation creates a reference to the given port. 117 * 118 * @param vport 119 * The virtual port to encapsulate. 120 */ 121 public void addEncapsulatedPort(KeplerVirtualIOPort port) 122 throws IllegalActionException, NameDuplicationException { 123 _addPort(port); 124 } 125 126 /** 127 * 128 */ 129 private void _addPort(Object obj) throws IllegalActionException, 130 NameDuplicationException { 131 // adding a ptolemy port 132 if (obj instanceof IOPort) { 133 IOPort port = (IOPort) obj; 134 // make sure the port has the same direction 135 if (!_validDirection(port)) { 136 String msg = "error adding port '" + port.getName() 137 + "' to port generalization '" + getName() 138 + "': mismatched input/output directions"; 139 throw new IllegalActionException(this, msg); 140 } 141 String refname = "_" + port.getName() + "_ref"; 142 KeplerIOPortReference portRef = new KeplerIOPortReference(this, 143 refname); 144 portRef.setPort(port); 145 } 146 // adding a kepler virtual port 147 else if (obj instanceof KeplerVirtualIOPort) { 148 KeplerVirtualIOPort port = (KeplerVirtualIOPort) obj; 149 // make sure the port has the same direction 150 if (!_validDirection(port)) { 151 String msg = "error adding port '" + port.getName() 152 + "' to port generalization '" + getName() 153 + "': mismatched input/output directions"; 154 throw new IllegalActionException(this, msg); 155 } 156 String refname = "_" + port.getName() + "_ref"; 157 KeplerVirtualIOPortReference portRef = new KeplerVirtualIOPortReference( 158 this, refname); 159 portRef.setPort(port); 160 } 161 162 } 163 164 /** 165 * 166 */ 167 private boolean _validDirection(IOPort port) { 168 if (_direction == null) { 169 _direction = port.isOutput() ? _OUTPUT : _INPUT; 170 return true; 171 } 172 173 if (port.isOutput() && _direction.equals(_INPUT)) 174 return false; 175 else if (port.isInput() && _direction.equals(_OUTPUT)) 176 return false; 177 178 return true; 179 } 180 181 /** 182 * 183 */ 184 private boolean _validDirection(KeplerVirtualIOPort port) { 185 if (_direction == null) { 186 _direction = port.isOutput() ? _OUTPUT : _INPUT; 187 return true; 188 } 189 190 // get the virtual port direction 191 if (port.isOutput() && _direction.equals(_INPUT)) 192 return false; 193 else if (port.isInput() && _direction.equals(_OUTPUT)) 194 return false; 195 196 return true; 197 } 198 199 /** 200 * 201 */ 202 public boolean isOutput() { 203 return _OUTPUT.equals(_direction); 204 } 205 206 /** 207 * 208 */ 209 public boolean isInput() { 210 return _INPUT.equals(_direction); 211 } 212 213 /** 214 * Returns a record type of the encapsulated ports, where the labels are the 215 * port names. 216 */ 217 public Type getType() { 218 Vector<String> labels = new Vector<String>(); 219 Vector<Type> types = new Vector<Type>(); 220 // get all the ports and add their names and types 221 for (Iterator iter = getEncapsulatedPortReferences().iterator(); iter 222 .hasNext();) { 223 Object ref = iter.next(); 224 // it should be a port reference 225 if (ref instanceof KeplerIOPortReference) { 226 Object obj = ((KeplerIOPortReference) ref).getPort(); 227 // it has a type 228 if (obj instanceof TypedIOPort) { 229 TypedIOPort port = (TypedIOPort) obj; 230 String label = port.getName(); 231 labels.add(label); 232 Type type = port.getType() == null ? BaseType.UNKNOWN 233 : port.getType(); 234 types.add(type); 235 } 236 // it doesn't have a type, use unknown type 237 else if (obj instanceof IOPort) { 238 IOPort port = (IOPort) obj; 239 String label = port.getName(); 240 labels.add(label); 241 types.add(BaseType.UNKNOWN); 242 } 243 // it is a virtual port 244 else if (obj instanceof KeplerVirtualIOPort) { 245 KeplerVirtualIOPort port = (KeplerVirtualIOPort) obj; 246 String label = port.getName(); 247 labels.add(label); 248 Type type = port.getType() == null ? BaseType.UNKNOWN 249 : port.getType(); 250 types.add(type); 251 } 252 } 253 } 254 255 String[] recLabels = new String[labels.size()]; 256 Type[] recTypes = new Type[types.size()]; 257 int i = 0; 258 for (Iterator<String> iter = labels.iterator(); iter.hasNext(); i++) 259 recLabels[i] = iter.next(); 260 i = 0; 261 for (Iterator<Type> iter = types.iterator(); iter.hasNext(); i++) 262 recTypes[i] = iter.next(); 263 return new RecordType(recLabels, recTypes); 264 } 265 266 /** 267 * 268 */ 269 public String toString() { 270 return getName(); 271 } 272 273 /** private members */ 274 275 private String _direction = null; 276 private String _OUTPUT = "output"; 277 private String _INPUT = "input"; 278 279} // KeplerCompositeIOPort