KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > dyade > aaa > jndi2 > impl > ServerImpl


1 /*
2  * JORAM: Java(TM) Open Reliable Asynchronous Messaging
3  * Copyright (C) 2001 - ScalAgent Distributed Technologies
4  * Copyright (C) 1996 - Dyade
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA.
20  *
21  * Initial developer(s): Sofiane Chibani
22  * Contributor(s): David Feliot, Nicolas Tachker
23  */

24 package fr.dyade.aaa.jndi2.impl;
25
26 import java.io.*;
27 import java.util.*;
28 import javax.naming.*;
29
30 import fr.dyade.aaa.util.*;
31
32 import org.objectweb.util.monolog.api.BasicLevel;
33 import org.objectweb.util.monolog.api.Logger;
34
35 public class ServerImpl {
36
37   /**
38    * Identifier of this server.
39    */

40   private Object JavaDoc serverId;
41
42   /**
43    * Identifier of the server that owns
44    * the root naming context.
45    */

46   private Object JavaDoc rootOwnerId;
47
48   /**
49    * Optional update listener.
50    * May be <code>null</code>.
51    */

52   private UpdateListener updateListener;
53   
54   /**
55    * A context manager for the factory
56    * operations (new, delete). It also
57    * handles a cache and the persistency.
58    */

59   private ContextManager contextManager;
60
61   /**
62    * Constructs a <code>ServerImpl</code>
63    *
64    * @param transaction Transactional context that
65    * provides atomicity for the write operations
66    * performed during a request.
67    *
68    * @param serverId Identifier of this server.
69    *
70    * @param rootOwnerId Identifier of the server
71    * that owns the root naming context.
72    */

73   public ServerImpl(Transaction transaction,
74                     Object JavaDoc serverId,
75                     Object JavaDoc rootOwnerId) {
76     this.serverId = serverId;
77     this.rootOwnerId = rootOwnerId;
78     contextManager = new ContextManager(
79       transaction, serverId, rootOwnerId);
80   }
81
82   public void setUpdateListener(UpdateListener updateListener) {
83     this.updateListener = updateListener;
84   }
85   
86   public void initialize() throws Exception JavaDoc {
87     contextManager.initialize();
88
89     // Creates the root naming context if this
90
// server owns it.
91
if (rootOwnerId.equals(serverId)) {
92       NamingContext rootNc =
93         contextManager.getRootNamingContext();
94       if (rootNc == null) {
95         contextManager.newNamingContext(
96           serverId,
97           null,
98           new CompositeName());
99       }
100     }
101   }
102   
103   /**
104    * Binds an object to the specified path.
105    *
106    * @param path the path of the object
107    *
108    * @param obj the object to bind
109    *
110    * @exception NameAlreadyBoundException if the name of
111    * the subcontext is already bound.
112    *
113    * @exception NameNotFoundException if some of the
114    * intermediate names in the path don't exist.
115    *
116    * @exception NotOwnerException if the owner of the
117    * parent context is checked and is not the local
118    * naming server.
119    */

120   public void bind(CompositeName path,
121                    Object JavaDoc obj) throws NamingException {
122     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
123       Trace.logger.log(BasicLevel.DEBUG, "ServerImpl.bind(" +
124                        path + ',' +
125                        obj + ',' + ')');
126     // The root context is (in a way) already bound since
127
// it is already a context.
128
if (path.size() == 0) throw new NameAlreadyBoundException();
129
130     path = (CompositeName)path.clone();
131     String JavaDoc lastName = (String JavaDoc)path.remove(path.size() - 1);
132     NamingContext nc = contextManager.getNamingContext(path);
133
134     bind(nc, lastName, obj, serverId);
135     
136     if (updateListener != null) {
137       updateListener.onUpdate(
138         new BindEvent(nc.getId(), lastName, obj));
139     }
140   }
141
142   public void bind(NamingContext nc,
143                    String JavaDoc lastName,
144                    Object JavaDoc obj,
145                    Object JavaDoc ownerId) throws NamingException {
146     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
147       Trace.logger.log(BasicLevel.DEBUG,
148                        "ServerImpl.bind(" +
149                        nc + ',' +
150                        lastName + ',' +
151                        obj + ',' +
152                        ownerId + ')');
153     if (! nc.getOwnerId().equals(ownerId)) {
154       throw new NotOwnerException(
155         nc.getOwnerId());
156     }
157
158     Record r = nc.getRecord(lastName);
159     if (r != null) throw new NameAlreadyBoundException();
160     else {
161       nc.addRecord(new ObjectRecord(lastName, obj));
162       contextManager.storeNamingContext(nc);
163     }
164   }
165
166   /**
167    * Rebinds an object to the specified path.
168    *
169    * @param path the path of the object
170    *
171    * @param obj the object to rebind
172    *
173    * @exception NameNotFoundException if some of the
174    * intermediate names in the path don't exist.
175    *
176    * @exception NotOwnerException if the owner of the
177    * parent context is checked and is not the local
178    * naming server.
179    *
180    * @exception NamingException if the specified path
181    * is bound to a naming context.
182    */

183   public void rebind(CompositeName path,
184                      Object JavaDoc obj) throws NamingException {
185     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
186       Trace.logger.log(BasicLevel.DEBUG, "ServerImpl.rebind(" +
187                        path + ',' +
188                        obj + ',' + ')');
189
190     // The root context cannot become a name-value pair.
191
if (path.size() == 0) throw new NamingException("Cannot rebind the root context");
192
193     path = (CompositeName)path.clone();
194     String JavaDoc lastName = (String JavaDoc)path.remove(path.size() - 1);
195     NamingContext nc = contextManager.getNamingContext(path);
196
197     rebind(nc, lastName, obj, serverId);
198
199     if (updateListener != null) {
200       updateListener.onUpdate(
201         new RebindEvent(nc.getId(), lastName, obj));
202     }
203   }
204
205   public void rebind(NamingContext nc,
206                      String JavaDoc lastName,
207                      Object JavaDoc obj,
208                      Object JavaDoc ownerId) throws NamingException {
209     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
210       Trace.logger.log(BasicLevel.DEBUG,
211                        "ServerImpl.rebind(" +
212                        nc + ',' +
213                        lastName + ',' +
214                        obj + ',' +
215                        ownerId + ')');
216     if (! nc.getOwnerId().equals(ownerId)) {
217       throw new NotOwnerException(
218         nc.getOwnerId());
219     }
220
221     Record r = nc.getRecord(lastName);
222     if (r != null) {
223       if (r instanceof ContextRecord) {
224         // DF: seems not consistent to delete recursively the whole
225
// context (empty or not) as the reverse operation is not possible
226
// (create a context with a name already bound).
227
// So prefer to raise an error.
228
// Have to check the spec.
229
throw new NamingException("Cannot rebind a context");
230       } else {
231         ObjectRecord or = (ObjectRecord)r;
232         or.setObject(obj);
233       }
234     } else {
235       nc.addRecord(new ObjectRecord(lastName, obj));
236     }
237     contextManager.storeNamingContext(nc);
238   }
239
240   /**
241    * Looks up the specified path.
242    *
243    * @param path the path to look up
244    *
245    * @exception NameNotFoundException if some of the
246    * names (intermediate and final) in the path don't exist.
247    *
248    * @exception NotOwnerException if the owner of the
249    * parent context is checked and is not the local
250    * naming server.
251    *
252    * @return <code>null</code> if the bound object is a context.
253    *
254    * @exception NameNotFoundException
255    */

256   public Record lookup(CompositeName path) throws NamingException {
257     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
258       Trace.logger.log(BasicLevel.DEBUG, "ServerImpl.lookup(" + path + ')');
259
260     if (path.size() == 0) {
261       return null;
262     }
263
264     path = (CompositeName)path.clone();
265     String JavaDoc lastName = (String JavaDoc)path.remove(path.size() - 1);
266     NamingContext nc = contextManager.getNamingContext(path);
267     
268     Record r = nc.getRecord(lastName);
269     if (r == null) {
270       NameNotFoundException nnfe =
271         new NameNotFoundException();
272       nnfe.setResolvedName(path);
273       throw new MissingRecordException(
274         nc.getId(), nc.getOwnerId(), nnfe);
275     } else if (r instanceof ObjectRecord) {
276       return r;
277     } else {
278       return null;
279     }
280   }
281
282   /**
283    * Unbinds the specified path. This operation is
284    * idempotent: does nothing if the final name of
285    * the path is not found.
286    *
287    * @param path the path to unbind
288    *
289    * @exception NameNotFoundException if some of the
290    * intermediate names in the path don't exist.
291    *
292    * @exception NotOwnerException if the owner of the
293    * parent context is checked and is not the local
294    * naming server.
295    *
296    * @exception NamingException if the specified path
297    * is bound to a naming context.
298    */

299   public void unbind(CompositeName path) throws NamingException {
300     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
301       Trace.logger.log(BasicLevel.DEBUG, "ServerImpl.unbind(" +
302                        path + ')');
303
304     // The root context cannot be deleted.
305
if (path.size() == 0) throw new NamingException("Cannot unbind the root context");
306
307     path = (CompositeName)path.clone();
308     String JavaDoc lastName = (String JavaDoc)path.remove(path.size() - 1);
309     NamingContext nc = contextManager.getNamingContext(path);
310
311     if (unbind(nc, lastName, serverId)) {
312       if (updateListener != null) {
313         updateListener.onUpdate(
314           new UnbindEvent(nc.getId(), lastName));
315       }
316     }
317   }
318
319   public boolean unbind(NamingContext nc,
320                         String JavaDoc lastName,
321                         Object JavaDoc ownerId) throws NamingException {
322     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
323       Trace.logger.log(BasicLevel.DEBUG,
324                        "ServerImpl.unbind(" +
325                        nc + ',' +
326                        lastName + ',' +
327                        ownerId + ')');
328     if (! nc.getOwnerId().equals(ownerId)) {
329       throw new NotOwnerException(
330         nc.getOwnerId());
331     }
332     Record r = nc.getRecord(lastName);
333     if (r != null) {
334       if (r instanceof ContextRecord) {
335         throw new NamingException("Cannot unbind a context");
336       } else {
337         nc.removeRecord(lastName);
338         contextManager.storeNamingContext(nc);
339         return true;
340       }
341     } else {
342       // else do nothing (idempotency)
343
return false;
344     }
345   }
346
347   public NameClassPair[] list(CompositeName path) throws NamingException {
348     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
349       Trace.logger.log(BasicLevel.DEBUG, "ServerImpl.list(" + path + ')');
350     NamingContext nc = contextManager.getNamingContext(path);
351     return nc.getNameClassPairs();
352   }
353
354   public Binding[] listBindings(CompositeName path) throws NamingException {
355     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
356       Trace.logger.log(BasicLevel.DEBUG, "ServerImpl.listBindings(" + path + ')');
357     NamingContext nc = contextManager.getNamingContext(path);
358     return nc.getBindings();
359   }
360
361   public void createSubcontext(CompositeName path)
362     throws NamingException {
363     createSubcontext(path, serverId);
364   }
365
366   /**
367    * Create a subcontext.
368    *
369    * @param path the path of the subcontext
370    *
371    * @param subcontextOwner identifier of the owner of
372    * the subcontext (<code>null</code> if the
373    * owner is the local naming server).
374    *
375    * @exception NameAlreadyBoundException if the name of
376    * the subcontext is already bound.
377    *
378    * @exception NameNotFoundException if some of the
379    * intermediate names in the path don't exist.
380    *
381    * @exception NotOwnerException if the owner of the
382    * parent context is checked and is not the local
383    * naming server.
384    */

385   public void createSubcontext(CompositeName path,
386                                Object JavaDoc subcontextOwnerId)
387     throws NamingException {
388     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
389       Trace.logger.log(
390         BasicLevel.DEBUG,
391         "ServerImpl.createSubcontext(" +
392         path + ',' + subcontextOwnerId + ')');
393
394     // The root already exists.
395
if (path.size() == 0) throw new NameAlreadyBoundException();
396
397     CompositeName parentPath = (CompositeName)path.clone();
398     String JavaDoc lastName =
399       (String JavaDoc)parentPath.remove(parentPath.size() - 1);
400     NamingContext parentNc =
401       contextManager.getNamingContext(parentPath);
402
403     NamingContextId ncid = createSubcontext(
404       parentNc, lastName, path, null,
405       subcontextOwnerId, serverId);
406
407     if (updateListener != null) {
408       updateListener.onUpdate(
409         new CreateSubcontextEvent(
410           parentNc.getId(), lastName, path, ncid,
411           subcontextOwnerId));
412     }
413   }
414     
415   public NamingContextId createSubcontext(
416     NamingContext parentNc,
417     String JavaDoc lastName,
418     CompositeName path,
419     NamingContextId ncid,
420     Object JavaDoc subcontextOwnerId,
421     Object JavaDoc ownerId)
422     throws NamingException {
423     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
424       Trace.logger.log(BasicLevel.DEBUG,
425                        "ServerImpl.createSubcontext(" +
426                        parentNc + ',' +
427                        lastName + ',' +
428                        path + ',' +
429                        ncid + ',' +
430                        subcontextOwnerId + ',' +
431                        ownerId + ')');
432     if (! parentNc.getOwnerId().equals(ownerId)) {
433       throw new NotOwnerException(
434         parentNc.getOwnerId());
435     }
436
437     if (parentNc.getRecord(lastName) != null)
438       throw new NameAlreadyBoundException();
439     
440     NamingContext nc =
441       contextManager.newNamingContext(
442         subcontextOwnerId, ncid, path);
443     parentNc.addRecord(new ContextRecord(
444       lastName, nc.getId()));
445     contextManager.storeNamingContext(parentNc);
446     return nc.getId();
447   }
448
449   /**
450    * Destroy a subcontext. This operation is
451    * idempotent: does nothing if the final name of
452    * the path is not found.
453    *
454    * @param path the path of the subcontext
455    *
456    * @exception NameAlreadyBoundException if the name of
457    * the subcontext is already bound.
458    *
459    * @exception NameNotFoundException if some of the
460    * intermediate names in the path don't exist.
461    *
462    * @exception NotOwnerException if the owner of the
463    * parent context is checked and is not the local
464    * naming server.
465    *
466    * @exception NotContextException if the specified path
467    * isn't bound to a context.
468    */

469   public void destroySubcontext(CompositeName path) throws NamingException {
470     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
471       Trace.logger.log(BasicLevel.DEBUG,
472                        "ServerImpl.destroySubcontext(" +
473                        path + ')');
474
475     if (path.size() == 0)
476       throw new NamingException("Cannot delete root context.");
477
478     CompositeName parentPath = (CompositeName)path.clone();
479     String JavaDoc lastName = (String JavaDoc)parentPath.remove(parentPath.size() - 1);
480     NamingContext parentNc = contextManager.getNamingContext(parentPath);
481     
482     try {
483       NamingContext nc = contextManager.getNamingContext(path);
484       if (nc.size() > 0) {
485         if (Trace.logger.isLoggable(BasicLevel.DEBUG))
486           Trace.logger.log(BasicLevel.DEBUG,
487                            " -> not empty: nc = " + nc);
488         throw new ContextNotEmptyException();
489       }
490     } catch (MissingRecordException exc) {
491       // else do nothing (idempotency)
492
return;
493     }
494
495     if (destroySubcontext(parentNc, lastName, path, serverId)) {
496       if (updateListener != null) {
497         updateListener.onUpdate(
498           new DestroySubcontextEvent(
499             parentNc.getId(), lastName, path));
500       }
501     }
502   }
503
504   public boolean destroySubcontext(NamingContext parentNc,
505                                    String JavaDoc lastName,
506                                    CompositeName path,
507                                    Object JavaDoc ownerId)
508     throws NamingException {
509     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
510       Trace.logger.log(BasicLevel.DEBUG,
511                        "ServerImpl.destroySubcontext(" +
512                        parentNc + ',' +
513                        lastName + ',' +
514                        path + ',' +
515                        ownerId + ')');
516     if (! parentNc.getOwnerId().equals(ownerId)) {
517       throw new NotOwnerException(
518         parentNc.getOwnerId());
519     }
520
521     Record r = parentNc.getRecord(lastName);
522     if (r != null) {
523       if (r instanceof ContextRecord) {
524         ContextRecord cr = (ContextRecord)r;
525         NamingContextId ctxId = cr.getId();
526         contextManager.delete(ctxId, path);
527         
528         // Remove from the parent context
529
parentNc.removeRecord(lastName);
530         contextManager.storeNamingContext(parentNc);
531         return true;
532       } else {
533         throw new NotContextException();
534       }
535     } else {
536       // else do nothing (idempotency)
537
return false;
538     }
539   }
540
541   /**
542    * Returns copies of the naming contexts owned by the server
543    * which identifier is specified.
544    *
545    * @param serverId the identifier of the server that owns
546    * the naming contexts to get.
547    */

548   public NamingContextInfo[] copyNamingContexts(Object JavaDoc serverId)
549     throws NamingException {
550     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
551     Trace.logger.log(BasicLevel.DEBUG,
552                      "ServerImpl.copyNamingContexts(" + serverId + ')');
553     return contextManager.copyNamingContexts(serverId);
554   }
555
556   public NamingContext getNamingContext(NamingContextId ncid)
557     throws NamingException {
558     return contextManager.getNamingContext(ncid);
559   }
560
561   public void addNamingContext(NamingContextInfo ncInfo)
562     throws NamingException {
563     if (Trace.logger.isLoggable(BasicLevel.DEBUG))
564       Trace.logger.log(BasicLevel.DEBUG,
565                        "ServerImpl.addNamingContext(" +
566                        ncInfo + ')');
567     contextManager.addNamingContext(ncInfo);
568   }
569
570   public void changeOwner(Object JavaDoc formerOwnerId)
571     throws NamingException {
572     NamingContextInfo[] contexts =
573       contextManager.changeOwner(
574         formerOwnerId, serverId);
575     if (updateListener != null) {
576       updateListener.onUpdate(
577         new ChangeOwnerEvent(
578           formerOwnerId,
579           contexts));
580     }
581   }
582
583   public void resetNamingContext(NamingContext context)
584     throws NamingException {
585     contextManager.resetNamingContext(context);
586   }
587
588   public void writeBag(ObjectOutputStream out)
589     throws IOException {
590     contextManager.writeBag(out);
591   }
592
593   public void readBag(ObjectInputStream in)
594     throws IOException, ClassNotFoundException JavaDoc {
595     contextManager.readBag(in);
596   }
597 }
598
599   
600
Popular Tags