1    //
2    // SwitchRMI  Framework
3    // Copyright (c) 2000-2002 by Michael J. Henderson & Associates.
4    //
5    // Michael Henderson
6    // http://switchrmi.sf.net
7    // mailto:mikehenderson@dunelm.org.uk
8    //
9    // This library is free software.
10   //
11   // You may redistribute it and/or modify it under the terms of the GNU
12   // Lesser General Public License as published by the Free Software Foundation.
13   //
14   // Version 2.1 of the license should be included with this distribution in
15   // the file LICENSE, as well as License.html. If the license is not
16   // included with this distribution, you may find a copy at the FSF web
17   // site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
18   // Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
19   //
20   // This library is distributed in the hope that it will be useful,
21   // but WITHOUT ANY WARRANTY; without even the implied waranty of
22   // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   // Lesser General Public License for more details.
24   //
25   // $Id: RmiConfiguration.java,v 1.1 2002/11/11 22:19:48 mikehenderson Exp $
26   package com.mjh.switchrmi.jndi;
27   
28   import com.mjh.dom.*;
29   import com.mjh.switchrmi.*;
30   
31   import java.io.*;
32   
33   import java.lang.reflect.*;
34   
35   import java.net.*;
36   
37   import java.util.*;
38   
39   import javax.naming.*;
40   
41   import javax.xml.parsers.*;
42   import javax.xml.transform.*;
43   
44   import org.apache.log4j.Logger;
45   import org.w3c.dom.*;
46   
47   public class RmiConfiguration
48   {
49       public static final String SWITCHRMI_JNDI_INITIAL_URL = 
50               "switchrmi.jndi.initial.url";
51       private static final Logger log = 
52               Logger.getLogger(RmiConfiguration.class.getName());
53       private final static String FILE_SUFFIX = ".xml";
54       private final static String ROOT_TAG = "switchrmi";
55       private final static String SERVICE_TAG = "service";
56       private final static String CLIENT_TAG = "client";
57       private final static String PROTOCOL_TAG = "protocol";
58       private final static String TRANSPORT_TAG = "transport";
59       private final static String CODEBASE_TAG = "codebase";
60       private final static String LIBRARY_TAG = "lib";
61       private final static String OBJECT_TAG = "object";
62       private final static String REMOTE_TAG = "remote";
63       private final static String DESCRIPTION_TAG = "description";
64       private final static String JAVA_TAG = "java";
65       private final static String SCRIPT_TAG = "script";
66       private final static String PROXY_TAG = "proxy";
67       private final static String INTERFACE_TAG = "interface";
68       private final static String NAME_ATTR = "name";
69       private final static String HANDLER_ATTR = "handler";
70       private final static String SCOPE_ATTR = "scope";
71       private final static String VALUE_ATTR = "value";
72       private final static String CLASS_ATTR = "class";
73       private final static String SOURCE_ATTR = "source";
74       private final static String LANG_ATTR = "language";
75       private final static String URL_ATTR = "url";
76       private final static String PROTOCOL_ATTR = "protocol";
77       private final static String DEFAULT_RESOURCE_NAME = 
78               "/com/mjh/switchrmi/RmiConfiguration.xml";
79       private HashMap parsers = new HashMap();
80       private Context jndiContext;
81   
82       public RmiConfiguration(Context ctx)
83                        throws Exception
84       {
85           init();
86           this.jndiContext = ctx;
87           parseResource(DEFAULT_RESOURCE_NAME);
88       }
89   
90       public RmiConfiguration(Context ctx, String resourceUrl)
91                        throws Exception
92       {
93           if (log.isDebugEnabled())
94           {
95               log.debug("2 args constructor resourceUrl  = " + resourceUrl);
96           }
97   
98           this.jndiContext = ctx;
99           init();
100          parseResource(DEFAULT_RESOURCE_NAME);
101  
102          if (resourceUrl != null)
103          {
104              parseUrl(new URL(resourceUrl));
105          }
106      }
107  
108      private void init()
109      {
110          parsers.put(ROOT_TAG, new RootParser(ROOT_TAG));
111          parsers.put(SERVICE_TAG, new ServiceParser(SERVICE_TAG));
112          parsers.put(CLIENT_TAG, new ClientParser(CLIENT_TAG));
113  
114          parsers.put(PROTOCOL_TAG, new TypeParser(PROTOCOL_TAG));
115          parsers.put(TRANSPORT_TAG, new TypeParser(TRANSPORT_TAG));
116  
117          parsers.put(OBJECT_TAG, new ObjectParser(OBJECT_TAG));
118          parsers.put(REMOTE_TAG, new RemoteParser(REMOTE_TAG));
119          parsers.put(CODEBASE_TAG, new CodebaseParser(CODEBASE_TAG));
120          parsers.put(LIBRARY_TAG, new LibraryParser(LIBRARY_TAG));
121          parsers.put(JAVA_TAG, new JavaClassParser(JAVA_TAG));
122          parsers.put(SCRIPT_TAG, new ScriptParser(SCRIPT_TAG));
123          parsers.put(PROXY_TAG, new ObjectParser(PROXY_TAG));
124          parsers.put(INTERFACE_TAG, new InterfaceParser(INTERFACE_TAG));
125          parsers.put(DESCRIPTION_TAG, new DescriptionParser(DESCRIPTION_TAG));
126      }
127  
128      private void parseResource(String resourceName)
129                          throws Exception
130      {
131          URL resourceUrl = RmiConfiguration.class.getResource(resourceName);
132  
133          if (log.isDebugEnabled())
134          {
135              log.debug("resourceUrl = " + resourceUrl);
136          }
137  
138          parseUrl(resourceUrl);
139      }
140  
141      private void parseUrl(URL url)
142                     throws Exception
143      {
144          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
145          DocumentBuilder builder = factory.newDocumentBuilder();
146          Document doc = (Document) builder.parse(url.toString());
147  
148          parse(doc);
149      }
150  
151      private void parse(Document document)
152                  throws Exception
153      {
154          try
155          {
156              Element root = document.getDocumentElement();
157              TagParser parser = (TagParser) parsers.get(root.getTagName());
158  
159              parser.parse(root, jndiContext);
160          }
161          catch (Exception ex)
162          {
163              if (log.isDebugEnabled())
164              {
165                  log.debug(ex);
166              }
167  
168              ex.printStackTrace();
169              throw ex;
170          }
171      }
172  
173      private TagParser getParser(String tagName)
174      {
175          return (TagParser) parsers.get(tagName);
176      }
177  
178      abstract class TagParser
179      {
180          String tagName;
181  
182          public TagParser(String string)
183          {
184              tagName = string;
185          }
186  
187          public void parse(NodeList list, Object object)
188                     throws Exception
189          {
190              int length = list.getLength();
191  
192              for (int i = 0; i < length; i++)
193              {
194                  parse((Element) list.item(i), object);
195              }
196          }
197  
198          public abstract void parse(Element element, Object object)
199                              throws Exception;
200  
201          public void parseChildElements(Element element, Object object)
202          {
203              try
204              {
205                  NodeList children = DomUtil.getChildElements(element);
206                  int length = children.getLength();
207  
208                  for (int i = 0; i < length; i++)
209                  {
210                      Element child = (Element) children.item(i);
211  
212                      if (log.isDebugEnabled())
213                      {
214                          log.debug("child = " + child);
215                      }
216  
217                      getParser(child.getTagName()).parse(child, object);
218                  }
219              }
220              catch (Exception ex)
221              {
222                  if (log.isDebugEnabled())
223                  {
224                      log.debug("Exception ", ex);
225                  }
226              }
227          }
228  
229          protected Context getSubcontext(Context ctx, String name)
230              throws Exception
231          {
232              Context subctx = null;
233  
234              try
235              {
236                  subctx = ctx.createSubcontext(name);
237              }
238              catch (NameAlreadyBoundException ex)
239              {
240                  subctx = (Context) ((JndiContextImpl) ctx)._lookup(name);
241              }
242  
243              return subctx;
244          }
245      }
246  
247      class RootParser extends TagParser
248      {
249          public RootParser(String tag)
250          {
251              super(tag);
252          }
253  
254          public void parse(Element element, Object object)
255                     throws Exception
256          {
257              Context ctx = (Context) object;
258  
259              ctx = getSubcontext(ctx, tagName);
260              parseChildElements(element, ctx);
261          }
262      }
263  
264      class ServiceParser extends TagParser
265      {
266          public ServiceParser(String tagName)
267          {
268              super(tagName);
269          }
270  
271          public void parse(Element element, Object object)
272                     throws Exception
273          {
274              Context ctx = (Context) object;
275  
276              if (log.isDebugEnabled())
277              {
278                  log.debug("ServiceParser.parse(), tagName = " + tagName);
279              }
280  
281              ctx = getSubcontext(ctx, tagName);
282  
283              parseChildElements(element, ctx);
284          }
285      }
286  
287      class ClientParser extends ServiceParser
288      {
289          public ClientParser(String tagName)
290          {
291              super(tagName);
292          }
293      }
294  
295      class TypeParser extends TagParser
296      {
297          Class typeClazz;
298  
299          public TypeParser(String string)
300          {
301              super(string);
302          }
303  
304          public void parse(Element element, Object object)
305                     throws Exception
306          {
307              boolean debug = log.isDebugEnabled();
308  
309              if (debug)
310              {
311                  log.debug(" tagName = " + tagName);
312                  log.debug(" element = " + element);
313              }
314  
315              String name = element.getAttribute(NAME_ATTR);
316              String className = element.getAttribute(CLASS_ATTR);
317  
318              try
319              {
320                  GenericReferenceable ref = new GenericReferenceable(className);
321  
322                  parseChildElements(element, ref);
323  
324                  if (debug)
325                  {
326                      log.debug("-------------------------------");
327                  }
328  
329                  Context ctx = (Context) object;
330  
331                  if (debug)
332                  {
333                      log.debug("ctx = " + ctx.getNameInNamespace());
334                  }
335  
336                  ctx = getSubcontext(ctx, tagName);
337  
338                  if (debug)
339                  {
340                      log.debug("ctx = " + ctx.getNameInNamespace());
341                      log.debug("tagName = " + tagName);
342                      log.debug("ctx = " + ctx);
343                  }
344  
345                  ctx.rebind(name, ref);
346  
347                  if (debug)
348                  {
349                      log.debug("ctx = " + ctx);
350                      log.debug("ref = " + ref);
351                      log.debug("-------------------------------");
352                  }
353              }
354              catch (Exception ex)
355              {
356                  if (debug)
357                  {
358                      log.debug(ex);
359                  }
360  
361                  throw ex;
362              }
363          }
364      }
365  
366      class CodebaseParser extends TagParser
367      {
368          public CodebaseParser(String tag)
369          {
370              super(tag);
371          }
372  
373          public void parse(Element element, Object object)
374                     throws Exception
375          {
376              if (log.isDebugEnabled())
377              {
378                  log.debug("element = " + element.toString());
379              }
380  
381              GenericReferenceable ref = (GenericReferenceable) object;
382  
383              ref.setCodebase(element.getAttribute(URL_ATTR));
384          }
385      }
386  
387      class LibraryParser extends TagParser
388      {
389          public LibraryParser(String tag)
390          {
391              super(tag);
392          }
393  
394          public void parse(Element element, Object object)
395                     throws Exception
396          {
397              if (log.isDebugEnabled())
398              {
399                  log.debug("element = " + element.toString());
400              }
401  
402              GenericReferenceable ref = (GenericReferenceable) object;
403  
404              ref.addLibrary(element.getAttribute(NAME_ATTR));
405          }
406      }
407  
408      class DescriptionParser extends TagParser
409      {
410          public DescriptionParser(String tag)
411          {
412              super(tag);
413          }
414  
415          public void parse(Element element, Object object)
416                     throws Exception
417          {
418              if (log.isDebugEnabled())
419              {
420                  log.debug("element = " + element.toString());
421              }
422  
423              Text text = (Text) element.getFirstChild();
424              GenericReferenceable ref = (GenericReferenceable) object;
425  
426              ref.setDescription(text.getData());
427          }
428      }
429  
430      class ObjectParser extends TagParser
431      {
432          public ObjectParser(String tag)
433          {
434              super(tag);
435          }
436  
437          public void parse(Element element, Object object)
438                     throws Exception
439          {
440              log.debug("element = " + element.toString());
441  
442              try
443              {
444                  String name = element.getAttribute(NAME_ATTR);
445                  String scope = element.getAttribute(SCOPE_ATTR);
446                  ObjectReferenceable ref = new ObjectReferenceable();
447  
448                  ref.setName(name);
449                  ref.setScope(scope);
450                  parseChildElements(element, ref);
451  
452                  Context ctx = (Context) object;
453  
454                  ctx = getSubcontext(ctx, tagName);
455                  ctx.rebind(name, ref);
456                  ctx.addToEnvironment(name, ref);
457  
458                  if (log.isDebugEnabled())
459                  {
460                      log.debug("ref = " + ref);
461                      log.debug("ctx = " + ctx);
462                  }
463              }
464              catch (Exception ex)
465              {
466                  if (log.isDebugEnabled())
467                  {
468                      log.debug("Exception ", ex);
469                  }
470  
471                  throw ex;
472              }
473          }
474      }
475  
476      class InterfaceParser extends TagParser
477      {
478          public InterfaceParser(String tag)
479          {
480              super(tag);
481          }
482  
483          public void parse(Element element, Object object)
484                     throws Exception
485          {
486              if (log.isDebugEnabled())
487              {
488                  log.debug("element = " + element.toString());
489              }
490  
491              ObjectReferenceable ref = (ObjectReferenceable) object;
492  
493              ref.addInterface(element.getAttribute(CLASS_ATTR));
494          }
495      }
496  
497      class JavaClassParser extends TagParser
498      {
499          public JavaClassParser(String tag)
500          {
501              super(tag);
502          }
503  
504          public void parse(Element element, Object object)
505                     throws Exception
506          {
507              if (log.isDebugEnabled())
508              {
509                  log.debug("element = " + element.toString());
510              }
511  
512              ObjectReferenceable ref = (ObjectReferenceable) object;
513              String className = element.getAttribute(CLASS_ATTR);
514  
515              ref.setClassName(className);
516              ref.setType(tagName);
517  
518              Map map = new HashMap();
519  
520              map.put(CLASS_ATTR, className);
521              ref.setTypeInfo(map);
522          }
523      }
524  
525      class ScriptParser extends TagParser
526      {
527          public ScriptParser(String tag)
528          {
529              super(tag);
530          }
531  
532          public void parse(Element element, Object object)
533                     throws Exception
534          {
535              if (log.isDebugEnabled())
536              {
537                  log.debug("element = " + element.toString());
538              }
539  
540              ObjectReferenceable ref = (ObjectReferenceable) object;
541              String source = element.getAttribute(SOURCE_ATTR);
542              String language = element.getAttribute(LANG_ATTR);
543  
544              ref.setType(tagName);
545  
546              Map map = new HashMap();
547  
548              map.put(SOURCE_ATTR, source);
549              map.put(LANG_ATTR, language);
550  
551              ref.setTypeInfo(map);
552          }
553      }
554  
555      class RemoteParser extends TagParser
556      {
557          public RemoteParser(String tag)
558          {
559              super(tag);
560          }
561  
562          public void parse(Element element, Object object)
563                     throws Exception
564          {
565              if (log.isDebugEnabled())
566              {
567                  log.debug("element = " + element.toString());
568              }
569  
570              ObjectReferenceable ref = (ObjectReferenceable) object;
571  
572              parseChildElements(element, ref);
573  
574              String url = element.getAttribute(URL_ATTR);
575              String protocol = element.getAttribute(PROTOCOL_ATTR);
576  
577              ref.setType(tagName);
578  
579              Map map = new HashMap();
580  
581              map.put(URL_ATTR, url);
582              map.put(PROTOCOL_ATTR, protocol);
583  
584              ref.setTypeInfo(map);
585          }
586      }
587  }