View Javadoc

1   // ========================================================================
2   // $Id: NamingEntry.java 4027 2008-11-12 00:59:06Z janb $
3   // Copyright 2006 Mort Bay Consulting Pty. Ltd.
4   // ------------------------------------------------------------------------
5   // Licensed under the Apache License, Version 2.0 (the "License");
6   // you may not use this file except in compliance with the License.
7   // You may obtain a copy of the License at 
8   // http://www.apache.org/licenses/LICENSE-2.0
9   // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  // ========================================================================
15  
16  package org.mortbay.jetty.plus.naming;
17  
18  import javax.naming.Context;
19  import javax.naming.InitialContext;
20  import javax.naming.LinkRef;
21  import javax.naming.Name;
22  import javax.naming.NameParser;
23  import javax.naming.NamingException;
24  
25  import org.mortbay.log.Log;
26  import org.mortbay.naming.NamingUtil;
27  
28  
29  
30  /**
31   * NamingEntry
32   *
33   * Base class for all jndi related entities. Instances of
34   * subclasses of this class are declared in jetty.xml or in a 
35   * webapp's WEB-INF/jetty-env.xml file.
36   *
37   * NOTE: that all NamingEntries will be bound in a single namespace.
38   *  The "global" level is just in the top level context. The "local"
39   *  level is a context specific to a webapp.
40   */
41  public abstract class NamingEntry
42  {
43      public static final String __contextName = "__"; //all NamingEntries stored in context called "__"
44      protected String jndiName;  //the name representing the object associated with the NamingEntry
45      protected Object objectToBind; //the object associated with the NamingEntry
46      protected String namingEntryNameString; //the name of the NamingEntry relative to the context it is stored in
47      protected String objectNameString; //the name of the object relative to the context it is stored in
48     
49     
50    
51   
52      
53      public NamingEntry (Object scope, String jndiName, Object object)
54      throws NamingException
55      {
56          this.jndiName = jndiName;
57          this.objectToBind = object;
58          save(scope); 
59      }
60      
61      /** 
62       * Create a NamingEntry. 
63       * A NamingEntry is a name associated with a value which can later
64       * be looked up in JNDI by a webapp.
65       * 
66       * We create the NamingEntry and put it into JNDI where it can
67       * be linked to the webapp's env-entry, resource-ref etc entries.
68       * 
69       * @param jndiName the name of the object which will eventually be in java:comp/env
70       * @param object the object to be bound
71       * @throws NamingException
72       */
73      public NamingEntry (String jndiName, Object object)
74      throws NamingException
75      {
76          this (null, jndiName, object);
77      }
78  
79      
80   
81      
82      /**
83       * Add a java:comp/env binding for the object represented by this NamingEntry,
84       * but bind it as the name supplied
85       * @throws NamingException
86       */
87      public void bindToENC(String localName)
88      throws NamingException
89      {
90          //TODO - check on the whole overriding/non-overriding thing
91          InitialContext ic = new InitialContext();
92          Context env = (Context)ic.lookup("java:comp/env");
93          Log.debug("Binding java:comp/env/"+localName+" to "+objectNameString);
94          NamingUtil.bind(env, localName, new LinkRef(objectNameString));
95      }
96      
97      /**
98       * Unbind this NamingEntry from a java:comp/env
99       */
100     public void unbindENC ()
101     {
102         try
103         {
104             InitialContext ic = new InitialContext();
105             Context env = (Context)ic.lookup("java:comp/env");
106             Log.debug("Unbinding java:comp/env/"+getJndiName());
107             env.unbind(getJndiName());
108         }
109         catch (NamingException e)
110         {
111             Log.warn(e);
112         }
113     }
114     
115     /**
116      * Unbind this NamingEntry entirely
117      */
118     public void release ()
119     {
120         try
121         {
122             InitialContext ic = new InitialContext();
123             ic.unbind(objectNameString);
124             ic.unbind(namingEntryNameString);
125             this.jndiName=null;
126             this.namingEntryNameString=null;
127             this.objectNameString=null;
128             this.objectToBind=null;
129         }
130         catch (NamingException e)
131         {
132             Log.warn(e);
133         }
134     }
135     
136     /**
137      * Get the unique name of the object
138      * relative to the scope
139      * @return
140      */
141     public String getJndiName ()
142     {
143         return this.jndiName;
144     }
145     
146     /**
147      * Get the object that is to be bound
148      * @return
149      */
150     public Object getObjectToBind()
151     throws NamingException
152     {   
153         return this.objectToBind;
154     }
155     
156 
157     /**
158      * Get the name of the object, fully
159      * qualified with the scope
160      * @return
161      */
162     public String getJndiNameInScope ()
163     {
164         return objectNameString;
165     }
166  
167  
168     
169     /**
170      * Save the NamingEntry for later use.
171      * 
172      * Saving is done by binding the NamingEntry
173      * itself, and the value it represents into
174      * JNDI. In this way, we can link to the
175      * value it represents later, but also
176      * still retrieve the NamingEntry itself too.
177      * 
178      * The object is bound at the jndiName passed in.
179      * This NamingEntry is bound at __/jndiName.
180      * 
181      * eg
182      * 
183      * jdbc/foo    : DataSource
184      * __/jdbc/foo : NamingEntry
185      * 
186      * @throws NamingException
187      */
188     protected void save (Object scope)
189     throws NamingException
190     {
191         InitialContext ic = new InitialContext();
192         NameParser parser = ic.getNameParser("");
193         Name prefix = NamingEntryUtil.getNameForScope(scope);
194       
195         //bind the NamingEntry into the context
196         Name namingEntryName = NamingEntryUtil.makeNamingEntryName(parser, getJndiName());
197         namingEntryName.addAll(0, prefix);
198         namingEntryNameString = namingEntryName.toString();
199         NamingUtil.bind(ic, namingEntryNameString, this);
200                 
201         //bind the object as well
202         Name objectName = parser.parse(getJndiName());
203         objectName.addAll(0, prefix);
204         objectNameString = objectName.toString();
205         NamingUtil.bind(ic, objectNameString, objectToBind);
206     } 
207     
208 }