KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > remoting > marshal > MarshalFactory


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.remoting.marshal;
8
9 import java.util.HashMap JavaDoc;
10 import java.util.Map JavaDoc;
11 import org.jboss.logging.Logger;
12 import org.jboss.remoting.InvokerLocator;
13 import org.jboss.remoting.marshal.http.HTTPMarshaller;
14 import org.jboss.remoting.marshal.http.HTTPUnMarshaller;
15 import org.jboss.remoting.marshal.serializable.SerializableMarshaller;
16 import org.jboss.remoting.marshal.serializable.SerializableUnMarshaller;
17
18
19 /**
20  * This class will provide marshallers and unmarshallers for data based on
21  * the data type want to marshal to. The most common will be just to serialize
22  * the data. However, may have jaxrpc, IIOP, serializers. Can also have marshallers
23  * and unmarshallers based on class type. For example, might be marshaller/unmarshaller
24  * for the Transaction class.
25  *
26  * @author <a HREF="mailto:tom@jboss.org">Tom Elrod</a>
27  */

28 public class MarshalFactory
29 {
30    private static Map JavaDoc marshallers = new HashMap JavaDoc();
31    private static Map JavaDoc unmarshallers = new HashMap JavaDoc();
32    private static Map JavaDoc classMarshallers = new HashMap JavaDoc();
33    private static Map JavaDoc classUnmarshallers = new HashMap JavaDoc();
34
35    protected final static Logger log = Logger.getLogger(MarshalFactory.class);
36
37    // statically load core marshallers/unmarshallers
38
static
39    {
40       try
41       {
42          marshallers.put(SerializableMarshaller.DATATYPE, new SerializableMarshaller());
43          unmarshallers.put(SerializableUnMarshaller.DATATYPE, new SerializableUnMarshaller());
44          marshallers.put(HTTPMarshaller.DATATYPE, new HTTPMarshaller());
45          unmarshallers.put(HTTPUnMarshaller.DATATYPE, new HTTPUnMarshaller());
46       }
47       catch(Exception JavaDoc e)
48       {
49          log.error("Could not statically load default marshallers.", e);
50       }
51    }
52
53    /**
54     * Will add the marshaller and unmarshaller based on class type. Each can then be retrieved using the
55     * class type as key.
56     *
57     * @param classType
58     * @param marshaller
59     * @param unMarshaller
60     */

61    public static void addMarshaller(Class JavaDoc classType, Marshaller marshaller, UnMarshaller unMarshaller)
62    {
63       classMarshallers.put(classType, marshaller);
64       classUnmarshallers.put(classType, unMarshaller);
65    }
66
67    /**
68     * Adds the marshaller and unmarshaller based on data type. Each can then be retrieved using the data type
69     * as the key.
70     *
71     * @param dataType
72     * @param marshaller
73     * @param unMarshaller
74     */

75    public static void addMarshaller(String JavaDoc dataType, Marshaller marshaller, UnMarshaller unMarshaller)
76    {
77       marshallers.put(dataType, marshaller);
78       unmarshallers.put(dataType, unMarshaller);
79    }
80
81    /**
82     * Looks up marshaller by class type. Will return null if not found.
83     *
84     * @param classType
85     * @return
86     */

87    public static Marshaller getMarshaller(Class JavaDoc classType)
88    {
89       Marshaller marshaller = null;
90       Object JavaDoc obj = classMarshallers.get(classType);
91       if(obj != null && obj instanceof Marshaller)
92       {
93          marshaller = (Marshaller) obj;
94
95          try
96          {
97             marshaller = marshaller.cloneMarshaller();
98          }
99          catch(CloneNotSupportedException JavaDoc e)
100          {
101             log.warn("Could not clone " + marshaller);
102          }
103       }
104       else
105       {
106          log.warn("Could not find marshaller for class type '" + classType + "'. Object in collection is " + obj);
107       }
108
109       return marshaller;
110    }
111
112    /**
113     * Returns unmarshaller by class type. Will return null if not found.
114     *
115     * @param classType
116     * @return
117     */

118    public static UnMarshaller getUnMarshaller(Class JavaDoc classType)
119    {
120       UnMarshaller unmarshaller = null;
121       Object JavaDoc obj = classUnmarshallers.get(classType);
122       if(obj != null && obj instanceof UnMarshaller)
123       {
124          unmarshaller = (UnMarshaller) obj;
125
126          try
127          {
128             unmarshaller = unmarshaller.cloneUnMarshaller();
129          }
130          catch(CloneNotSupportedException JavaDoc e)
131          {
132             log.warn("Could not clone " + unmarshaller);
133          }
134
135       }
136       else
137       {
138          log.warn("Could not find unmarshaller for class type '" + classType + "'. Object in collection is " + obj);
139       }
140       return unmarshaller;
141    }
142
143    /**
144     * Gets marshaller based on data type (i.e. serializable) and based on the marshallers registered with the factory.
145     *
146     * @param dataType
147     * @return The marshaller or null if none for for the specified type
148     */

149    public static Marshaller getMarshaller(String JavaDoc dataType)
150    {
151       Marshaller marshaller = null;
152       Object JavaDoc obj = marshallers.get(dataType);
153       if(obj != null && obj instanceof Marshaller)
154       {
155          marshaller = (Marshaller) obj;
156
157          try
158          {
159             marshaller = marshaller.cloneMarshaller();
160          }
161          catch(CloneNotSupportedException JavaDoc e)
162          {
163             log.warn("Could not clone " + marshaller);
164          }
165
166       }
167       else
168       {
169          log.warn("Could not find marshaller for data type '" + dataType + "'. Object in collection is " + obj);
170       }
171
172       return marshaller;
173    }
174
175    /**
176     * Gets the marshaller based on data type (i.e. serialziable) and based on the unmarshallers registered with the factory.
177     *
178     * @param dataType
179     * @return The unmarshaller or null if none for the specified type
180     */

181    public static UnMarshaller getUnMarshaller(String JavaDoc dataType)
182    {
183       UnMarshaller unmarshaller = null;
184       Object JavaDoc obj = unmarshallers.get(dataType);
185       if(obj != null && obj instanceof UnMarshaller)
186       {
187          unmarshaller = (UnMarshaller) obj;
188
189          try
190          {
191             unmarshaller = unmarshaller.cloneUnMarshaller();
192          }
193          catch(CloneNotSupportedException JavaDoc e)
194          {
195             log.warn("Could not clone " + unmarshaller);
196          }
197       }
198       else
199       {
200          log.warn("Could not find unmarshaller for data type '" + dataType + "'. Object in collection is " + obj);
201       }
202
203       return unmarshaller;
204    }
205
206    /**
207     * Will try to look up marshaller by first looking for data type parameter within locator and then using that
208     * to look up marhsaller locally. If can not find it, will then look to see if can find the 'marshaller' parameter
209     * within the locator parameters. If found, will try to load the marshaller by the class name specified as the parameter
210     * value. If still can not find the class within the local VM, will look to see if there is a parameter for
211     * the server's marshaller loader port. If this exists, will then try calling on the remote server to load the
212     * marshaller (and its related classes) within the local VM. If still can not be found, will return null.
213     *
214     * @param locator
215     * @param classLoader
216     * @return
217     */

218    public static Marshaller getMarshaller(InvokerLocator locator, ClassLoader JavaDoc classLoader)
219    {
220       Marshaller marshaller = null;
221       if(locator != null)
222       {
223          Map JavaDoc params = locator.getParameters();
224          if(params != null)
225          {
226             // start with data type as is prefered method of getting marshaller/unmarshaller
227
String JavaDoc dataType = (String JavaDoc) params.get(InvokerLocator.DATATYPE);
228             if(dataType == null)
229             {
230                dataType = (String JavaDoc) params.get(InvokerLocator.DATATYPE_CASED);
231             }
232             if(dataType != null)
233             {
234                marshaller = getMarshaller(dataType);
235             }
236             if(marshaller == null)
237             {
238                log.debug("Could not find data type to lookup by marshaller class");
239
240                // will now look for explicit param for marshaller class
241
String JavaDoc marshallerFQN = (String JavaDoc) params.get(InvokerLocator.MARSHALLER);
242                marshaller = loadMarshaller(marshallerFQN);
243                if(marshaller != null)
244                {
245                   log.debug("Found marshaller by loading locally.");
246                   // try to load unmarshaller so that can add to list
247
String JavaDoc unmarshallerFQN = (String JavaDoc) params.get(InvokerLocator.UNMARSHALLER);
248                   UnMarshaller unmarshaller = loadUnMarshaller(unmarshallerFQN);
249                   if(unmarshaller != null)
250                   {
251                      addMarshaller(dataType, marshaller, unmarshaller);
252                   }
253                }
254             }
255             if(marshaller == null)
256             {
257                log.debug("Tried to find marshaller from locator by both data type and class name but was unsuccessful. " +
258                          "Will try to load it from remote server.");
259             }
260             // if still have not found marshaller, check to see if can load remotely
261
if(marshaller == null && dataType != null)
262             {
263                InvokerLocator loaderLocator = MarshallLoaderFactory.convertLocator(locator);
264                if(loaderLocator != null)
265                {
266                   marshaller = MarshallerLoaderClient.getMarshaller(loaderLocator, dataType, classLoader);
267                   UnMarshaller unmarshaller = MarshallerLoaderClient.getUnMarshaller(loaderLocator, dataType, classLoader);
268                   if(unmarshaller != null)
269                   {
270                      unmarshaller.setClassLoader(classLoader);
271                   }
272                   log.debug("Remotely loaded marshaller: " + marshaller);
273                   log.debug("Remotely loaded unmarshaller: " + unmarshaller);
274                   if(marshaller != null && unmarshaller != null)
275                   {
276                      addMarshaller(dataType, marshaller, unmarshaller);
277                   }
278                }
279             }
280          }
281       }
282
283       if(marshaller != null)
284       {
285          try
286          {
287             marshaller = marshaller.cloneMarshaller();
288          }
289          catch(CloneNotSupportedException JavaDoc e)
290          {
291             log.warn("Could not clone " + marshaller);
292          }
293       }
294       return marshaller;
295    }
296
297    private static Marshaller loadMarshaller(String JavaDoc marshallerFQN)
298    {
299       Marshaller marshaller = null;
300       if(marshallerFQN != null)
301       {
302          try
303          {
304             Class JavaDoc marshallerClass = Class.forName(marshallerFQN);
305             marshaller = (Marshaller) marshallerClass.newInstance();
306          }
307          catch(Exception JavaDoc e)
308          {
309             log.warn("Found marshaller fully qualified class name within locator parameters, but was unable " +
310                      "to load class: " + marshallerFQN);
311          }
312       }
313       return marshaller;
314    }
315
316    /**
317     * Will try to look up unmarshaller by first looking for data type parameter within locator and then using that
318     * to look up unmarshaller locally. If can not find it, will then look to see if can find the 'unmarshaller' parameter
319     * within the locator parameters. If found, will try to load the unmarshaller by the class name specified as the parameter
320     * value. If still can not find the class within the local VM, will look to see if there is a parameter for
321     * the server's marshaller loader port. If this exists, will then try calling on the remote server to load the
322     * unmarshaller (and its related classes) within the local VM. If still can not be found, will return null.
323     *
324     * @param locator
325     * @param classLoader
326     * @return
327     */

328    public static UnMarshaller getUnMarshaller(InvokerLocator locator, ClassLoader JavaDoc classLoader)
329    {
330       UnMarshaller unmarshaller = null;
331       if(locator != null)
332       {
333          Map JavaDoc params = locator.getParameters();
334          if(params != null)
335          {
336             // start with data type as is prefered method of getting marshaller/unmarshaller
337
String JavaDoc dataType = (String JavaDoc) params.get(InvokerLocator.DATATYPE);
338             if(dataType != null)
339             {
340                unmarshaller = getUnMarshaller(dataType);
341             }
342             if(unmarshaller == null)
343             {
344                log.debug("Could not find data type to lookup by unmarshaller class");
345
346                // will now look for explicit param for marshaller class
347
String JavaDoc unmarshallerFQN = (String JavaDoc) params.get(InvokerLocator.UNMARSHALLER);
348                unmarshaller = loadUnMarshaller(unmarshallerFQN);
349                if(unmarshaller != null)
350                {
351                   String JavaDoc marshallerFQN = (String JavaDoc) params.get(InvokerLocator.MARSHALLER);
352                   Marshaller marshaller = loadMarshaller(marshallerFQN);
353                   if(marshaller != null)
354                   {
355                      addMarshaller(dataType, marshaller, unmarshaller);
356                   }
357                }
358             }
359             if(log.isTraceEnabled() && unmarshaller == null)
360             {
361                log.trace("Tried to find unmarshaller from locator by both data type and class name but was unsuccessful.");
362             }
363             // if still have not found unmarshaller, check to see if can load remotely
364
if(unmarshaller == null && dataType != null)
365             {
366                InvokerLocator loaderLocator = MarshallLoaderFactory.convertLocator(locator);
367                unmarshaller = MarshallerLoaderClient.getUnMarshaller(loaderLocator, dataType, classLoader);
368                if(unmarshaller != null)
369                {
370                   unmarshaller.setClassLoader(classLoader);
371                }
372                Marshaller marshaller = MarshallerLoaderClient.getMarshaller(loaderLocator, dataType, classLoader);
373                if(log.isTraceEnabled())
374                {
375                   log.trace("Remotely loaded marshaller: " + marshaller);
376                   log.trace("Remotely loaded unmarshaller: " + unmarshaller);
377                }
378                if(marshaller != null && unmarshaller != null)
379                {
380                   addMarshaller(dataType, marshaller, unmarshaller);
381                }
382             }
383          }
384       }
385
386       if(unmarshaller != null)
387       {
388          try
389          {
390             unmarshaller = unmarshaller.cloneUnMarshaller();
391          }
392          catch(CloneNotSupportedException JavaDoc e)
393          {
394             log.warn("Could not clone " + unmarshaller);
395          }
396       }
397       return unmarshaller;
398    }
399
400    private static UnMarshaller loadUnMarshaller(String JavaDoc unmarshallerFQN)
401    {
402       UnMarshaller unmarshaller = null;
403       if(unmarshallerFQN != null)
404       {
405          try
406          {
407             Class JavaDoc unmarshallerClass = Class.forName(unmarshallerFQN);
408             unmarshaller = (UnMarshaller) unmarshallerClass.newInstance();
409          }
410          catch(Exception JavaDoc e)
411          {
412             log.error("Found unmarshaller fully qualified class name within locator parameters, but was unable " +
413                       "to load class: " + unmarshallerFQN, e);
414          }
415       }
416       return unmarshaller;
417    }
418 }
Popular Tags