Coverage Report - org.apache.camel.util.jndi.JndiContext
 
Classes in this File Line Coverage Branch Coverage Complexity
JndiContext
35% 
62% 
0
 
 1  
 /**
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.camel.util.jndi;
 18  
 
 19  
 import java.io.Serializable;
 20  
 import java.util.HashMap;
 21  
 import java.util.Hashtable;
 22  
 import java.util.Iterator;
 23  
 import java.util.Map;
 24  
 
 25  
 import javax.naming.Binding;
 26  
 import javax.naming.CompositeName;
 27  
 import javax.naming.Context;
 28  
 import javax.naming.LinkRef;
 29  
 import javax.naming.Name;
 30  
 import javax.naming.NameClassPair;
 31  
 import javax.naming.NameNotFoundException;
 32  
 import javax.naming.NameParser;
 33  
 import javax.naming.NamingEnumeration;
 34  
 import javax.naming.NamingException;
 35  
 import javax.naming.NotContextException;
 36  
 import javax.naming.OperationNotSupportedException;
 37  
 import javax.naming.Reference;
 38  
 import javax.naming.spi.NamingManager;
 39  
 
 40  
 import org.apache.camel.impl.ReflectionInjector;
 41  
 import org.apache.camel.spi.Injector;
 42  
 import org.apache.camel.util.IntrospectionSupport;
 43  
 import org.apache.camel.util.ObjectHelper;
 44  
 
 45  
 /**
 46  
  * A default JNDI context
 47  
  * 
 48  
  * @version $Revision: 1.2 $ $Date: 2005/08/27 03:52:39 $
 49  
  */
 50  3
 public class JndiContext implements Context, Serializable {
 51  
     public static final String SEPARATOR = "/";
 52  3
     protected static final NameParser NAME_PARSER = new NameParser() {
 53  3
         public Name parse(String name) throws NamingException {
 54  0
             return new CompositeName(name);
 55  
         }
 56  
     };
 57  3
     protected static final Injector INJETOR = new ReflectionInjector();
 58  
     private static final long serialVersionUID = -5754338187296859149L;
 59  
         
 60  
     private final Hashtable environment; // environment for this context
 61  
     private final Map bindings; // bindings at my level
 62  
     private final Map treeBindings; // all bindings under me
 63  
     private boolean frozen;
 64  228
     private String nameInNamespace = "";
 65  
 
 66  
     public JndiContext() {
 67  6
         this(new Hashtable());
 68  6
     }
 69  
 
 70  
     public JndiContext(Hashtable env) {
 71  228
         this(env, createBindingsMapFromEnvironment(env));
 72  228
     }
 73  
 
 74  228
     public JndiContext(Hashtable environment, Map bindings) {
 75  228
         if (environment == null) {
 76  0
             this.environment = new Hashtable();
 77  0
         } else {
 78  228
             this.environment = new Hashtable(environment);
 79  
         }
 80  228
         this.bindings = bindings;
 81  228
         treeBindings = new HashMap();
 82  228
     }
 83  
 
 84  
     public JndiContext(Hashtable environment, Map bindings, String nameInNamespace) {
 85  0
         this(environment, bindings);
 86  0
         this.nameInNamespace = nameInNamespace;
 87  0
     }
 88  
 
 89  0
     protected JndiContext(JndiContext clone, Hashtable env) {
 90  0
         this.bindings = clone.bindings;
 91  0
         this.treeBindings = clone.treeBindings;
 92  0
         this.environment = new Hashtable(env);
 93  0
     }
 94  
 
 95  
     protected JndiContext(JndiContext clone, Hashtable env, String nameInNamespace) {
 96  0
         this(clone, env);
 97  0
         this.nameInNamespace = nameInNamespace;
 98  0
     }
 99  
     
 100  
     /**
 101  
      * A helper method to create the JNDI bindings from the input environment
 102  
      * properties using $foo.class to point to a class name with $foo.* being
 103  
      * properties set on the injected bean
 104  
      */
 105  
     public static Map createBindingsMapFromEnvironment(Hashtable env) {
 106  228
         Map answer = new HashMap(env);
 107  
 
 108  228
         for (Object object : env.entrySet()) {
 109  1110
             Map.Entry entry = (Map.Entry)object;
 110  1110
             Object key = entry.getKey();
 111  1110
             Object value = entry.getValue();
 112  
 
 113  1110
             if (key instanceof String && value instanceof String) {
 114  1110
                 String keyText = (String)key;
 115  1110
                 String valueText = (String)value;
 116  1110
                 if (keyText.endsWith(".class")) {
 117  222
                     Class<?> type = ObjectHelper.loadClass(valueText);
 118  222
                     if (type != null) {
 119  222
                         String newEntry = keyText.substring(0, keyText.length() - ".class".length());
 120  222
                         Object bean = createBean(type, answer, newEntry + ".");
 121  222
                         if (bean != null) {
 122  222
                             answer.put(newEntry, bean);
 123  
                         }
 124  
                     }
 125  
                 }
 126  
             }
 127  1110
         }
 128  
 
 129  228
         return answer;
 130  
     }
 131  
 
 132  
     public void freeze() {
 133  0
         frozen = true;
 134  0
     }
 135  
 
 136  
     boolean isFrozen() {
 137  9
         return frozen;
 138  
     }
 139  
 
 140  
     /**
 141  
      * internalBind is intended for use only during setup or possibly by
 142  
      * suitably synchronized superclasses. It binds every possible lookup into a
 143  
      * map in each context. To do this, each context strips off one name segment
 144  
      * and if necessary creates a new context for it. Then it asks that context
 145  
      * to bind the remaining name. It returns a map containing all the bindings
 146  
      * from the next context, plus the context it just created (if it in fact
 147  
      * created it). (the names are suitably extended by the segment originally
 148  
      * lopped off).
 149  
      * 
 150  
      * @param name
 151  
      * @param value
 152  
      * @return
 153  
      * @throws javax.naming.NamingException
 154  
      */
 155  
     protected Map internalBind(String name, Object value) throws NamingException {
 156  9
         assert name != null && name.length() > 0;
 157  9
         assert !frozen;
 158  
 
 159  9
         Map newBindings = new HashMap();
 160  9
         int pos = name.indexOf('/');
 161  9
         if (pos == -1) {
 162  9
             if (treeBindings.put(name, value) != null) {
 163  0
                 throw new NamingException("Something already bound at " + name);
 164  
             }
 165  9
             bindings.put(name, value);
 166  9
             newBindings.put(name, value);
 167  9
         } else {
 168  0
             String segment = name.substring(0, pos);
 169  0
             assert segment != null;
 170  0
             assert !segment.equals("");
 171  0
             Object o = treeBindings.get(segment);
 172  0
             if (o == null) {
 173  0
                 o = newContext();
 174  0
                 treeBindings.put(segment, o);
 175  0
                 bindings.put(segment, o);
 176  0
                 newBindings.put(segment, o);
 177  0
             } else if (!(o instanceof JndiContext)) {
 178  0
                 throw new NamingException("Something already bound where a subcontext should go");
 179  
             }
 180  0
             JndiContext defaultContext = (JndiContext)o;
 181  0
             String remainder = name.substring(pos + 1);
 182  0
             Map subBindings = defaultContext.internalBind(remainder, value);
 183  0
             for (Iterator iterator = subBindings.entrySet().iterator(); iterator.hasNext();) {
 184  0
                 Map.Entry entry = (Map.Entry)iterator.next();
 185  0
                 String subName = segment + "/" + (String)entry.getKey();
 186  0
                 Object bound = entry.getValue();
 187  0
                 treeBindings.put(subName, bound);
 188  0
                 newBindings.put(subName, bound);
 189  0
             }
 190  
         }
 191  9
         return newBindings;
 192  
     }
 193  
 
 194  
     protected JndiContext newContext() {
 195  0
         return new JndiContext();
 196  
     }
 197  
 
 198  
     public Object addToEnvironment(String propName, Object propVal) throws NamingException {
 199  0
         return environment.put(propName, propVal);
 200  
     }
 201  
 
 202  
     public Hashtable getEnvironment() throws NamingException {
 203  0
         return (Hashtable)environment.clone();
 204  
     }
 205  
 
 206  
     public Object removeFromEnvironment(String propName) throws NamingException {
 207  0
         return environment.remove(propName);
 208  
     }
 209  
 
 210  
     public Object lookup(String name) throws NamingException {
 211  33
         if (name.length() == 0) {
 212  0
             return this;
 213  
         }
 214  33
         Object result = treeBindings.get(name);
 215  33
         if (result == null) {
 216  24
             result = bindings.get(name);
 217  
         }
 218  33
         if (result == null) {
 219  15
             int pos = name.indexOf(':');
 220  15
             if (pos > 0) {
 221  0
                 String scheme = name.substring(0, pos);
 222  0
                 Context ctx = NamingManager.getURLContext(scheme, environment);
 223  0
                 if (ctx == null) {
 224  0
                     throw new NamingException("scheme " + scheme + " not recognized");
 225  
                 }
 226  0
                 return ctx.lookup(name);
 227  
             } else {
 228  
                 // Split out the first name of the path
 229  
                 // and look for it in the bindings map.
 230  15
                 CompositeName path = new CompositeName(name);
 231  
 
 232  15
                 if (path.size() == 0) {
 233  0
                     return this;
 234  
                 } else {
 235  15
                     String first = path.get(0);
 236  15
                     Object value = bindings.get(first);
 237  15
                     if (value == null) {
 238  15
                         throw new NameNotFoundException(name);
 239  0
                     } else if (value instanceof Context && path.size() > 1) {
 240  0
                         Context subContext = (Context)value;
 241  0
                         value = subContext.lookup(path.getSuffix(1));
 242  
                     }
 243  0
                     return value;
 244  
                 }
 245  
             }
 246  
         }
 247  18
         if (result instanceof LinkRef) {
 248  0
             LinkRef ref = (LinkRef)result;
 249  0
             result = lookup(ref.getLinkName());
 250  
         }
 251  18
         if (result instanceof Reference) {
 252  
             try {
 253  0
                 result = NamingManager.getObjectInstance(result, null, null, this.environment);
 254  0
             } catch (NamingException e) {
 255  0
                 throw e;
 256  0
             } catch (Exception e) {
 257  0
                 throw (NamingException)new NamingException("could not look up : " + name).initCause(e);
 258  0
             }
 259  
         }
 260  18
         if (result instanceof JndiContext) {
 261  0
             String prefix = getNameInNamespace();
 262  0
             if (prefix.length() > 0) {
 263  0
                 prefix = prefix + SEPARATOR;
 264  
             }
 265  0
             result = new JndiContext((JndiContext)result, environment, prefix + name);
 266  
         }
 267  18
         return result;
 268  
     }
 269  
 
 270  
     public Object lookup(Name name) throws NamingException {
 271  0
         return lookup(name.toString());
 272  
     }
 273  
 
 274  
     public Object lookupLink(String name) throws NamingException {
 275  0
         return lookup(name);
 276  
     }
 277  
 
 278  
     public Name composeName(Name name, Name prefix) throws NamingException {
 279  0
         Name result = (Name)prefix.clone();
 280  0
         result.addAll(name);
 281  0
         return result;
 282  
     }
 283  
 
 284  
     public String composeName(String name, String prefix) throws NamingException {
 285  0
         CompositeName result = new CompositeName(prefix);
 286  0
         result.addAll(new CompositeName(name));
 287  0
         return result.toString();
 288  
     }
 289  
 
 290  
     public NamingEnumeration list(String name) throws NamingException {
 291  0
         Object o = lookup(name);
 292  0
         if (o == this) {
 293  0
             return new ListEnumeration();
 294  0
         } else if (o instanceof Context) {
 295  0
             return ((Context)o).list("");
 296  
         } else {
 297  0
             throw new NotContextException();
 298  
         }
 299  
     }
 300  
 
 301  
     public NamingEnumeration listBindings(String name) throws NamingException {
 302  0
         Object o = lookup(name);
 303  0
         if (o == this) {
 304  0
             return new ListBindingEnumeration();
 305  0
         } else if (o instanceof Context) {
 306  0
             return ((Context)o).listBindings("");
 307  
         } else {
 308  0
             throw new NotContextException();
 309  
         }
 310  
     }
 311  
 
 312  
     public Object lookupLink(Name name) throws NamingException {
 313  0
         return lookupLink(name.toString());
 314  
     }
 315  
 
 316  
     public NamingEnumeration list(Name name) throws NamingException {
 317  0
         return list(name.toString());
 318  
     }
 319  
 
 320  
     public NamingEnumeration listBindings(Name name) throws NamingException {
 321  0
         return listBindings(name.toString());
 322  
     }
 323  
 
 324  
     public void bind(Name name, Object value) throws NamingException {
 325  0
         bind(name.toString(), value);
 326  0
     }
 327  
 
 328  
     public void bind(String name, Object value) throws NamingException {
 329  9
         if (isFrozen()) {
 330  0
             throw new OperationNotSupportedException();
 331  
         } else {
 332  9
             internalBind(name, value);
 333  
         }
 334  9
     }
 335  
 
 336  
     public void close() throws NamingException {
 337  
         // ignore
 338  0
     }
 339  
 
 340  
     public Context createSubcontext(Name name) throws NamingException {
 341  0
         throw new OperationNotSupportedException();
 342  
     }
 343  
 
 344  
     public Context createSubcontext(String name) throws NamingException {
 345  0
         throw new OperationNotSupportedException();
 346  
     }
 347  
 
 348  
     public void destroySubcontext(Name name) throws NamingException {
 349  0
         throw new OperationNotSupportedException();
 350  
     }
 351  
 
 352  
     public void destroySubcontext(String name) throws NamingException {
 353  0
         throw new OperationNotSupportedException();
 354  
     }
 355  
 
 356  
     public String getNameInNamespace() throws NamingException {
 357  0
         return nameInNamespace;
 358  
     }
 359  
 
 360  
     public NameParser getNameParser(Name name) throws NamingException {
 361  0
         return NAME_PARSER;
 362  
     }
 363  
 
 364  
     public NameParser getNameParser(String name) throws NamingException {
 365  0
         return NAME_PARSER;
 366  
     }
 367  
 
 368  
     public void rebind(Name name, Object value) throws NamingException {
 369  0
         bind(name, value);
 370  0
     }
 371  
 
 372  
     public void rebind(String name, Object value) throws NamingException {
 373  0
         bind(name, value);
 374  0
     }
 375  
 
 376  
     public void rename(Name oldName, Name newName) throws NamingException {
 377  0
         throw new OperationNotSupportedException();
 378  
     }
 379  
 
 380  
     public void rename(String oldName, String newName) throws NamingException {
 381  0
         throw new OperationNotSupportedException();
 382  
     }
 383  
 
 384  
     public void unbind(Name name) throws NamingException {
 385  0
         throw new OperationNotSupportedException();
 386  
     }
 387  
 
 388  
     public void unbind(String name) throws NamingException {
 389  0
         throw new OperationNotSupportedException();
 390  
     }
 391  
 
 392  0
     private abstract class LocalNamingEnumeration implements NamingEnumeration {
 393  0
         private Iterator i = bindings.entrySet().iterator();
 394  
 
 395  
         public boolean hasMore() throws NamingException {
 396  0
             return i.hasNext();
 397  
         }
 398  
 
 399  
         public boolean hasMoreElements() {
 400  0
             return i.hasNext();
 401  
         }
 402  
 
 403  
         protected Map.Entry getNext() {
 404  0
             return (Map.Entry)i.next();
 405  
         }
 406  
 
 407  
         public void close() throws NamingException {
 408  0
         }
 409  
     }
 410  
 
 411  
     private class ListEnumeration extends LocalNamingEnumeration {
 412  0
         ListEnumeration() {
 413  0
         }
 414  
 
 415  
         public Object next() throws NamingException {
 416  0
             return nextElement();
 417  
         }
 418  
 
 419  
         public Object nextElement() {
 420  0
             Map.Entry entry = getNext();
 421  0
             return new NameClassPair((String)entry.getKey(), entry.getValue().getClass().getName());
 422  
         }
 423  
     }
 424  
 
 425  
     private class ListBindingEnumeration extends LocalNamingEnumeration {
 426  0
         ListBindingEnumeration() {
 427  0
         }
 428  
 
 429  
         public Object next() throws NamingException {
 430  0
             return nextElement();
 431  
         }
 432  
 
 433  
         public Object nextElement() {
 434  0
             Map.Entry entry = getNext();
 435  0
             return new Binding((String)entry.getKey(), entry.getValue());
 436  
         }
 437  
     }
 438  
 
 439  
     protected static Object createBean(Class<?> type, Map properties, String prefix) {
 440  222
         Object value = INJETOR.newInstance(type);
 441  222
         IntrospectionSupport.setProperties(value, properties, prefix);
 442  222
         return value;
 443  
     }
 444  
 }