View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.plus.jndi;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.List;
24  
25  import javax.naming.Binding;
26  import javax.naming.Context;
27  import javax.naming.InitialContext;
28  import javax.naming.Name;
29  import javax.naming.NameNotFoundException;
30  import javax.naming.NameParser;
31  import javax.naming.NamingEnumeration;
32  import javax.naming.NamingException;
33  
34  import org.eclipse.jetty.jndi.NamingUtil;
35  import org.eclipse.jetty.util.log.Logger;
36  
37  
38  public class NamingEntryUtil
39  {
40      private static Logger __log = NamingUtil.__log;
41  
42      /**
43       * Link a name in a webapp's java:/comp/evn namespace to a pre-existing
44       * resource. The pre-existing resource can be either in the webapp's
45       * naming environment, or in the container's naming environment. Webapp's
46       * environment takes precedence over the server's namespace.
47       *
48       * @param scope the scope of the lookup
49       * @param asName the name to bind as
50       * @param mappedName the name from the environment to link to asName
51       * @throws NamingException
52       */
53      public static boolean bindToENC (Object scope, String asName, String mappedName)
54      throws NamingException
55      {
56          if (asName==null||asName.trim().equals(""))
57              throw new NamingException ("No name for NamingEntry");
58  
59          if (mappedName==null || "".equals(mappedName))
60              mappedName=asName;
61  
62          NamingEntry entry = lookupNamingEntry (scope, mappedName);
63          if (entry == null)
64              return false;
65  
66          entry.bindToENC(asName);
67          return true;
68       }
69  
70  
71  
72  
73  
74      /**
75       * Find a NamingEntry in the given scope.
76       *
77       * @param scope
78       * @param jndiName
79       * @return the naming entry for the given scope
80       * @throws NamingException
81       */
82      public static NamingEntry lookupNamingEntry (Object scope, String jndiName)
83      throws NamingException
84      {
85          NamingEntry entry = null;
86          try
87          {
88              Name scopeName = getNameForScope(scope);
89              InitialContext ic = new InitialContext();
90              NameParser parser = ic.getNameParser("");
91              Name namingEntryName = makeNamingEntryName(parser, jndiName);
92              scopeName.addAll(namingEntryName);
93              entry =  (NamingEntry)ic.lookup(scopeName);
94          }
95          catch (NameNotFoundException ee)
96          {
97          }
98  
99          return entry;
100     }
101 
102     public static Object lookup(Object scope, String jndiName) throws NamingException
103     {
104         Name scopeName = getNameForScope(scope);
105         InitialContext ic = new InitialContext();
106         NameParser parser = ic.getNameParser("");
107         scopeName.addAll(parser.parse(jndiName));
108         return ic.lookup(scopeName);
109     }
110 
111     /**
112      * Get all NameEntries of a certain type in the given naming
113      * environment scope (server-wide names or context-specific names)
114      *
115      * @param scope
116      * @param clazz the type of the entry
117      * @return all NameEntries of a certain type in the given naming environment scope (server-wide names or context-specific names)
118      * @throws NamingException
119      */
120     public static List<Object> lookupNamingEntries (Object scope, Class<?> clazz)
121     throws NamingException
122     {
123         try
124         {
125             Context scopeContext = getContextForScope(scope);
126             Context namingEntriesContext = (Context)scopeContext.lookup(NamingEntry.__contextName);
127             ArrayList<Object> list = new ArrayList<Object>();
128             lookupNamingEntries(list, namingEntriesContext, clazz);
129             return list;
130         }
131         catch (NameNotFoundException e)
132         {
133             return Collections.emptyList();
134         }
135     }
136 
137 
138     public static Name makeNamingEntryName (NameParser parser, NamingEntry namingEntry)
139     throws NamingException
140     {
141         return makeNamingEntryName(parser, (namingEntry==null?null:namingEntry.getJndiName()));
142     }
143 
144     public static Name makeNamingEntryName (NameParser parser, String jndiName)
145     throws NamingException
146     {
147         if (jndiName==null)
148             return null;
149 
150         if (parser==null)
151         {
152             InitialContext ic = new InitialContext();
153             parser = ic.getNameParser("");
154         }
155 
156         Name name = parser.parse("");
157         name.add(NamingEntry.__contextName);
158         name.addAll(parser.parse(jndiName));
159         return name;
160     }
161 
162 
163     public static Name getNameForScope (Object scope)
164     {
165         try
166         {
167             InitialContext ic = new InitialContext();
168             NameParser parser = ic.getNameParser("");
169             Name name = parser.parse("");
170             if (scope != null)
171             {
172                 name.add(canonicalizeScope(scope));
173             }
174             return name;
175         }
176         catch (NamingException e)
177         {
178             __log.warn(e);
179             return null;
180         }
181     }
182 
183     public static Context getContextForScope(Object scope)
184     throws NamingException
185     {
186         InitialContext ic = new InitialContext();
187         NameParser parser = ic.getNameParser("");
188         Name name = parser.parse("");
189         if (scope != null)
190         {
191             name.add(canonicalizeScope(scope));
192         }
193         return (Context)ic.lookup(name);
194     }
195 
196     public static Context getContextForNamingEntries (Object scope)
197     throws NamingException
198     {
199         Context scopeContext = getContextForScope(scope);
200         return (Context)scopeContext.lookup(NamingEntry.__contextName);
201     }
202 
203     /**
204      * Build up a list of NamingEntry objects that are of a specific type.
205      *
206      * @param list
207      * @param context
208      * @param clazz
209      * @return
210      * @throws NamingException
211      */
212     private static List<Object> lookupNamingEntries (List<Object> list, Context context, Class<?> clazz)
213     throws NamingException
214     {
215         try
216         {
217             NamingEnumeration<Binding> nenum = context.listBindings("");
218             while (nenum.hasMoreElements())
219             {
220                 Binding binding = nenum.next();
221                 if (binding.getObject() instanceof Context)
222                     lookupNamingEntries (list, (Context)binding.getObject(), clazz);
223                 else if (clazz.isInstance(binding.getObject()))
224                   list.add(binding.getObject());
225             }
226         }
227         catch (NameNotFoundException e)
228         {
229             __log.debug("No entries of type "+clazz.getName()+" in context="+context);
230         }
231 
232         return list;
233     }
234 
235     private static String canonicalizeScope(Object scope)
236     {
237         if (scope==null)
238             return "";
239 
240         String str = scope.getClass().getName()+"@"+Long.toHexString(scope.hashCode());
241         str=str.replace('/', '_').replace(' ', '_');
242         return str;
243     }
244 }