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