KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > dream > message > manager > MessageManagerImpl


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

24
25 package org.objectweb.dream.message.manager;
26
27 import java.util.ArrayList JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32
33 import org.objectweb.dream.AbstractComponent;
34 import org.objectweb.dream.message.AbstractExtensibleMessage;
35 import org.objectweb.dream.message.Chunk;
36 import org.objectweb.dream.message.ChunkAlreadyExistsException;
37 import org.objectweb.dream.message.ChunkType;
38 import org.objectweb.dream.message.ChunkTypeImpl;
39 import org.objectweb.dream.message.ExtensibleMessage;
40 import org.objectweb.dream.message.ExtensibleMessageImpl;
41 import org.objectweb.dream.message.ExtensibleMessageNC;
42 import org.objectweb.dream.message.ExtensibleMessageNCImpl;
43 import org.objectweb.dream.message.Message;
44 import org.objectweb.dream.message.MessageAlreadyExistException;
45 import org.objectweb.dream.message.MessageReferenceCounter;
46 import org.objectweb.dream.message.MessageType;
47 import org.objectweb.dream.message.MessageTypeNC;
48 import org.objectweb.dream.pool.ObjectPool;
49 import org.objectweb.fractal.api.NoSuchInterfaceException;
50 import org.objectweb.fractal.api.control.IllegalBindingException;
51 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
52 import org.objectweb.util.monolog.api.BasicLevel;
53
54 /**
55  * Basic implementation of a message manager.
56  */

