1
2
3
4
5
6
7
8 /
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public class DatabaseContext implements Context
54 {
55 /*** Environment entry for persistence component. */
56 public static final String PERSISTENCE = "org.objectledge.database.persistence.Persistence";
57
58 /*** the persistence component. */
59 protected Persistence persistence;
60
61 /*** The enviroment. */
62 protected Hashtable env;
63
64 /*** The default parser. */
65 protected static NameParser parser = new DefaultNameParser();
66
67 /*** The context persistent delegate. */
68 protected PersistentContext context;
69
70 /***
71 * The context constructor used by initial context factory.
72 *
73 * @param env the environment
74 */
75 public DatabaseContext(Hashtable env)
76 {
77 this.env = env;
78 persistence = (Persistence)env.get(PERSISTENCE);
79 if(persistence == null)
80 {
81 throw new RuntimeException("failed to retrieve the persistence " +
82 "component from environment");
83 }
84 String dn = (String)env.get(Context.PROVIDER_URL);
85 List list = null;
86 try
87 {
88 list = persistence.load("dn = '"+dn+"'", PersistentContext.FACTORY);
89 }
90 catch(PersistenceException e)
91 {
92 throw new RuntimeException("failed to load '"+dn+"' context from database", e);
93 }
94 if(list.size() == 0)
95 {
96 throw new RuntimeException("failed to lookup the context in database");
97 }
98 if(list.size() > 1)
99 {
100 throw new RuntimeException("ambiguous context '"+dn+"' in database");
101 }
102 context = (PersistentContext)list.get(0);
103 }
104
105 /***
106 * The context constructor.
107 *
108 * @param env the environment.
109 * @param context the persistent context delegate.
110 * @param persistence the persistence.
111 * @throws NamingException if operation failed.
112 */
113 protected DatabaseContext(Hashtable env, PersistentContext context, Persistence persistence)
114 throws NamingException
115 {
116
117 this.env = env;
118 this.persistence = persistence;
119 this.context = context;
120 }
121
122 /***
123 * {@inheritDoc}
124 */
125 public Object lookup(Name name) throws NamingException
126 {
127 if (name.isEmpty())
128 {
129 return new DatabaseContext(env, context, persistence);
130 }
131 String dn = getDN(name);
132 List list = lookupContext(dn);
133 if(list.size() == 0)
134 {
135 throw new NamingException("faled to retrieve context '"+dn+"' form database");
136 }
137 if(list.size() > 1)
138 {
139 throw new NamingException("ambigious context '"+dn+"' in database");
140 }
141 return new DatabaseContext(env, (PersistentContext)list.get(0), persistence);
142 }
143
144 /***
145 * {@inheritDoc}
146 */
147 public Object lookup(String name) throws NamingException
148 {
149 return lookup(new CompositeName(name));
150 }
151
152 /***
153 * {@inheritDoc}
154 */
155 public void bind(Name name, Object obj) throws NamingException
156 {
157 throw new UnsupportedOperationException();
158 }
159
160 /***
161 * {@inheritDoc}
162 */
163 public void bind(String name, Object obj) throws NamingException
164 {
165 bind(new CompositeName(name),obj);
166 }
167
168 /***
169 * {@inheritDoc}
170 */
171 public void rebind(Name name, Object obj) throws NamingException
172 {
173 throw new UnsupportedOperationException();
174 }
175
176 /***
177 * {@inheritDoc}
178 */
179 public void rebind(String name, Object obj) throws NamingException
180 {
181 rebind(new CompositeName(name),obj);
182 }
183
184 /***
185 * {@inheritDoc}
186 */
187 public void unbind(Name name) throws NamingException
188 {
189 throw new UnsupportedOperationException();
190 }
191
192 /***
193 * {@inheritDoc}
194 */
195 public void unbind(String name) throws NamingException
196 {
197 unbind(new CompositeName(name));
198 }
199
200 /***
201 * {@inheritDoc}
202 */
203 public void rename(Name oldName, Name newName) throws NamingException
204 {
205 if (oldName.isEmpty())
206 {
207 throw new InvalidNameException("Invalid source name");
208 }
209 if (newName.isEmpty())
210 {
211 throw new InvalidNameException("Invalid target name");
212 }
213 String dn = getDN(oldName);
214 List list = lookupContext(dn);
215 if(list.size() == 0)
216 {
217 throw new NamingException("faled to retrieve context '"+dn+"' form database");
218 }
219 if(list.size() > 1)
220 {
221 throw new NamingException("ambigious context '"+dn+"' in database");
222 }
223 PersistentContext delegate = (PersistentContext)list.get(0);
224 String newDn = getDN(newName);
225 delegate.setDN(newDn);
226 try
227 {
228 persistence.save(delegate);
229 }
230 catch(PersistenceException e)
231 {
232 throw new DatabaseNamingException("failed to rename the context name",e);
233 }
234 }
235
236 /***
237 * {@inheritDoc}
238 */
239 public void rename(String oldName, String newName) throws NamingException
240 {
241 rename(new CompositeName(oldName), new CompositeName(newName));
242 }
243
244 /***
245 * {@inheritDoc}
246 */
247 public NamingEnumeration list(Name name) throws NamingException
248 {
249 DatabaseContext ctx = (DatabaseContext)lookup(name);
250 long parentId = ctx.getDelegate().getContextId();
251 try
252 {
253 List list = persistence.load("parent = "+parentId, PersistentContext.FACTORY);
254 List target = new ArrayList();
255 for(int i = 0; i < list.size(); i++)
256 {
257 PersistentContext delegate = (PersistentContext)list.get(0);
258 target.add(new NameClassPair(delegate.getDN(), this.getClass().getName()));
259 }
260 return new DefaultEnumeration(target);
261 }
262 catch(PersistenceException e)
263 {
264 throw new DatabaseNamingException("failed to retrieve child contexts from database",e);
265 }
266 }
267
268 /***
269 * {@inheritDoc}
270 */
271 public NamingEnumeration list(String name) throws NamingException
272 {
273 return list(new CompositeName(name));
274 }
275
276 /***
277 * {@inheritDoc}
278 */
279 public NamingEnumeration listBindings(Name name) throws NamingException
280 {
281 throw new UnsupportedOperationException();
282 }
283
284 /***
285 * {@inheritDoc}
286 */
287 public NamingEnumeration listBindings(String name) throws NamingException
288 {
289 return listBindings(new CompositeName(name));
290 }
291
292 /***
293 * {@inheritDoc}
294 */
295 public void destroySubcontext(Name name) throws NamingException
296 {
297 if (name.isEmpty())
298 {
299 throw new InvalidNameException("Cannot perform self destroy");
300 }
301 DatabaseContext ctx = (DatabaseContext)lookup(name);
302 long parentId = ctx.getDelegate().getContextId();
303 try
304 {
305 List list = persistence.load("parent = "+parentId, PersistentContext.FACTORY);
306 if(list.size()>0)
307 {
308 throw new NamingException("failed to destroy not empty subcontext");
309 }
310 persistence.delete(ctx.getDelegate());
311 }
312 catch(PersistenceException e)
313 {
314 throw new DatabaseNamingException("failed to delete '"+ctx.getDelegate().getDN()+
315 "' context from database",e);
316 }
317 }
318
319 /***
320 * {@inheritDoc}
321 */
322 public void destroySubcontext(String name) throws NamingException
323 {
324 destroySubcontext(new CompositeName(name));
325 }
326
327 /***
328 * {@inheritDoc}
329 */
330 public Context createSubcontext(Name name) throws NamingException
331 {
332 PersistentContext delegate = createContextDelegate(name);
333 return new DatabaseContext(env, delegate, persistence);
334 }
335
336 /***
337 * {@inheritDoc}
338 */
339 public Context createSubcontext(String name) throws NamingException
340 {
341 return createSubcontext(new CompositeName(name));
342 }
343
344 /***
345 * {@inheritDoc}
346 */
347 public Object lookupLink(Name name) throws NamingException
348 {
349 throw new UnsupportedOperationException();
350 }
351
352 /***
353 * {@inheritDoc}
354 */
355 public Object lookupLink(String name) throws NamingException
356 {
357 return lookupLink(new CompositeName(name));
358 }
359
360 /***
361 * {@inheritDoc}
362 */
363 public NameParser getNameParser(Name name) throws NamingException
364 {
365 return parser;
366 }
367
368 /***
369 * {@inheritDoc}
370 */
371 public NameParser getNameParser(String name) throws NamingException
372 {
373 return parser;
374 }
375
376 /***
377 * {@inheritDoc}
378 */
379 public Name composeName(Name name, Name prefix) throws NamingException
380 {
381 Name compoundName = name;
382 if(compoundName instanceof CompositeName)
383 {
384 compoundName = parser.parse(compoundName.toString());
385 }
386 Name compoundPrefix = prefix;
387 if(compoundPrefix instanceof CompositeName)
388 {
389 compoundPrefix = parser.parse(compoundPrefix.toString());
390 }
391 compoundPrefix.addAll(compoundName);
392 return new CompositeName(compoundPrefix.toString());
393 }
394
395 /***
396 * {@inheritDoc}
397 */
398 public String composeName(String name, String prefix) throws NamingException
399 {
400 Name compoundName = parser.parse(name);
401 Name compoundPrefix = parser.parse(prefix);
402 compoundPrefix.addAll(compoundName);
403 return compoundPrefix.toString();
404 }
405
406 /***
407 * {@inheritDoc}
408 */
409 public Object addToEnvironment(String propName, Object propVal) throws NamingException
410 {
411 if (env == null)
412 {
413 env = new Hashtable();
414 }
415 return env.put(propName, propVal);
416 }
417
418 /***
419 * {@inheritDoc}
420 */
421 public Object removeFromEnvironment(String propName) throws NamingException
422 {
423 if(env == null)
424 {
425 return null;
426 }
427 return env.remove(propName);
428 }
429
430 /***
431 * {@inheritDoc}
432 */
433 public Hashtable getEnvironment() throws NamingException
434 {
435 return new Hashtable(env);
436 }
437
438 /***
439 * {@inheritDoc}
440 */
441 public void close() throws NamingException
442 {
443
444 }
445
446 /***
447 * {@inheritDoc}
448 */
449 public String getNameInNamespace() throws NamingException
450 {
451 return context.getDN();
452 }
453
454
455
456
457 /***
458 * Lookup the context with given dn.
459 *
460 * @param dn the dn of the context.
461 * @return the list of contexts with given dn.
462 * @throws NamingException if operation fails.
463 */
464 protected List lookupContext(String dn)
465 throws NamingException
466 {
467 try
468 {
469 return persistence.load("dn = '"+dn+"'", PersistentContext.FACTORY);
470 }
471 catch(PersistenceException e)
472 {
473 throw new DatabaseNamingException("failed to retrieve context from database",e);
474 }
475 }
476
477 /***
478 * Get the dn from relative name.
479 *
480 * @param relativeName the relative name of the context.
481 * @return the dn of the context.
482 * @throws NamingException if operation fails.
483 */
484 protected String getDN(Name relativeName)
485 throws NamingException
486 {
487 Name base = parser.parse(new CompositeName(this.getNameInNamespace()).get(0));
488 return base.add(relativeName.get(0)).toString();
489 }
490
491 /***
492 * Create the context delegate.
493 *
494 * @param name the name of the context.
495 * @return the persistent delegate.
496 * @throws NamingException if operation fails.
497 */
498 protected PersistentContext createContextDelegate(Name name)
499 throws NamingException
500 {
501 String dn = getDN(name);
502 List list = lookupContext(dn);
503 if(list.size() > 0)
504 {
505 throw new NameAlreadyBoundException("context '"+dn+"' already exists");
506 }
507 PersistentContext subContext = new PersistentContext(dn, context.getContextId());
508 try
509 {
510 persistence.save(subContext);
511 }
512 catch(PersistenceException e)
513 {
514 throw new DatabaseNamingException("failed to add the subcontext with name = '"+
515 dn+"'",e);
516 }
517 return subContext;
518 }
519
520 /***
521 * Access to delegate object.
522 *
523 * @return the delegate context.
524 */
525 PersistentContext getDelegate()
526 {
527 return context;
528 }
529 }