    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 }