57 public class MessageManagerImpl extends AbstractComponent
58     implements
59       MessageManager,
60       MessageManagerAttributeController
61 {
62
63   // ---------------------------------------------------------------------------
64
// Attribute field
65
// ---------------------------------------------------------------------------
66

67   // the id of this message manager
68
short id = -1;
69
70   // ---------------------------------------------------------------------------
71
// Client interfaces
72
// ---------------------------------------------------------------------------
73

74   /**
75    * The name of the optional client interface used to pool
76    * {@link ExtensibleMessage }instances.
77    */

78   public static final String JavaDoc EXTENSIBLE_MESSAGE_POOL_OPT_ITF_NAME = "extensible-message-pool";
79
80   /**
81    * The name of the optional client interface used to pool
82    * {@link ExtensibleMessageNC }instances.
83    */

84   public static final String JavaDoc EXTENSIBLE_MESSAGE_NC_POOL_OPT_ITF_NAME = "extensible-message-NC-pool";
85
86   /**
87    * The name of the collection interface used to pool chunk instances
88    */

89   public static final String JavaDoc CHUNK_POOL_COLLECTION_ITF_NAME = "chunk-pool";
90
91   protected ObjectPool extensibleMessagePoolOptItf = null;
92   protected ObjectPool extensibleMessageNCPoolOptItf = null;
93
94   protected Map JavaDoc chunkPoolItfs = null;
95   protected List JavaDoc unknownChunkPools = null;
96
97   // ---------------------------------------------------------------------------
98
// Implementation of the MessageManager interface
99
// ---------------------------------------------------------------------------
100

101   /**
102    * @see MessageManager#createMessage(MessageType)
103    */

104   public Message createMessage(MessageType type) throws UnknownChunkTypeError
105   {
106     ExtensibleMessage msg;
107     Iterator JavaDoc iterator;
108     if (type instanceof MessageTypeNC)
109     {
110       ExtensibleMessageNC message = createExtensibleMessageNC();
111       msg = message;
112       MessageTypeNC typeNC = (MessageTypeNC) type;
113
114       // add named sub messages
115
iterator = typeNC.getSubMessageNamesIterator();
116       while (iterator.hasNext())
117       {
118         String JavaDoc msgName = (String JavaDoc) iterator.next();
119         MessageType t = typeNC.getSubMessageType(msgName);
120         try
121         {
122           message.addSubMessage(msgName, createMessage(t));
123         }
124         catch (MessageAlreadyExistException e)
125         {
126           // cannot happend
127
}
128       }
129
130       iterator = typeNC.getUnnamedSubMessageTypesIterator();
131     }
132     else
133     {
134       msg = createExtensibleMessage();
135       iterator = type.getSubMessageTypesIterator();
136     }
137     // add unnamed sub messages
138
while (iterator.hasNext())
139     {
140       MessageType t = (MessageType) iterator.next();
141       msg.addSubMessage(createMessage(t));
142     }
143
144     // add chunks
145
iterator = type.getChunkNamesIterator();
146     while (iterator.hasNext())
147     {
148       String JavaDoc chunkName = (String JavaDoc) iterator.next();
149       ChunkType t = type.getChunkType(chunkName);
150       try
151       {
152         msg.addChunk(chunkName, t, createChunk(t));
153       }
154       catch (ChunkAlreadyExistsException e)
155       {
156         // cannot happend
157
}
158     }
159     return msg;
160   }
161
162   /**
163    * @see MessageManager#deleteMessage(Message)
164    */

165   public void deleteMessage(Message message)
166   {
167     if (((MessageReferenceCounter) message).decrementReferenceCounter())
168     {
169       logger.log(BasicLevel.DEBUG, "Recycle message.");
170       Iterator JavaDoc iterator;
171       // if no chunk pool, it is not necessary to recycle chunk instance
172
if (chunkPoolItfs != null)
173       {
174         iterator = message.getMessageType().getChunkNamesIterator();
175         while (iterator.hasNext())
176         {
177           String JavaDoc chunkName = (String JavaDoc) iterator.next();
178           deleteChunk(message.getChunk(chunkName));
179         }
180       }
181
182       iterator = message.getSubMessageIterator();
183       while (iterator.hasNext())
184       {
185         Message subMessage = (Message) iterator.next();
186         deleteMessage(subMessage);
187       }
188       if (message instanceof ExtensibleMessageNC)
189       {
190         if (extensibleMessageNCPoolOptItf != null)
191         {
192           extensibleMessageNCPoolOptItf.recycleInstance(message);
193         }
194       }
195       else
196       {
197         if (extensibleMessagePoolOptItf != null)
198         {
199           extensibleMessagePoolOptItf.recycleInstance(message);
200         }
201       }
202     }
203   }
204
205   /**
206    * @see MessageManager#duplicateMessage(Message, boolean)
207    */

208   public Message duplicateMessage(Message message, boolean clone)
209   {
210     if (clone)
211     {
212       // TODO wrong for sub message !!
213
Message newInstance = createMessage(message.getMessageType());
214       message.transfertChunkStates(newInstance);
215       return newInstance;
216     }
217     else
218     {
219       ((AbstractExtensibleMessage) message).incrementReferenceCounter();
220       return message;
221     }
222   }
223
224   /**
225    * @see MessageManager#createChunk(ChunkType)
226    */

227   public Object JavaDoc createChunk(ChunkType type) throws UnknownChunkTypeError
228   {
229     if (type instanceof ChunkTypeImpl)
230     {
231       Chunk chunk = createChunkInstance(type);
232       chunk.setMessageManagerId(id);
233       return chunk;
234     }
235     else
236     {
237       throw new UnknownChunkTypeError(type);
238     }
239   }
240
241   /**
242    * @see MessageManager#deleteChunk(Object)
243    */

244   public void deleteChunk(Object JavaDoc chunk)
245   {
246     if (chunk instanceof Chunk)
247     {
248       recycleChunkInstance((Chunk) chunk);
249     }
250   }
251
252   /**
253    * @see MessageManager#duplicateChunk(Object, boolean)
254    */

255   public Object JavaDoc duplicateChunk(Object JavaDoc chunk, boolean clone)
256   {
257     if (chunk instanceof Chunk)
258     {
259       Chunk c = (Chunk) chunk;
260       Chunk newInstance = (Chunk) createChunk(c.getType());
261       c.transfertState(newInstance);
262       return c;
263     }
264     else
265     {
266       throw new UnsupportedOperationException JavaDoc(
267           "Unable to duplicate chunk, does not implement Chunk interface : "
268               + chunk);
269     }
270   }
271
272   /**
273    * @see MessageManager#getMessageManagerId()
274    */

275   public short getMessageManagerId()
276   {
277     return id;
278   }
279
280   // ---------------------------------------------------------------------------
281
// Implementation of the MessageManagerAttributeController
282
// ---------------------------------------------------------------------------
283

284   /**
285    * @see MessageManagerAttributeController#getId()
286    */

287   public short getId()
288   {
289     return id;
290   }
291
292   /**
293    * @see MessageManagerAttributeController#setId(short)
294    */

295   public void setId(short id)
296   {
297     this.id = id;
298   }
299
300   // ---------------------------------------------------------------------------
301
// Utilty methods
302
// ---------------------------------------------------------------------------
303

304   protected final ExtensibleMessageNC createExtensibleMessageNC()
305   {
306     if (extensibleMessageNCPoolOptItf == null)
307     {
308       return new ExtensibleMessageNCImpl(id);
309     }
310     else
311     {
312       return (ExtensibleMessageNC) extensibleMessageNCPoolOptItf.newInstance();
313     }
314   }
315
316   protected final ExtensibleMessage createExtensibleMessage()
317   {
318     if (extensibleMessagePoolOptItf == null)
319     {
320       return new ExtensibleMessageImpl(id);
321     }
322     else
323     {
324       return (ExtensibleMessage) extensibleMessagePoolOptItf.newInstance();
325     }
326   }
327
328   protected final Chunk createChunkInstance(ChunkType chunkType)
329   {
330     if (unknownChunkPools != null)
331     {
332       if (chunkPoolItfs == null)
333       {
334         chunkPoolItfs = new HashMap JavaDoc();
335       }
336       // their is unknown chunk pool binding.
337
Iterator JavaDoc iterator = unknownChunkPools.iterator();
338       while (iterator.hasNext())
339       {
340         ObjectPool chunkPool = (ObjectPool) iterator.next();
341         Chunk instance = (Chunk) chunkPool.newInstance();
342         ChunkType type = instance.getType();
343         chunkPoolItfs.put(type, instance);
344         chunkPool.recycleInstance(instance);
345       }
346       unknownChunkPools = null; // gc the List
347
}
348     if (chunkPoolItfs != null)
349     {
350       ObjectPool pool = (ObjectPool) chunkPoolItfs.get(chunkType);
351       if (pool != null)
352       {
353         return (Chunk) pool.newInstance();
354       }
355     }
356     try
357     {
358       return (Chunk) ((ChunkTypeImpl) chunkType).getChunkImpl().newInstance();
359     }
360     catch (Exception JavaDoc e)
361     {
362       throw new UnknownChunkTypeError(
363           "Unable to instanciate chunk implementation : " + e.getMessage(),
364           chunkType);
365     }
366   }
367
368   protected final void recycleChunkInstance(Chunk chunk)
369   {
370     if (chunkPoolItfs != null)
371     {
372       ObjectPool pool = (ObjectPool) chunkPoolItfs.get(chunk.getType());
373       if (pool != null)
374       {
375         pool.recycleInstance(chunk);
376       }
377     }
378   }
379
380   // ---------------------------------------------------------------------------
381
// Implementation of the BindingController interface
382
// ---------------------------------------------------------------------------
383

384   /**
385    * @see org.objectweb.fractal.api.control.BindingController#bindFc(String,
386    * Object)
387    */

388   public void bindFc(String JavaDoc clientItfName, Object JavaDoc serverItf)
389       throws NoSuchInterfaceException, IllegalBindingException,
390       IllegalLifeCycleException
391   {
392     super.bindFc(clientItfName, serverItf);
393     if (clientItfName.equals(EXTENSIBLE_MESSAGE_POOL_OPT_ITF_NAME))
394     {
395       extensibleMessagePoolOptItf = (ObjectPool) serverItf;
396     }
397     else if (clientItfName.equals(EXTENSIBLE_MESSAGE_NC_POOL_OPT_ITF_NAME))
398     {
399       extensibleMessageNCPoolOptItf = (ObjectPool) serverItf;
400     }
401     else if (clientItfName.startsWith(CHUNK_POOL_COLLECTION_ITF_NAME))
402     {
403       if (chunkPoolItfs == null)
404       {
405         chunkPoolItfs = new HashMap JavaDoc();
406       }
407       chunkPoolItfs.put(clientItfName, serverItf);
408       if (unknownChunkPools == null)
409       {
410         unknownChunkPools = new ArrayList JavaDoc();
411       }
412       unknownChunkPools.add(serverItf);
413     }
414   }
415
416   /**
417    * @see org.objectweb.fractal.api.control.BindingController#unbindFc(String)
418    */

419   public void unbindFc(String JavaDoc clientItfName) throws NoSuchInterfaceException,
420       IllegalBindingException, IllegalLifeCycleException
421   {
422     if (clientItfName.equals(EXTENSIBLE_MESSAGE_POOL_OPT_ITF_NAME))
423     {
424       extensibleMessagePoolOptItf = null;
425     }
426     else if (clientItfName.equals(EXTENSIBLE_MESSAGE_NC_POOL_OPT_ITF_NAME))
427     {
428       extensibleMessageNCPoolOptItf = null;
429     }
430     else if (clientItfName.startsWith(CHUNK_POOL_COLLECTION_ITF_NAME))
431     {
432       Object JavaDoc serverItf = super.lookupFc(clientItfName);
433       if (unknownChunkPools != null)
434       {
435         unknownChunkPools.remove(serverItf);
436       }
437       chunkPoolItfs.values().remove(serverItf);
438     }
439     super.unbindFc(clientItfName);
440   }
441
442   /**
443    * @see org.objectweb.fractal.api.control.BindingController#listFc()
444    */

445   public String JavaDoc[] listFc()
446   {
447     return new String JavaDoc[]{EXTENSIBLE_MESSAGE_NC_POOL_OPT_ITF_NAME,
448         EXTENSIBLE_MESSAGE_POOL_OPT_ITF_NAME, CHUNK_POOL_COLLECTION_ITF_NAME};
449   }
450 }
Popular Tags