KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jegg > impl > PortImpl


1 /*
2  * Copyright (c) 2004, Bruce Lowery
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * - Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * - Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * - Neither the name of JEGG nor the names of its contributors may be used
14  * to endorse or promote products derived from this software without
15  * specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */

29 package jegg.impl;
30
31 import java.util.Collection JavaDoc;
32 import java.util.HashSet JavaDoc;
33 import java.util.Iterator JavaDoc;
34
35 import jegg.Message;
36 import jegg.PortException;
37 import jegg.Port;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42 /**
43  * Used to deliver a message to an egg. Each Egg
44  * instance has just one message port instance that other eggs can use to
45  * send it messages. Any message that is written to an egg port will be
46  * delivered, asynchronously, to the egg that the port belongs to.
47  * <p>
48  * An egg can publish its port in the JEgg port registry so that other
49  * eggs will be able to send it messages (see {@link jegg.Egg.publishPort(Port)
50  * Egg.publishPort()}).
51  */

52 public final class PortImpl implements Port
53 {
54     /** Class logger */
55     private static final Log LOG = LogFactory.getLog(PortImpl.class);
56     
57     private EggInfo _info = null;
58     
59     /** The egg that this port belongs to. */
60     private EggShell _owner;
61     
62     /** Other ports connected to this one */
63     private final Collection JavaDoc _otherPorts = new HashSet JavaDoc();
64     
65     PortImpl (final EggInfo info)
66     {
67         super();
68         _info = info;
69     }
70     /**
71      * Construct a port for the specified egg.
72      * @param egg the egg that will own the new port.
73      */

74     PortImpl (final EggShell egg)
75     {
76         super();
77         _owner = egg;
78         _owner.setPort(this);
79     }
80     
81     public Class JavaDoc[] getInterface()
82     {
83         if (null == _owner)
84         {
85             try
86             {
87                 instantiate();
88             }
89             catch (HatchException e)
90             {
91                 RuntimeException JavaDoc t = new IllegalStateException JavaDoc("Can't create egg "+_info.getEggName());
92                 t.initCause(e);
93                 throw t;
94             }
95         }
96         return _owner.getInterface();
97     }
98     
99     public Object JavaDoc getId()
100     {
101         if (null == _owner)
102         {
103             try
104             {
105                 instantiate();
106             }
107             catch (HatchException e)
108             {
109                 RuntimeException JavaDoc t = new IllegalStateException JavaDoc("Can't create egg "+_info.getEggName());
110                 t.initCause(e);
111                 throw t;
112             }
113         }
114         return _owner.getId();
115     }
116     
117     /**
118      * Deliver an object as a message to the egg that owns
119      * this port.
120      * @param o the object to send to this port's owner. The
121      * object will be delivered wrapped in a Message instance.
122      */

123     public final void send(final Object JavaDoc o) throws PortException
124     {
125         if (null == _owner)
126         {
127             try
128             {
129                 instantiate();
130             }
131             catch (HatchException e)
132             {
133                 throw new PortException("Can't create egg "+_info.getEggName(), e);
134             }
135         }
136         
137         send(_owner.createMessage(o));
138     }
139
140     /**
141      * Deliver a message to the egg that owns this port.
142      * @param o the object to deliver to the egg.
143      * @param p the prioroty of the message.
144      */

145     public final void send(final Message m) throws PortException
146     {
147         if (null == _owner)
148         {
149             try
150             {
151                 instantiate();
152             }
153             catch (HatchException e)
154             {
155                 throw new PortException("Can't create egg "+_info.getEggName(), e);
156             }
157         }
158         _owner.enqueue(m);
159     }
160     
161     /**
162      * Deliver a message to all clients connected to this
163      * port. The message will be send with a medium priority
164      * level assigned to it.
165      * @param message
166      */

167     final void broadcast(final Object JavaDoc msg)
168     {
169         broadcast(msg,Priority.MEDIUM);
170     }
171     
172     /**
173      * Deliver a message with specific priority to all
174      * clients connected to this port.
175      * @param msg
176      * @param p
177      */

178     final void broadcast(final Object JavaDoc msg, final Priority p)
179     {
180         MessageImpl message = new MessageImpl(msg,this,p);
181         for (Iterator JavaDoc it = _otherPorts.iterator(); it.hasNext(); )
182         {
183             PortImpl po = (PortImpl) it.next();
184             try
185             {
186                 po.send(message);
187             }
188             catch (PortException e)
189             {
190                 LOG.error("Failed to broadcast message to port "+po+": ", e);
191             }
192         }
193     }
194     
195     /**
196      * Add a port to the list of ports that broadcast messages will
197      * be sent to.
198      * @param port xx
199      */

200     public final void connect (final Port port)
201     {
202         _otherPorts.add(port);
203     }
204     
205     /**
206      * Remove a connected port.
207      * @param client
208      */

209     public final void disconnect(final Port port)
210     {
211         _otherPorts.remove(port);
212     }
213     
214     /**
215      * Get list of ports connected to this one
216      */

217     final Port[] getConnectedPorts()
218     {
219         return (Port[]) _otherPorts.toArray(new Port[_otherPorts.size()]);
220     }
221     
222     void setOwner(EggShell owner)
223     {
224         if (LOG.isDebugEnabled())
225             LOG.debug("setOwner("+owner+")");
226         
227         _owner = owner;
228     }
229     
230     private void instantiate() throws HatchException
231     {
232         if (null != _owner) {return;}
233         
234         HenHouse.getHenHouse().hatch(this._info, true, true);
235         _owner = _info.getEgg();
236     }
237     
238 } // END OF CLASS Port
239
Popular Tags