001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jnp.server;
023:
024: import java.util.Collection;
025: import java.util.Enumeration;
026: import java.util.Hashtable;
027: import java.util.Iterator;
028: import java.util.Vector;
029: import javax.naming.Binding;
030: import javax.naming.CannotProceedException;
031: import javax.naming.Context;
032: import javax.naming.InvalidNameException;
033: import javax.naming.Name;
034: import javax.naming.NameAlreadyBoundException;
035: import javax.naming.NameClassPair;
036: import javax.naming.NameNotFoundException;
037: import javax.naming.NamingException;
038: import javax.naming.NotContextException;
039: import javax.naming.Reference;
040: import javax.naming.spi.ResolveResult;
041:
042: import org.jnp.interfaces.Naming;
043: import org.jnp.interfaces.NamingContext;
044: import org.jnp.interfaces.NamingParser;
045: import org.jboss.logging.Logger;
046:
047: /**
048: * The JNDI naming server implementation class.
049: *
050: * @author Rickard Oberg
051: * @author patriot1burke
052: * @author Scott.Stark@jboss.org
053: * @version $Revision: 57199 $
054: */
055: public class NamingServer implements Naming, java.io.Serializable {
056: private static Logger log = Logger.getLogger(NamingServer.class);
057:
058: /** @since 1.12 at least */
059: private static final long serialVersionUID = 4183855539507934373L;
060: // Constants -----------------------------------------------------
061:
062: // Attributes ----------------------------------------------------
063:
064: protected Hashtable table = new Hashtable();
065: protected Name prefix;
066: protected NamingParser parser = new NamingParser();
067: protected NamingServer parent;
068:
069: // Static --------------------------------------------------------
070:
071: // Constructors --------------------------------------------------
072: public NamingServer() throws NamingException {
073: this (null, null);
074: }
075:
076: public NamingServer(Name prefix, NamingServer parent)
077: throws NamingException {
078: if (prefix == null)
079: prefix = parser.parse("");
080: this .prefix = prefix;
081:
082: this .parent = parent;
083: }
084:
085: // Public --------------------------------------------------------
086:
087: // Naming implementation -----------------------------------------
088: public synchronized void bind(Name name, Object obj,
089: String className) throws NamingException {
090: if (name.isEmpty()) {
091: // Empty names are not allowed
092: throw new InvalidNameException();
093: } else if (name.size() > 1) {
094: // Recurse to find correct context
095: // System.out.println("bind#"+name+"#");
096:
097: Object ctx = getObject(name);
098: if (ctx != null) {
099: if (ctx instanceof NamingServer) {
100: ((NamingServer) ctx).bind(name.getSuffix(1), obj,
101: className);
102: } else if (ctx instanceof Reference) {
103: // Federation
104: if (((Reference) ctx).get("nns") != null) {
105: CannotProceedException cpe = new CannotProceedException();
106: cpe.setResolvedObj(ctx);
107: cpe.setRemainingName(name.getSuffix(1));
108: throw cpe;
109: } else {
110: throw new NotContextException();
111: }
112: } else {
113: throw new NotContextException();
114: }
115: } else {
116: throw new NameNotFoundException();
117: }
118: } else {
119: // Bind object
120: if (name.get(0).equals("")) {
121: throw new InvalidNameException();
122: } else {
123: // System.out.println("bind "+name+"="+obj);
124: try {
125: getBinding(name);
126: // Already bound
127: throw new NameAlreadyBoundException();
128: } catch (NameNotFoundException e) {
129: setBinding(name, obj, className);
130: }
131: }
132: }
133: }
134:
135: public synchronized void rebind(Name name, Object obj,
136: String className) throws NamingException {
137: if (name.isEmpty()) {
138: // Empty names are not allowed
139: throw new InvalidNameException();
140: } else if (name.size() > 1) {
141: // Recurse to find correct context
142: // System.out.println("rebind#"+name+"#");
143:
144: Object ctx = getObject(name);
145: if (ctx instanceof NamingServer) {
146: ((NamingServer) ctx).rebind(name.getSuffix(1), obj,
147: className);
148: } else if (ctx instanceof Reference) {
149: // Federation
150: if (((Reference) ctx).get("nns") != null) {
151: CannotProceedException cpe = new CannotProceedException();
152: cpe.setResolvedObj(ctx);
153: cpe.setRemainingName(name.getSuffix(1));
154: throw cpe;
155: } else {
156: throw new NotContextException();
157: }
158: } else {
159: throw new NotContextException();
160: }
161: } else {
162: // Bind object
163: if (name.get(0).equals("")) {
164: throw new InvalidNameException();
165: } else {
166: // System.out.println("rebind "+name+"="+obj+"("+this+")");
167: setBinding(name, obj, className);
168: }
169: }
170: }
171:
172: public synchronized void unbind(Name name) throws NamingException {
173: if (name.isEmpty()) {
174: // Empty names are not allowed
175: throw new InvalidNameException();
176: } else if (name.size() > 1) {
177: // Recurse to find correct context
178: // System.out.println("unbind#"+name+"#");
179:
180: Object ctx = getObject(name);
181: if (ctx instanceof NamingServer) {
182: ((NamingServer) ctx).unbind(name.getSuffix(1));
183: } else if (ctx instanceof Reference) {
184: // Federation
185: if (((Reference) ctx).get("nns") != null) {
186: CannotProceedException cpe = new CannotProceedException();
187: cpe.setResolvedObj(ctx);
188: cpe.setRemainingName(name.getSuffix(1));
189: throw cpe;
190: } else {
191: throw new NotContextException();
192: }
193: } else {
194: throw new NotContextException();
195: }
196: } else {
197: // Unbind object
198: if (name.get(0).equals("")) {
199: throw new InvalidNameException();
200: } else {
201: // System.out.println("unbind "+name+"="+getBinding(name));
202: if (getBinding(name) != null) {
203: removeBinding(name);
204: } else {
205: throw new NameNotFoundException();
206: }
207: }
208: }
209: }
210:
211: // public synchronized Object lookup(Name name)
212: public Object lookup(Name name) throws NamingException {
213: Object result;
214: if (name.isEmpty()) {
215: // Return this
216: result = new NamingContext(null, (Name) (prefix.clone()),
217: getRoot());
218: } else if (name.size() > 1) {
219: // Recurse to find correct context
220: // System.out.println("lookup#"+name+"#");
221:
222: Object ctx = getObject(name);
223: if (ctx instanceof NamingServer) {
224: result = ((NamingServer) ctx).lookup(name.getSuffix(1));
225: } else if (ctx instanceof Reference) {
226: // Federation
227: if (((Reference) ctx).get("nns") != null) {
228: CannotProceedException cpe = new CannotProceedException();
229: cpe.setResolvedObj(ctx);
230: cpe.setRemainingName(name.getSuffix(1));
231: throw cpe;
232: }
233:
234: result = new ResolveResult(ctx, name.getSuffix(1));
235: } else {
236: throw new NotContextException();
237: }
238: } else {
239: // Get object to return
240: if (name.get(0).equals("")) {
241: result = new NamingContext(null, prefix, getRoot());
242: } else {
243: // System.out.println("lookup "+name);
244: Object res = getObject(name);
245:
246: if (res instanceof NamingServer) {
247: Name fullName = (Name) (prefix.clone());
248: fullName.addAll(name);
249: result = new NamingContext(null, fullName,
250: getRoot());
251: } else
252: result = res;
253: }
254: }
255:
256: return result;
257: }
258:
259: public Collection list(Name name) throws NamingException {
260: // System.out.println("list of #"+name+"#"+name.size());
261: if (name.isEmpty()) {
262: // System.out.println("list "+name);
263:
264: Vector list = new Vector();
265: Enumeration keys = table.keys();
266: while (keys.hasMoreElements()) {
267: String key = (String) keys.nextElement();
268: Binding b = getBinding(key);
269:
270: list.addElement(new NameClassPair(b.getName(), b
271: .getClassName(), true));
272: }
273: return list;
274: } else {
275: // System.out.println("list#"+name+"#");
276:
277: Object ctx = getObject(name);
278: if (ctx instanceof NamingServer) {
279: return ((NamingServer) ctx).list(name.getSuffix(1));
280: } else if (ctx instanceof Reference) {
281: // Federation
282: if (((Reference) ctx).get("nns") != null) {
283: CannotProceedException cpe = new CannotProceedException();
284: cpe.setResolvedObj(ctx);
285: cpe.setRemainingName(name.getSuffix(1));
286: throw cpe;
287: } else {
288: throw new NotContextException();
289: }
290: } else {
291: throw new NotContextException();
292: }
293: }
294: }
295:
296: public Collection listBindings(Name name) throws NamingException {
297: if (name.isEmpty()) {
298: Collection bindings = table.values();
299: Collection newBindings = new Vector(bindings.size());
300: Iterator iter = bindings.iterator();
301: while (iter.hasNext()) {
302: Binding b = (Binding) iter.next();
303: if (b.getObject() instanceof NamingServer) {
304: Name n = (Name) prefix.clone();
305: n.add(b.getName());
306: newBindings.add(new Binding(b.getName(), b
307: .getClassName(), new NamingContext(null, n,
308: getRoot())));
309: } else {
310: newBindings.add(b);
311: }
312: }
313:
314: return newBindings;
315: } else {
316: Object ctx = getObject(name);
317: if (ctx instanceof NamingServer) {
318: return ((NamingServer) ctx).listBindings(name
319: .getSuffix(1));
320: } else if (ctx instanceof Reference) {
321: // Federation
322: if (((Reference) ctx).get("nns") != null) {
323: CannotProceedException cpe = new CannotProceedException();
324: cpe.setResolvedObj(ctx);
325: cpe.setRemainingName(name.getSuffix(1));
326: throw cpe;
327: } else {
328: throw new NotContextException();
329: }
330: } else {
331: throw new NotContextException();
332: }
333: }
334: }
335:
336: public Context createSubcontext(Name name) throws NamingException {
337: if (name.size() == 0)
338: throw new InvalidNameException(
339: "Cannot pass an empty name to createSubcontext");
340:
341: NamingException ex = null;
342: Context subCtx = null;
343: if (name.size() > 1) {
344: Object ctx = getObject(name);
345: if (ctx != null) {
346: Name subCtxName = name.getSuffix(1);
347: if (ctx instanceof NamingServer) {
348: subCtx = ((NamingServer) ctx)
349: .createSubcontext(subCtxName);
350: } else if (ctx instanceof Reference) {
351: // Federation
352: if (((Reference) ctx).get("nns") != null) {
353: CannotProceedException cpe = new CannotProceedException();
354: cpe.setResolvedObj(ctx);
355: cpe.setRemainingName(subCtxName);
356: throw cpe;
357: } else {
358: ex = new NotContextException();
359: ex.setResolvedName(name.getPrefix(0));
360: ex.setRemainingName(subCtxName);
361: throw ex;
362: }
363: } else {
364: ex = new NotContextException();
365: ex.setResolvedName(name.getPrefix(0));
366: ex.setRemainingName(subCtxName);
367: throw ex;
368: }
369: } else {
370: ex = new NameNotFoundException();
371: ex.setRemainingName(name);
372: throw ex;
373: }
374: } else {
375: Object binding = table.get(name.get(0));
376: if (binding != null) {
377: ex = new NameAlreadyBoundException();
378: ex.setResolvedName(prefix);
379: ex.setRemainingName(name);
380: throw ex;
381: } else {
382: Name fullName = (Name) prefix.clone();
383: fullName.addAll(name);
384: NamingServer subContext = new NamingServer(fullName,
385: this );
386: setBinding(name, subContext, NamingContext.class
387: .getName());
388: subCtx = new NamingContext(null, fullName, getRoot());
389: }
390: }
391: return subCtx;
392: }
393:
394: public Naming getRoot() {
395: if (parent == null)
396: return this ;
397: else
398: return parent.getRoot();
399: }
400:
401: // Y overrides ---------------------------------------------------
402:
403: // Package protected ---------------------------------------------
404:
405: // Protected -----------------------------------------------------
406:
407: // Private -------------------------------------------------------
408: private void setBinding(Name name, Object obj, String className) {
409: String n = name.toString();
410: table.put(n, new Binding(n, className, obj, true));
411: }
412:
413: private Binding getBinding(String key) throws NameNotFoundException {
414: Binding b = (Binding) table.get(key);
415: if (b == null) {
416: if (log.isTraceEnabled()) {
417: StringBuffer tmp = new StringBuffer("No binding for: "
418: + key);
419: tmp.append(" in context ");
420: tmp.append(this .prefix);
421: tmp.append(", bindings:\n");
422: Iterator bindings = table.values().iterator();
423: while (bindings.hasNext()) {
424: Binding value = (Binding) bindings.next();
425: tmp.append(value.getName());
426: tmp.append('=');
427: if (value.getObject() != null)
428: tmp.append(value.getObject().toString());
429: else
430: tmp.append("null");
431: tmp.append('\n');
432: }
433: log.trace(tmp.toString());
434: }
435: throw new NameNotFoundException(key + " not bound");
436: }
437: return b;
438: }
439:
440: private Binding getBinding(Name key) throws NameNotFoundException {
441: return getBinding(key.get(0));
442: }
443:
444: private Object getObject(Name key) throws NameNotFoundException {
445: return getBinding(key).getObject();
446: }
447:
448: private void removeBinding(Name name) {
449: table.remove(name.get(0));
450: }
451:
452: }
|