Source code: org/jnp/server/NamingServer.java
1 /*
2 * Distributable under LGPL license.
3 * See terms of license at gnu.org.
4 *
5 * Copyright 1999 by dreamBean Software,
6 * All rights reserved.
7 */
8 package org.jnp.server;
9
10 import java.io.ObjectStreamException;
11 import java.io.NotSerializableException;
12 import java.rmi.RemoteException;
13 import java.rmi.server.UnicastRemoteObject;
14 import java.rmi.server.RemoteObject;
15 import java.util.Enumeration;
16 import java.util.Collection;
17 import java.util.Iterator;
18 import java.util.Hashtable;
19 import java.util.Vector;
20
21 import javax.naming.Context;
22 import javax.naming.Name;
23 import javax.naming.NameClassPair;
24 import javax.naming.Binding;
25 import javax.naming.Reference;
26 import javax.naming.NamingEnumeration;
27 import javax.naming.InvalidNameException;
28 import javax.naming.NamingException;
29 import javax.naming.InvalidNameException;
30 import javax.naming.NameNotFoundException;
31 import javax.naming.NotContextException;
32 import javax.naming.NameAlreadyBoundException;
33 import javax.naming.CannotProceedException;
34 import javax.naming.spi.ResolveResult;
35
36 import org.jnp.interfaces.*;
37
38 /**
39 * <description>
40 *
41 * @see <related>
42 * @author $Author: patriot1burke $
43 * @version $Revision: 1.9 $
44 */
45 public class NamingServer
46 implements Naming, java.io.Serializable
47 {
48 // Constants -----------------------------------------------------
49
50 // Attributes ----------------------------------------------------
51
52 protected Hashtable table = new Hashtable();
53 protected Name prefix;
54 protected NamingParser parser = new NamingParser();
55 protected NamingServer parent;
56
57 // Static --------------------------------------------------------
58
59 // Constructors --------------------------------------------------
60 public NamingServer()
61 throws NamingException
62 {
63 this(null, null);
64 }
65
66 public NamingServer(Name prefix, NamingServer parent)
67 throws NamingException
68 {
69 if (prefix == null) prefix = parser.parse("");
70 this.prefix = prefix;
71
72 this.parent = parent;
73 }
74
75 // Public --------------------------------------------------------
76
77 // Naming implementation -----------------------------------------
78 public synchronized void bind(Name name, Object obj, String className)
79 throws NamingException
80 {
81 if (name.isEmpty())
82 {
83 // Empty names are not allowed
84 throw new InvalidNameException();
85 } else if (name.size() > 1)
86 {
87 // Recurse to find correct context
88 // System.out.println("bind#"+name+"#");
89
90 Object ctx = getObject(name);
91 if (ctx != null)
92 {
93 if (ctx instanceof NamingServer)
94 {
95 ((NamingServer)ctx).bind(name.getSuffix(1),obj, className);
96 } else if (ctx instanceof Reference)
97 {
98 // Federation
99 if (((Reference)ctx).get("nns") != null)
100 {
101 CannotProceedException cpe = new CannotProceedException();
102 cpe.setResolvedObj(ctx);
103 cpe.setRemainingName(name.getSuffix(1));
104 throw cpe;
105 } else
106 {
107 throw new NotContextException();
108 }
109 } else
110 {
111 throw new NotContextException();
112 }
113 } else
114 {
115 throw new NameNotFoundException();
116 }
117 } else
118 {
119 // Bind object
120 if (name.get(0).equals(""))
121 {
122 throw new InvalidNameException();
123 } else
124 {
125 // System.out.println("bind "+name+"="+obj);
126 try
127 {
128 getBinding(name);
129 // Already bound
130 throw new NameAlreadyBoundException();
131 } catch (NameNotFoundException e)
132 {
133 setBinding(name,obj,className);
134 }
135 }
136 }
137 }
138
139 public synchronized void rebind(Name name, Object obj, String className)
140 throws NamingException
141 {
142 if (name.isEmpty())
143 {
144 // Empty names are not allowed
145 throw new InvalidNameException();
146 } else if (name.size() > 1)
147 {
148 // Recurse to find correct context
149 // System.out.println("rebind#"+name+"#");
150
151 Object ctx = getObject(name);
152 if (ctx instanceof NamingServer)
153 {
154 ((NamingServer)ctx).rebind(name.getSuffix(1),obj, className);
155 } else if (ctx instanceof Reference)
156 {
157 // Federation
158 if (((Reference)ctx).get("nns") != null)
159 {
160 CannotProceedException cpe = new CannotProceedException();
161 cpe.setResolvedObj(ctx);
162 cpe.setRemainingName(name.getSuffix(1));
163 throw cpe;
164 } else
165 {
166 throw new NotContextException();
167 }
168 } else
169 {
170 throw new NotContextException();
171 }
172 } else
173 {
174 // Bind object
175 if (name.get(0).equals(""))
176 {
177 throw new InvalidNameException();
178 } else
179 {
180 // System.out.println("rebind "+name+"="+obj+"("+this+")");
181 setBinding(name,obj,className);
182 }
183 }
184 }
185
186 public synchronized void unbind(Name name)
187 throws NamingException
188 {
189 if (name.isEmpty())
190 {
191 // Empty names are not allowed
192 throw new InvalidNameException();
193 } else if (name.size() > 1)
194 {
195 // Recurse to find correct context
196 // System.out.println("unbind#"+name+"#");
197
198 Object ctx = getObject(name);
199 if (ctx instanceof NamingServer)
200 {
201 ((NamingServer)ctx).unbind(name.getSuffix(1));
202 } else if (ctx instanceof Reference)
203 {
204 // Federation
205 if (((Reference)ctx).get("nns") != null)
206 {
207 CannotProceedException cpe = new CannotProceedException();
208 cpe.setResolvedObj(ctx);
209 cpe.setRemainingName(name.getSuffix(1));
210 throw cpe;
211 } else
212 {
213 throw new NotContextException();
214 }
215 } else
216 {
217 throw new NotContextException();
218 }
219 } else
220 {
221 // Unbind object
222 if (name.get(0).equals(""))
223 {
224 throw new InvalidNameException();
225 } else
226 {
227 // System.out.println("unbind "+name+"="+getBinding(name));
228 if (getBinding(name) != null)
229 {
230 removeBinding(name);
231 } else
232 {
233 throw new NameNotFoundException();
234 }
235 }
236 }
237 }
238
239 // public synchronized Object lookup(Name name)
240 public Object lookup(Name name)
241 throws NamingException
242 {
243 Object result;
244 if (name.isEmpty())
245 {
246 // Return this
247 result = new NamingContext(null, (Name)(prefix.clone()), getRoot());
248 } else if (name.size() > 1)
249 {
250 // Recurse to find correct context
251 // System.out.println("lookup#"+name+"#");
252
253 Object ctx = getObject(name);
254 if (ctx instanceof NamingServer)
255 {
256 result = ((NamingServer)ctx).lookup(name.getSuffix(1));
257 } else if (ctx instanceof Reference)
258 {
259 // Federation
260 if (((Reference)ctx).get("nns") != null)
261 {
262 CannotProceedException cpe = new CannotProceedException();
263 cpe.setResolvedObj(ctx);
264 cpe.setRemainingName(name.getSuffix(1));
265 throw cpe;
266 }
267
268 result = new ResolveResult(ctx, name.getSuffix(1));
269 } else
270 {
271 throw new NotContextException();
272 }
273 } else
274 {
275 // Get object to return
276 if (name.get(0).equals(""))
277 {
278 result = new NamingContext(null, prefix, getRoot());
279 } else
280 {
281 // System.out.println("lookup "+name);
282 Object res = getObject(name);
283
284 if (res instanceof NamingServer)
285 {
286 Name fullName = (Name)(prefix.clone());
287 fullName.addAll(name);
288 result = new NamingContext(null, fullName, getRoot());
289 }
290 else
291 result = res;
292 }
293 }
294
295 return result;
296 }
297
298 public Collection list(Name name)
299 throws NamingException
300 {
301 // System.out.println("list of #"+name+"#"+name.size());
302 if (name.isEmpty())
303 {
304 // System.out.println("list "+name);
305
306 Vector list = new Vector();
307 Enumeration keys = table.keys();
308 while (keys.hasMoreElements())
309 {
310 String key = (String)keys.nextElement();
311 Binding b = getBinding(key);
312
313 list.addElement(new NameClassPair(b.getName(),b.getClassName(),true));
314 }
315 return list;
316 } else
317 {
318 // System.out.println("list#"+name+"#");
319
320 Object ctx = getObject(name);
321 if (ctx instanceof NamingServer)
322 {
323 return ((NamingServer)ctx).list(name.getSuffix(1));
324 } else if (ctx instanceof Reference)
325 {
326 // Federation
327 if (((Reference)ctx).get("nns") != null)
328 {
329 CannotProceedException cpe = new CannotProceedException();
330 cpe.setResolvedObj(ctx);
331 cpe.setRemainingName(name.getSuffix(1));
332 throw cpe;
333 } else
334 {
335 throw new NotContextException();
336 }
337 } else
338 {
339 throw new NotContextException();
340 }
341 }
342 }
343
344 public Collection listBindings(Name name)
345 throws NamingException
346 {
347 if (name.isEmpty())
348 {
349 Collection bindings = table.values();
350 Collection newBindings = new Vector(bindings.size());
351 Iterator enum = bindings.iterator();
352 while (enum.hasNext())
353 {
354 Binding b = (Binding)enum.next();
355 if (b.getObject() instanceof NamingServer)
356 {
357 Name n = (Name)prefix.clone();
358 n.add(b.getName());
359 newBindings.add(new Binding(b.getName(),
360 b.getClassName(),
361 new NamingContext(null, n, getRoot())));
362 } else
363 {
364 newBindings.add(b);
365 }
366 }
367
368 return newBindings;
369 } else
370 {
371 Object ctx = getObject(name);
372 if (ctx instanceof NamingServer)
373 {
374 return ((NamingServer)ctx).listBindings(name.getSuffix(1));
375 } else if (ctx instanceof Reference)
376 {
377 // Federation
378 if (((Reference)ctx).get("nns") != null)
379 {
380 CannotProceedException cpe = new CannotProceedException();
381 cpe.setResolvedObj(ctx);
382 cpe.setRemainingName(name.getSuffix(1));
383 throw cpe;
384 } else
385 {
386 throw new NotContextException();
387 }
388 } else
389 {
390 throw new NotContextException();
391 }
392 }
393 }
394
395 public Context createSubcontext(Name name)
396 throws NamingException
397 {
398 if( name.size() == 0 )
399 throw new InvalidNameException("Cannot pass an empty name to createSubcontext");
400
401 NamingException ex = null;
402 Context subCtx = null;
403 if (name.size() > 1)
404 {
405 Object ctx = getObject(name);
406 if (ctx != null)
407 {
408 Name subCtxName = name.getSuffix(1);
409 if (ctx instanceof NamingServer)
410 {
411 subCtx = ((NamingServer)ctx).createSubcontext(subCtxName);
412 }
413 else if (ctx instanceof Reference)
414 {
415 // Federation
416 if (((Reference)ctx).get("nns") != null)
417 {
418 CannotProceedException cpe = new CannotProceedException();
419 cpe.setResolvedObj(ctx);
420 cpe.setRemainingName(subCtxName);
421 throw cpe;
422 }
423 else
424 {
425 ex = new NotContextException();
426 ex.setResolvedName(name.getPrefix(0));
427 ex.setRemainingName(subCtxName);
428 throw ex;
429 }
430 }
431 else
432 {
433 ex = new NotContextException();
434 ex.setResolvedName(name.getPrefix(0));
435 ex.setRemainingName(subCtxName);
436 throw ex;
437 }
438 }
439 else
440 {
441 ex = new NameNotFoundException();
442 ex.setRemainingName(name);
443 throw ex;
444 }
445 }
446 else
447 {
448 Object binding = table.get(name.get(0));
449 if( binding != null )
450 {
451 ex = new NameAlreadyBoundException();
452 ex.setResolvedName(prefix);
453 ex.setRemainingName(name);
454 throw ex;
455 }
456 else
457 {
458 Name fullName = (Name) prefix.clone();
459 fullName.addAll(name);
460 NamingServer subContext = new NamingServer(fullName, this);
461 setBinding(name, subContext, NamingContext.class.getName());
462 subCtx = new NamingContext(null, fullName, getRoot());
463 }
464 }
465 return subCtx;
466 }
467
468 public Naming getRoot()
469 {
470 if (parent == null)
471 return this;
472 else
473 return parent.getRoot();
474 }
475
476 // Y overrides ---------------------------------------------------
477
478 // Package protected ---------------------------------------------
479
480 // Protected -----------------------------------------------------
481
482 // Private -------------------------------------------------------
483 private void setBinding(Name name, Object obj, String className)
484 {
485 String n = name.toString();
486 table.put(n, new Binding(n, className, obj, true));
487 }
488
489 private Binding getBinding(String key)
490 throws NameNotFoundException
491 {
492 Binding b = (Binding)table.get(key);
493 if (b == null)
494 {
495 throw new NameNotFoundException(key + " not bound");
496 }
497 return b;
498 }
499
500 private Binding getBinding(Name key)
501 throws NameNotFoundException
502 {
503 return getBinding(key.get(0));
504 }
505
506 private Object getObject(Name key)
507 throws NameNotFoundException
508 {
509 return getBinding(key).getObject();
510 }
511
512 private void removeBinding(Name name)
513 {
514 table.remove(name.get(0));
515 }
516
517 private NamingServer getParent()
518 {
519 return parent;
520 }
521 // Inner classes -------------------------------------------------
522 }