KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > tribe > messages > ChannelMessage


1 /**
2  * Tribe: Group communication library.
3  * Copyright (C) 2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: tribe@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): ______________________.
23  */

24
25 package org.objectweb.tribe.messages;
26
27 import java.io.ByteArrayOutputStream JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.ObjectOutputStream JavaDoc;
30 import java.io.Serializable JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.HashMap JavaDoc;
33
34 import org.objectweb.tribe.channel.ReceiveBuffer;
35 import org.objectweb.tribe.exceptions.NoReceiverException;
36
37 /**
38  * This class defines a ChannelMessage.
39  * <p>
40  * A ChannelMessage is made of chunks, the last chunk of the message containing
41  * the destination key to be used for message routing at reception.
42  *
43  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
44  * @version 1.0
45  */

46 public abstract class ChannelMessage implements Serializable JavaDoc
47 {
48   private Object JavaDoc key; // Message destination key
49
private ArrayList JavaDoc chunks;
50   private transient byte[] messageInBytes = null;
51
52   /**
53    * Creates a new <code>ChannelMessage</code> object
54    *
55    * @param destinationKey receive buffer key for message delivery
56    */

57   public ChannelMessage(Object JavaDoc destinationKey)
58   {
59     chunks = new ArrayList JavaDoc();
60     this.key = destinationKey;
61   }
62
63   /**
64    * Creates a new <code>ChannelMessage</code> object
65    *
66    * @param destinationKey receive buffer key for message delivery
67    * @param numberOfChunks number of chunks in the message if known in advance
68    */

69   public ChannelMessage(Object JavaDoc destinationKey, int numberOfChunks)
70   {
71     chunks = new ArrayList JavaDoc(numberOfChunks);
72     this.key = destinationKey;
73   }
74
75   /**
76    * Adds a chunk to this message
77    *
78    * @param chunk the message chunk to add
79    */

80   public synchronized void addChunk(Serializable JavaDoc chunk)
81   {
82     messageInBytes = null;
83     chunks.add(chunk);
84   }
85
86   /**
87    * Get the whole list of chunks. Warning this is not a copy but the real
88    * message content.
89    *
90    * @return an <code>ArrayList</code> of chunks (Objects).
91    */

92   public ArrayList JavaDoc getChunks()
93   {
94     return chunks;
95   }
96
97   /**
98    * Remove the last chunk.
99    *
100    * @return the last chunk of the chunk list or null if no more chunks are
101    * available.
102    */

103   public synchronized Object JavaDoc removeChunk()
104   {
105     messageInBytes = null;
106     int size = chunks.size();
107     if (size == 0)
108       return null;
109     else
110       return chunks.remove(size - 1);
111   }
112
113   /**
114    * Defines the destination key used for message delivery at the receiving
115    * host. A <code>ReceiveBuffer</code> must has been registered with this
116    * destination key at the receiver end for the message to be delivered.
117    *
118    * @return the destination key
119    */

120   public Object JavaDoc getDestinationKey()
121   {
122     return key;
123   }
124
125   /**
126    * Delivers the message to all receive buffers that are registered to the
127    * message destination key.
128    *
129    * @param receiveBuffers list of destination receive buffers
130    * @throws NoReceiverException if no receive buffer has been registered for
131    * the destination key found in the message
132    */

133   public void deliverMessage(HashMap JavaDoc receiveBuffers) throws NoReceiverException
134   {
135     ArrayList JavaDoc buffers;
136     synchronized (receiveBuffers)
137     {
138       // Get buffers for this gid
139
buffers = (ArrayList JavaDoc) receiveBuffers.get(key);
140     }
141     if (buffers == null)
142       throw new NoReceiverException("No receive buffer to deliver message for "
143           + key);
144
145     // Deliver the message to all buffers
146
// TODO: Use a reader/writer lock instead for better scalability
147
synchronized (buffers)
148     {
149       int size = buffers.size();
150       for (int i = 0; i < size; i++)
151       {
152         ReceiveBuffer buf = (ReceiveBuffer) buffers.get(i);
153         buf.addMessage(this);
154       }
155     }
156   }
157
158   /**
159    * Get a byte array representation of the message. This representation is
160    * computed only once (which means that the message is serialized only once)
161    * but calls to add/remove chunks will force a recompute of the message
162    * representation.
163    *
164    * @return this message as a byte array
165    */

166   public synchronized byte[] getByteArray()
167   {
168     if (messageInBytes == null)
169     {
170       try
171       {
172         ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
173         new ObjectOutputStream JavaDoc(baos).writeObject(this);
174         messageInBytes = baos.toByteArray();
175       }
176       catch (IOException JavaDoc e)
177       {
178         messageInBytes = null;
179         e.printStackTrace();
180       }
181     }
182     return messageInBytes;
183   }
184
185 }
Popular Tags