View Javadoc

1   /* JndiUtils.java
2    *
3    * Created Aug 11, 2005
4    *
5    * Copyright (C) 2005 Internet Archive.
6    *
7    * This file is part of the Heritrix web crawler (crawler.archive.org).
8    *
9    * Heritrix is free software; you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser Public License as published by
11   * the Free Software Foundation; either version 2.1 of the License, or
12   * any later version.
13   *
14   * Heritrix is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU Lesser Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser Public License
20   * along with Heritrix; if not, write to the Free Software
21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22   */
23  package org.archive.util;
24  
25  import java.util.Enumeration;
26  import java.util.Hashtable;
27  import java.util.Properties;
28  
29  import javax.management.MalformedObjectNameException;
30  import javax.management.ObjectName;
31  import javax.naming.CompoundName;
32  import javax.naming.Context;
33  import javax.naming.InitialContext;
34  import javax.naming.InvalidNameException;
35  import javax.naming.NameNotFoundException;
36  import javax.naming.NamingException;
37  import javax.naming.Reference;
38  import javax.naming.StringRefAddr;
39  
40  /***
41   * JNDI utilities.
42   * @author stack
43   * @version $Date: 2005-10-27 22:20:20 +0000 (Thu, 27 Oct 2005) $ $Version$
44   */
45  public class JndiUtils {
46      /***
47       * Syntax that will work with jmx ObjectNames (i.e. will escape '.' and
48       * will add treat ',' and '=' specially.
49       */
50      private static final Properties COMPOUND_NAME_SYNTAX = new Properties();
51      static {
52          COMPOUND_NAME_SYNTAX.put("jndi.syntax.direction", "left_to_right");
53          COMPOUND_NAME_SYNTAX.put("jndi.syntax.separator", "+");
54          COMPOUND_NAME_SYNTAX.put("jndi.syntax.ignorecase", "false");
55          COMPOUND_NAME_SYNTAX.put("jndi.syntax.escape", "//");
56          COMPOUND_NAME_SYNTAX.put("jndi.syntax.beginquote", "'");
57          COMPOUND_NAME_SYNTAX.put("jndi.syntax.trimblanks", "true");
58          COMPOUND_NAME_SYNTAX.put("jndi.syntax.separator.ava", ",");
59          COMPOUND_NAME_SYNTAX.put("jndi.syntax.separator.typeval", "=");
60      }
61      
62      public static CompoundName getCompoundName(final String name)
63      throws InvalidNameException {
64          return new CompoundName(name, COMPOUND_NAME_SYNTAX);
65      }
66      
67      /***
68       * Return name to use as jndi name.
69       * Used to do a subset of the ObjectName fields but not just
70       * let all through so its easy to just use the jndi name to 
71       * find mbean.
72       * @param on ObjectName instance to work with.
73       * @return Returns a compound name to use as jndi key.
74       * @throws NullPointerException
75       * @throws InvalidNameException
76       */
77      public static CompoundName getCompoundName(final ObjectName on)
78      throws NullPointerException,
79      InvalidNameException {
80          return getCompoundName(on.getCanonicalKeyPropertyListString());
81      }
82      
83      /***
84       * @param on ObjectName instance to work with.
85       * @return A simple reference based on passed <code>on</code>
86       */
87      public static Reference getReference(final ObjectName on) {
88         Reference r = new Reference(String.class.getName());
89         Hashtable ht = on.getKeyPropertyList();
90         r.add(new StringRefAddr(JmxUtils.HOST, (String)ht.get(JmxUtils.HOST)));
91         r.add(new StringRefAddr(JmxUtils.NAME, (String)ht.get(JmxUtils.NAME)));
92         // Put in a value to serve as a unique 'key'.
93         r.add(new StringRefAddr(JmxUtils.KEY,
94                 on.getCanonicalKeyPropertyListString()));
95         return r;
96      }
97      
98      /***
99       * Get subcontext.  Only looks down one level.
100      * @param subContext Name of subcontext to return.
101      * @return Sub context.
102      * @throws NamingException 
103      */
104     public static Context getSubContext(final String subContext)
105     throws NamingException {
106         return getSubContext(getCompoundName(subContext));
107     }
108     
109     /***
110      * Get subcontext.  Only looks down one level.
111      * @param subContext Name of subcontext to return.
112      * @return Sub context.
113      * @throws NamingException 
114      */
115     public static Context getSubContext(final CompoundName subContext)
116     throws NamingException {
117         Context context = new InitialContext();
118         try {
119             context = (Context)context.lookup(subContext);
120         } catch (NameNotFoundException e) {
121             context = context.createSubcontext(subContext); 
122         }
123         return context;
124     }
125     
126     /***
127      * 
128      * @param context A subcontext named for the <code>on.getDomain()</code>
129      * (Assumption is that caller already setup this subcontext).
130      * @param on The ObjectName we're to base our bind name on.
131      * @return Returns key we used binding this ObjectName.
132      * @throws NamingException
133      * @throws NullPointerException
134      */
135     public static CompoundName bindObjectName(Context context,
136             final ObjectName on)
137     throws NamingException, NullPointerException {
138         // I can't call getNameInNamespace in tomcat. Complains about
139         // unsupported operation -- that I can't get absolute name.
140         // Therefore just skip this test below -- at least for now.
141         // Check that passed context has the passed ObjectNames' name.
142         //
143 //        String name = getCompoundName(context.getNameInNamespace()).toString();
144 //        if (!name.equals(on.getDomain())) {
145 //            throw new NamingException("The current context is " + name +
146 //                " but domain is " + on.getDomain() + " (Was expecting " +
147 //                "them to be the same).");
148 //        }
149         CompoundName key = getCompoundName(on);
150         context.rebind(key, getReference(on));
151         return key;
152     }
153     
154     public static CompoundName unbindObjectName(final Context context,
155             final ObjectName on)
156     throws NullPointerException, NamingException {
157         CompoundName key = getCompoundName(on);
158         context.unbind(key);
159         return key;
160     }
161 
162 
163     /***
164      * Testing code.
165      * @param args Command line arguments.
166      * @throws NullPointerException 
167      * @throws MalformedObjectNameException 
168      * @throws NamingException 
169      * @throws InvalidNameException 
170      */
171     public static void main(String[] args)
172     throws MalformedObjectNameException, NullPointerException,
173     InvalidNameException, NamingException {
174         final ObjectName on = new ObjectName("org.archive.crawler:" +
175                 "type=Service,name=Heritrix00,host=debord.archive.org");
176         Context c = getSubContext(getCompoundName(on.getDomain()));
177         CompoundName key = bindObjectName(c, on);
178         Reference r = (Reference)c.lookup(key);
179         for (Enumeration e = r.getAll(); e.hasMoreElements();) {
180             System.out.println(e.nextElement());
181         }
182         unbindObjectName(c, on);
183     }
184 }