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
54
55
56
57
58
59
60
61
62
63
64
65 public class DatabaseDirContext extends DatabaseContext implements DirContext
66 {
67 /***
68 * The directory context constructor.
69 *
70 * @param env the environment.
71 */
72 public DatabaseDirContext(Hashtable env)
73 {
74 super(env);
75 }
76
77 /***
78 * The context constructor.
79 *
80 * @param env the environment.
81 * @param context the persistent context delegate.
82 * @param persistence the persistence.
83 * @throws NamingException if operation failed.
84 */
85 protected DatabaseDirContext(Hashtable env, PersistentContext context, Persistence persistence)
86 throws NamingException
87 {
88 super(env, context, persistence);
89 }
90
91 /***
92 * {@inheritDoc}
93 */
94 public Object lookup(Name name) throws NamingException
95 {
96 if (name.isEmpty())
97 {
98 return new DatabaseDirContext(env, context, persistence);
99 }
100 String dn = getDN(name);
101 List list = lookupContext(dn);
102 if(list.size() == 0)
103 {
104 throw new NamingException("faled to retrieve context '"+dn+"' from database");
105 }
106 if(list.size() > 1)
107 {
108 throw new NamingException("ambigious context '"+dn+"' in database");
109 }
110 return new DatabaseDirContext(env, (PersistentContext)list.get(0), persistence);
111 }
112
113 /***
114 * {@inheritDoc}
115 */
116 public Attributes getAttributes(Name name) throws NamingException
117 {
118 return getAttributes(name, null);
119 }
120
121 /***
122 * {@inheritDoc}
123 */
124 public Attributes getAttributes(String name) throws NamingException
125 {
126 return getAttributes(new CompositeName(name));
127 }
128
129 /***
130 * {@inheritDoc}
131 */
132 public Attributes getAttributes(Name name, String[] attrIds) throws NamingException
133 {
134 DatabaseDirContext ctx = (DatabaseDirContext)lookup(name);
135 long contextId = ctx.getDelegate().getContextId();
136 Attributes allAttributes = getAllAttributes(contextId);
137 return filterAttributes(allAttributes, attrIds);
138 }
139
140 /***
141 * {@inheritDoc}
142 */
143 public Attributes getAttributes(String name, String[] attrIds) throws NamingException
144 {
145 return getAttributes(new CompositeName(name), attrIds);
146 }
147
148 /***
149 * {@inheritDoc}
150 */
151 public void modifyAttributes(Name name, int modOp, Attributes attrs) throws NamingException
152 {
153 if (attrs == null || attrs.size() == 0)
154 {
155 return;
156 }
157 NamingEnumeration enumerator = attrs.getAll();
158 ModificationItem[] items = new ModificationItem[attrs.size()];
159 int i = 0;
160 while(enumerator.hasMoreElements())
161 {
162 items[i++] = new ModificationItem(modOp, (Attribute)enumerator.next());
163 }
164 modifyAttributes(name, items);
165 }
166
167 /***
168 * {@inheritDoc}
169 */
170 public void modifyAttributes(String name, int modOp, Attributes attrs)
171 throws NamingException
172 {
173 modifyAttributes(new CompositeName(name), modOp, attrs);
174 }
175
176 /***
177 * {@inheritDoc}
178 */
179 public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException
180 {
181 List failures = new ArrayList();
182 DatabaseDirContext ctx = (DatabaseDirContext)lookup(name);
183 boolean transactionControler;
184 try
185 {
186 transactionControler = persistence.getDatabase().beginTransaction();
187 }
188 catch(SQLException e)
189 {
190 throw new RuntimeException("Failed to begin transaction",e);
191 }
192 for (int i=0; i<mods.length; i++)
193 {
194 Attribute attribute = mods[i].getAttribute();
195 NamingEnumeration values = attribute.getAll();
196 switch (mods[i].getModificationOp())
197 {
198 case ADD_ATTRIBUTE:
199 try
200 {
201 while (values.hasMore())
202 {
203 String value = (String)values.next();
204 PersistentAttribute pAttribute = new PersistentAttribute(
205 ctx.getDelegate().getContextId(),
206 attribute.getID(), value);
207 persistence.save(pAttribute);
208 }
209 }
210 catch(PersistenceException e)
211 {
212 failures.add(mods[i]);
213 }
214 break;
215 case REPLACE_ATTRIBUTE:
216 try
217 {
218 StringBuilder sb = new StringBuilder();
219 sb.append("context_id = ");
220 sb.append(ctx.getDelegate().getContextId());
221 sb.append(" and name = '");
222 sb.append(attribute.getID());
223 sb.append("'");
224 persistence.delete(sb.toString(), PersistentAttribute.FACTORY);
225 while (values.hasMore())
226 {
227 String value = (String)values.next();
228 PersistentAttribute pAttribute = new PersistentAttribute(
229 ctx.getDelegate().getContextId(),
230 attribute.getID(), value);
231 persistence.save(pAttribute);
232 }
233 }
234 catch(PersistenceException e)
235 {
236 failures.add(mods[i]);
237 }
238 break;
239 case REMOVE_ATTRIBUTE:
240 try
241 {
242 if(values.hasMore())
243 {
244 while(values.hasMore())
245 {
246 String value = (String)values.next();
247 StringBuilder sb = new StringBuilder();
248 sb.append("context_id = ");
249 sb.append(ctx.getDelegate().getContextId());
250 sb.append(" and name = '");
251 sb.append(attribute.getID());
252 sb.append("' and value = '");
253 sb.append(value);
254 sb.append("'");
255 persistence.delete(sb.toString(), PersistentAttribute.FACTORY);
256 }
257 }
258 else
259 {
260 StringBuilder sb = new StringBuilder();
261 sb.append("context_id = ");
262 sb.append(ctx.getDelegate().getContextId());
263 sb.append(" and name = '");
264 sb.append(attribute.getID());
265 sb.append("'");
266 persistence.delete(sb.toString(), PersistentAttribute.FACTORY);
267 }
268 }
269 catch(PersistenceException e)
270 {
271 failures.add(mods[i]);
272 }
273
274 break;
275 default:
276 break;
277 }
278 }
279 if( failures.size() > 0)
280 {
281 try
282 {
283 persistence.getDatabase().rollbackTransaction(transactionControler);
284 }
285 catch(SQLException e)
286 {
287 throw new RuntimeException("Failed to begin transaction",e);
288 }
289 }
290 else
291 {
292 try
293 {
294 persistence.getDatabase().commitTransaction(transactionControler);
295 }
296 catch(SQLException e)
297 {
298 throw new RuntimeException("Failed to begin transaction",e);
299 }
300 }
301 }
302
303 /***
304 * {@inheritDoc}
305 */
306 public void modifyAttributes(String name, ModificationItem[] mods)
307 throws NamingException
308 {
309 modifyAttributes(new CompositeName(name), mods);
310 }
311
312 /***
313 * {@inheritDoc}
314 */
315 public void bind(Name name, Object obj, Attributes attrs) throws NamingException
316 {
317 throw new UnsupportedOperationException();
318 }
319
320 /***
321 * {@inheritDoc}
322 */
323 public void bind(String name, Object obj, Attributes attrs) throws NamingException
324 {
325 throw new UnsupportedOperationException();
326 }
327
328 /***
329 * {@inheritDoc}
330 */
331 public void rebind(Name name, Object obj, Attributes attrs) throws NamingException
332 {
333 throw new UnsupportedOperationException();
334 }
335
336 /***
337 * {@inheritDoc}
338 */
339 public void rebind(String name, Object obj, Attributes attrs) throws NamingException
340 {
341 throw new UnsupportedOperationException();
342 }
343
344 /***
345 * {@inheritDoc}
346 */
347 public void destroySubcontext(Name name) throws NamingException
348 {
349 DatabaseContext ctx = (DatabaseContext)lookup(name);
350 long contextId = ctx.getDelegate().getContextId();
351 deleteAllAttributes(contextId);
352 super.destroySubcontext(name);
353 }
354
355 /***
356 * {@inheritDoc}
357 */
358 public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException
359 {
360 PersistentContext delegate = createContextDelegate(name);
361 DatabaseDirContext subContext = new DatabaseDirContext(env, delegate, persistence);
362 if (attrs != null && attrs.size() > 0)
363 {
364 subContext.modifyAttributes("", DirContext.ADD_ATTRIBUTE, attrs);
365 }
366 return subContext;
367 }
368
369 /***
370 * {@inheritDoc}
371 */
372 public DirContext createSubcontext(String name, Attributes attrs) throws NamingException
373 {
374 return createSubcontext(new CompositeName(name),attrs);
375 }
376
377 /***
378 * {@inheritDoc}
379 */
380 public Context createSubcontext(String name) throws NamingException
381 {
382 return createSubcontext(name,null);
383 }
384
385 /***
386 * {@inheritDoc}
387 */
388 public Context createSubcontext(Name name) throws NamingException
389 {
390 return createSubcontext(name, null);
391 }
392
393
394 /***
395 * {@inheritDoc}
396 */
397 public DirContext getSchema(Name name) throws NamingException
398 {
399 throw new UnsupportedOperationException();
400 }
401
402 /***
403 * {@inheritDoc}
404 */
405 public DirContext getSchema(String name) throws NamingException
406 {
407 return getSchema(new CompositeName(name));
408 }
409
410 /***
411 * {@inheritDoc}
412 */
413 public DirContext getSchemaClassDefinition(Name name) throws NamingException
414 {
415 throw new UnsupportedOperationException();
416 }
417
418 /***
419 * {@inheritDoc}
420 */
421 public DirContext getSchemaClassDefinition(String name) throws NamingException
422 {
423 return getSchemaClassDefinition(new CompositeName(name));
424 }
425
426 /***
427 * {@inheritDoc}
428 */
429 public NamingEnumeration search(Name name, Attributes matchingAttributes,
430 String[] attributesToReturn)
431 throws NamingException
432 {
433 List searchResult = new ArrayList();
434 DatabaseDirContext ctx = (DatabaseDirContext)lookup(name);
435 long contextId = ctx.getDelegate().getContextId();
436 Map attributeMap = getChildrenAttributes(contextId);
437 Iterator it = attributeMap.keySet().iterator();
438 while(it.hasNext())
439 {
440 String dn = (String)it.next();
441 Attributes attributes = (Attributes)attributeMap.get(dn);
442 NamingEnumeration enumeration = matchingAttributes.getAll();
443 if(attributes == null && enumeration.hasMore())
444 {
445 break;
446 }
447 boolean found = true;
448 outer: while(enumeration.hasMore())
449 {
450 Attribute searchAttr = (Attribute)enumeration.next();
451 Attribute attr = (Attribute)attributes.get(searchAttr.getID());
452 if(attr == null)
453 {
454 found = false;
455 break;
456 }
457 NamingEnumeration values = searchAttr.getAll();
458 while (values.hasMore())
459 {
460 String value = (String)values.next();
461 if(attr.contains(value))
462 {
463 break outer;
464 }
465 }
466 found = false;
467 }
468 if(found)
469 {
470 SearchResult result = new SearchResult(dn.substring(0, getNameInNamespace()
471 .length() + 1), null, filterAttributes(attributes, attributesToReturn));
472 result.setNameInNamespace(dn);
473 searchResult.add(result);
474 }
475 }
476 return new DefaultEnumeration(searchResult);
477 }
478
479 /***
480 * {@inheritDoc}
481 */
482 public NamingEnumeration search(String name, Attributes matchingAttributes,
483 String[] attributesToReturn)
484 throws NamingException
485 {
486 return search(new CompositeName(name), matchingAttributes, null);
487 }
488
489 /***
490 * {@inheritDoc}
491 */
492 public NamingEnumeration search(Name name, Attributes matchingAttributes)
493 throws NamingException
494 {
495 return search(name, matchingAttributes, null);
496 }
497
498 /***
499 * {@inheritDoc}
500 */
501 public NamingEnumeration search(String name, Attributes matchingAttributes)
502 throws NamingException
503 {
504 return search(new CompositeName(name), matchingAttributes);
505 }
506
507 /***
508 * {@inheritDoc}
509 */
510 public NamingEnumeration search(Name name, String filter, SearchControls cons)
511 throws NamingException
512 {
513 throw new UnsupportedOperationException();
514 }
515
516 /***
517 * {@inheritDoc}
518 */
519 public NamingEnumeration search(String name, String filter, SearchControls cons)
520 throws NamingException
521 {
522 return search(new CompositeName(name), filter, cons);
523 }
524
525 /***
526 * {@inheritDoc}
527 */
528 public NamingEnumeration search(Name name, String filterExpr,
529 Object[] filterArgs, SearchControls cons)
530 throws NamingException
531 {
532 throw new UnsupportedOperationException();
533 }
534
535 /***
536 * {@inheritDoc}
537 */
538 public NamingEnumeration search(String name, String filterExpr,
539 Object[] filterArgs, SearchControls cons)
540 throws NamingException
541 {
542 throw new UnsupportedOperationException();
543 }
544
545 /***
546 * Get all attributes that belongs to specified context.
547 *
548 * @param contextId the context id.
549 * @return the attributes.
550 * @throws NamingException thrown if operation fails.
551 */
552 private Attributes getAllAttributes(long contextId)
553 throws NamingException
554 {
555 Attributes attrs = new BasicAttributes();
556 try
557 {
558 List list = persistence.load("context_id = "+contextId, PersistentAttribute.FACTORY);
559 for(int i = 0; i < list.size(); i++)
560 {
561 PersistentAttribute attribute = (PersistentAttribute)list.get(i);
562 Attribute attr = attrs.get(attribute.getName());
563 if (attr != null)
564 {
565 attr.add(attribute.getValue());
566 }
567 else
568 {
569 attr = new BasicAttribute(attribute.getName());
570 attr.add(attribute.getValue());
571 attrs.put(attr);
572 }
573 }
574 return attrs;
575 }
576 catch(PersistenceException e)
577 {
578 throw new DatabaseNamingException("failed to retrieve context from database",e);
579 }
580 }
581
582 /***
583 * Delete all attributes that belongs to specified context.
584 *
585 * @param contextId the context id.
586 * @throws NamingException thrown if operation fails.
587 */
588 private void deleteAllAttributes(long contextId)
589 throws NamingException
590 {
591 Attributes attrs = new BasicAttributes();
592 try
593 {
594 List list = persistence.load("context_id = "+contextId, PersistentAttribute.FACTORY);
595 for(int i = 0; i < list.size(); i++)
596 {
597 PersistentAttribute attribute = (PersistentAttribute)list.get(i);
598 persistence.delete(attribute);
599 }
600 }
601 catch(PersistenceException e)
602 {
603 throw new DatabaseNamingException("failed to retrieve context from database",e);
604 }
605 }
606
607 /***
608 * Filter attributes with attribute list.
609 *
610 * @param attributes the attributes to be filter.
611 * @param attrIds the filter.
612 * @return the filtered attributes.
613 */
614 private Attributes filterAttributes(Attributes attributes, String[] attrIds)
615 {
616 if(attrIds == null)
617 {
618 return attributes;
619 }
620 Attributes target = new BasicAttributes();
621 for(int i = 0; i < attrIds.length; i++)
622 {
623 Attribute attr = attributes.get(attrIds[i]);
624 if(attr != null)
625 {
626 target.put(attr);
627 }
628 }
629 return target;
630 }
631
632 /***
633 * Get all attributes from child contexts of specified context.
634 *
635 * @param parentId the parent context id.
636 * @return the map with attributes grouped by contexts.
637 * @throws NamingException thrown if operation fails.
638 */
639 private Map getChildrenAttributes(long parentId)
640 throws NamingException
641 {
642 Map map = new HashMap();
643 Connection conn = null;
644 try
645 {
646 conn = persistence.getDatabase().getConnection();
647 Statement statement = conn.createStatement();
648 ResultSet rs = statement.executeQuery(
649 "SELECT dn, name, value FROM ledge_naming_context, ledge_naming_attribute " +
650 "WHERE ledge_naming_context.context_id = ledge_naming_attribute.context_id" +
651 " and ledge_naming_context.parent=" + parentId);
652 while(rs.next())
653 {
654 String dn = rs.getString("dn");
655 String name = rs.getString("name");
656 String value = rs.getString("value");
657 Attributes attributes = (Attributes)map.get(dn);
658 if(attributes == null)
659 {
660 attributes = new BasicAttributes();
661 map.put(dn,attributes);
662 }
663 Attribute attribute = attributes.get(name);
664 if (attribute != null)
665 {
666 attribute.add(value);
667 }
668 else
669 {
670 attribute = new BasicAttribute(name);
671 attribute.add(value);
672 attributes.put(attribute);
673 }
674 }
675 }
676 catch (Exception e)
677 {
678 throw new DatabaseNamingException("Failed to execute query", e);
679 }
680 finally
681 {
682 DatabaseUtils.close(conn);
683 }
684 return map;
685 }
686 }