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