001/* This actor implements a receiver that adds functionality to another receiver. 002 003@Copyright (c) 2011-2014 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 */ 030 031package ptolemy.actor; 032 033import java.util.List; 034 035import ptolemy.data.Token; 036import ptolemy.kernel.util.IllegalActionException; 037 038/** A receiver that delegates to another receiver all method calls except 039 * {@link #put(Token)} (and its variants), for which it delegates to a 040 * communication aspect. The delegated receiver and the communication aspect are 041 * specified as constructor arguments. 042 * <p> 043 * This can be used, for example, when multiple communication links share 044 * resources. The communication aspect can, for example, delay the delivery 045 * of tokens to the delegated receiver to take into account resource 046 * availability. It could also be used to make a centralized record 047 * of various communications. 048 * <p> 049 * Subclasses of this receiver may also intervene on method calls other 050 * than put(). 051 * @author Patricia Derler, Edward A. Lee 052 * @version $Id$ 053 * @since Ptolemy II 10.0 054 * @Pt.ProposedRating Yellow (derler) 055 * @Pt.AcceptedRating Red (derler) 056 */ 057public class IntermediateReceiver extends AbstractReceiver { 058 059 /** Construct an intermediate receiver with no container that wraps the 060 * specified receiver using the specified communication aspect. 061 * @param aspect The communication aspect that receives tokens received by this receiver. 062 * @param receiver The receiver wrapped by this intermediate receiver. 063 */ 064 public IntermediateReceiver(CommunicationAspect aspect, Receiver receiver) { 065 _receiver = receiver; 066 communicationAspect = aspect; 067 } 068 069 /** Construct an intermediate receiver with no container that wraps the 070 * specified receiver using the specified communication aspect. 071 * @param aspect The communication aspect that receives tokens received by this receiver. 072 * @param receiver The receiver wrapped by this intermediate receiver. 073 * @param port The port wrapped by this intermediate receiver 074 */ 075 public IntermediateReceiver(CommunicationAspect aspect, Receiver receiver, 076 IOPort port) { 077 _receiver = receiver; 078 communicationAspect = aspect; 079 _port = port; 080 } 081 082 /////////////////////////////////////////////////////////////////// 083 //// public variables //// 084 085 /** communication aspect that receives tokens from this receiver. */ 086 public CommunicationAspect communicationAspect; 087 088 /** The source actor that sent a token to this receiver. */ 089 public Actor source; 090 091 /////////////////////////////////////////////////////////////////// 092 //// public methods //// 093 094 /** Reset the communication aspect and the receiver that we delegate to. 095 */ 096 @Override 097 public void clear() throws IllegalActionException { 098 communicationAspect.reset(); 099 } 100 101 /** Delegate to the internal receiver and return whatever it returns. 102 * @return A list of instances of Token. 103 * @exception IllegalActionException Always thrown in this base class. 104 */ 105 @Override 106 public List<Token> elementList() throws IllegalActionException { 107 return _receiver.elementList(); 108 } 109 110 /** Delegate to the internal receiver and return whatever it returns. 111 * @exception NoTokenException If the delegated receiver throws it. 112 */ 113 @Override 114 public Token get() throws NoTokenException { 115 return _receiver.get(); 116 } 117 118 /** Delegate to the internal receiver and return whatever it returns. 119 * @return The port containing the internal receiver. 120 * @see #setContainer(IOPort) 121 */ 122 @Override 123 public IOPort getContainer() { 124 return _receiver.getContainer(); 125 } 126 127 /** Delegate to the internal receiver and return whatever it returns. 128 */ 129 @Override 130 public boolean hasRoom() { 131 return _receiver.hasRoom(); 132 } 133 134 /** Delegate to the internal receiver and return whatever it returns. 135 */ 136 @Override 137 public boolean hasRoom(int numberOfTokens) { 138 return _receiver.hasRoom(numberOfTokens); 139 } 140 141 /** Delegate to the internal receiver and return whatever it returns. 142 */ 143 @Override 144 public boolean hasToken() { 145 return _receiver.hasToken(); 146 } 147 148 /** Delegate to the internal receiver and return whatever it returns. 149 */ 150 @Override 151 public boolean hasToken(int numberOfTokens) { 152 return _receiver.hasToken(numberOfTokens); 153 } 154 155 /** Delegate to the internal receiver and return whatever it returns. 156 */ 157 @Override 158 public boolean isKnown() { 159 return _receiver.isKnown(); 160 } 161 162 /** Forward the specified token to communication aspect specified in 163 * the constructor. 164 */ 165 @Override 166 public void put(Token token) 167 throws NoRoomException, IllegalActionException { 168 communicationAspect.sendToken(this, _receiver, token); 169 ((Actor) _receiver.getContainer().getContainer()).getDirector() 170 .notifyTokenSentToCommunicationAspect(); 171 } 172 173 /** Reset this receiver to its initial state, which in this base 174 * class is the same as calling clear(). 175 * @exception IllegalActionException If reset() is not supported by 176 * the domain. 177 */ 178 @Override 179 public void reset() throws IllegalActionException { 180 super.reset(); 181 _receiver.reset(); 182 } 183 184 /** Set the container of the internal receiver. 185 * @param port The container. 186 * @exception IllegalActionException If the container is not of 187 * an appropriate subclass of IOPort. Not thrown in this base class, 188 * but may be thrown in derived classes. 189 * @see #getContainer() 190 */ 191 @Override 192 public void setContainer(IOPort port) throws IllegalActionException { 193 _receiver.setContainer(port); 194 } 195 196 /////////////////////////////////////////////////////////////////// 197 //// protected variables //// 198 199 /** Target receiver that is wrapped by this intermediate receiver. */ 200 public Receiver _receiver; 201 202 /** The port. */ 203 protected IOPort _port; 204}