1 package org.xvsm.lookup.xvsm;
2
3 import java.net.URI;
4 import java.net.URISyntaxException;
5 import java.util.ArrayList;
6 import java.util.Enumeration;
7 import java.util.Hashtable;
8
9 import org.jdom.Element;
10 import org.xvsm.configuration.ConfigurationManager;
11 import org.xvsm.coordinators.KeyCoordinator;
12 import org.xvsm.coordinators.LindaCoordinator;
13 import org.xvsm.core.AtomicEntry;
14 import org.xvsm.core.Capi;
15 import org.xvsm.core.ContainerRef;
16 import org.xvsm.core.Entry;
17 import org.xvsm.core.Tuple;
18 import org.xvsm.interfaces.ICapi;
19 import org.xvsm.interfaces.container.IContainer;
20 import org.xvsm.interfaces.lookup.ILookup;
21 import org.xvsm.internal.exceptions.ContainerFullException;
22 import org.xvsm.internal.exceptions.ContainerNameOccupiedException;
23 import org.xvsm.internal.exceptions.CountNotMetException;
24 import org.xvsm.internal.exceptions.InvalidContainerException;
25 import org.xvsm.internal.exceptions.XCoreException;
26 import org.xvsm.lookup.LookupManager;
27 import org.xvsm.lookup.exceptions.ContainerAlreadyPublishedException;
28 import org.xvsm.lookup.exceptions.ContainerNotPublishedException;
29 import org.xvsm.lookup.exceptions.LookupException;
30 import org.xvsm.remote.TransportHandler;
31 import org.xvsm.selectors.KeySelector;
32 import org.xvsm.selectors.LindaSelector;
33 import org.xvsm.selectors.RandomSelector;
34 import org.xvsm.transactions.Transaction;
35
36 /***
37 * This is the implementation of the ILookup-Interface using XVSM containers.
38 * For publishing containers are 2 containers created on the lookup-server:
39 * "LookupContainer" and "LookupContainerDetails".
40 *
41 * @author Hannu-Daniel Goiss
42 */
43 public class XVSMLookup implements ILookup {
44 private URI remoteCapi;
45 private ICapi capi;
46
47 /***
48 * Constructor for use with environment variable
49 *
50 * @param site
51 * @param table
52 * @throws LookupException
53 */
54 public XVSMLookup(URI site, Hashtable<String, String> table)
55 throws LookupException {
56 URI remotesiteURI = null;
57
58 String remotesite = table
59 .get("org.xvsm.lookup.xvsm.XVSMLookup.RemoteURI");
60
61 if (remotesite.compareTo("") != 0) {
62 try {
63 remotesiteURI = new URI(remotesite);
64 } catch (URISyntaxException use) {
65 throw new LookupException(use);
66 }
67 }
68 startLookup(site, remotesiteURI);
69 }
70
71 /***
72 * Constructor for use with XML file
73 *
74 * @param site
75 * @param element
76 * @throws LookupException
77 */
78 public XVSMLookup(URI site, Element element) throws LookupException {
79 URI remotesiteURI = null;
80
81 String remotesite = element.getChild("RemoteURI").getTextTrim();
82
83 if (remotesite.compareTo("") != 0) {
84 try {
85 remotesiteURI = new URI(remotesite);
86 } catch (URISyntaxException use) {
87 throw new LookupException(use);
88 }
89 }
90 startLookup(site, remotesiteURI);
91 }
92
93 /***
94 * @param site
95 * @param remote_site
96 * @throws LookupException
97 */
98 public XVSMLookup(URI site, URI remote_site) throws LookupException {
99 startLookup(site, remote_site);
100 }
101
102 /***
103 * @param site
104 * @param remote_site
105 * @throws LookupException
106 */
107 private void startLookup(URI site, URI remote_site) throws LookupException {
108 try {
109 capi = new Capi();
110
111 ContainerRef cref = null;
112 try {
113 cref = capi.createContainer(null, remote_site,
114 "LookupContainer", IContainer.INFINITE_SIZE,
115 new KeyCoordinator(new KeyCoordinator.KeyType("lookup",
116 String.class)), new LindaCoordinator());
117 } catch (ContainerNameOccupiedException cnoe) {
118 }
119 try {
120 capi.createContainer(null, remote_site,
121 "LookupContainerDetails", IContainer.INFINITE_SIZE,
122 new KeyCoordinator(new KeyCoordinator.KeyType("lookup",
123 String.class)), new LindaCoordinator());
124 } catch (ContainerNameOccupiedException cnoe) {
125 }
126 remoteCapi = remote_site;
127 } catch (XCoreException xce) {
128 throw new LookupException(xce);
129 }
130 }
131
132
133
134
135
136
137 public void publish(ContainerRef cref)
138 throws ContainerAlreadyPublishedException, LookupException {
139 String ipname;
140 String name = null;
141 Transaction tx = null;
142 ContainerRef lookup_cref;
143 boolean throwException = false;
144
145 try {
146 name = this.getContainerName(cref);
147 } catch (LookupException le) {
148 }
149
150 catch (XCoreException xce) {
151 throw new LookupException(xce);
152 }
153
154 try {
155 ipname = name;
156
157 try {
158 try {
159 lookup_cref = capi.lookupContainer(null, remoteCapi,
160 "LookupContainer");
161 } catch (InvalidContainerException e) {
162 lookup_cref = capi.createContainer(null, remoteCapi,
163 "LookupContainer", IContainer.INFINITE_SIZE,
164 new KeyCoordinator(new KeyCoordinator.KeyType(
165 "lookup", String.class)),
166 new LindaCoordinator());
167 }
168
169 tx = capi.createTransaction(remoteCapi, Capi.INFINITE_TIMEOUT);
170
171 Entry a1 = new AtomicEntry<String>(name);
172 Entry a2 = new AtomicEntry<ContainerRef>(cref);
173 URI testuri = TransportHandler.getInstance().getListener(
174 ConfigurationManager.getInstance().getStringSetting(
175 "DefaultAnswerToProtocol")).getUri();
176
177
178
179 Entry a3 = new AtomicEntry<URI>(testuri);
180
181 Tuple t1 = new Tuple(a1, a2, a3);
182 t1.addSelectors(new KeySelector<String>("lookup", name));
183
184 try {
185 capi.write(lookup_cref, 0, tx, t1);
186 } catch (ContainerFullException e) {
187 throwException = true;
188 }
189
190 if (throwException == false) {
191 this.updateDescription(cref, tx);
192 capi.commitTransaction(tx);
193 } else {
194 capi.rollbackTransaction(tx);
195 }
196
197 } catch (XCoreException e) {
198 try {
199 capi.rollbackTransaction(tx);
200 } catch (Exception e1) {
201 }
202
203 try {
204 unpublish(cref);
205 } catch (Exception e1) {
206
207 }
208
209 throw new LookupException(e);
210 }
211
212 } catch (XCoreException xce) {
213 throw new LookupException(xce);
214 }
215 if (throwException == true) {
216 throw new ContainerAlreadyPublishedException(name);
217 }
218 }
219
220 public void publish(String name) throws ContainerAlreadyPublishedException,
221 LookupException {
222
223 }
224
225
226
227
228
229
230 public void unpublish(ContainerRef cref)
231 throws ContainerNotPublishedException, LookupException {
232 Transaction tx = null;
233 String name;
234
235 try {
236 name = getContainerName(cref);
237
238 try {
239 ContainerRef rem_cref = capi.lookupContainer(null, remoteCapi,
240 "LookupContainer");
241 ContainerRef rem_cref_def = capi.lookupContainer(null,
242 remoteCapi, "LookupContainerDetails");
243 tx = capi.createTransaction(remoteCapi, Capi.INFINITE_TIMEOUT);
244
245 try {
246 capi.destroy(rem_cref, 0, tx, new KeySelector<String>(
247 "lookup", name));
248 } catch (CountNotMetException cnme) {
249 }
250 try {
251 capi.destroy(rem_cref_def, 0, tx, new KeySelector<String>(
252 "lookup", name));
253 } catch (CountNotMetException cnme) {
254 }
255
256 capi.commitTransaction(tx);
257 } catch (Exception e) {
258
259
260 try {
261 capi.rollbackTransaction(tx);
262 } catch (Exception e1) {
263 }
264 }
265 } catch (XCoreException xce) {
266 throw new LookupException(xce);
267 }
268 }
269
270
271
272
273
274
275 public ContainerRef[] lookup(String name)
276 throws ContainerNotPublishedException, LookupException {
277 Transaction tx = null;
278 boolean vorhanden;
279 ArrayList<ContainerRef> containers = new ArrayList<ContainerRef>();
280 ContainerRef tempContainer = null;
281 String containerName = null;
282 URI containerIp = null;
283
284 try {
285 try {
286 ContainerRef rem_cref = capi.lookupContainer(null, remoteCapi,
287 "LookupContainer");
288
289 tx = capi.createTransaction(remoteCapi, Capi.INFINITE_TIMEOUT);
290
291 Entry[] entries1 = capi.read(rem_cref, 0, tx,
292 new KeySelector<String>("lookup", name));
293
294 capi.commitTransaction(tx);
295
296 if (entries1.length > 0) {
297 Tuple t1 = (Tuple) entries1[0];
298
299 Entry[] e = t1.toArray();
300
301 AtomicEntry ae1 = (AtomicEntry) e[0];
302 AtomicEntry ae2 = (AtomicEntry) e[1];
303 AtomicEntry ae3 = (AtomicEntry) e[2];
304
305 containerName = (String) ae1.getValue();
306 tempContainer = (ContainerRef) ae2.getValue();
307 containerIp = (URI) ae3.getValue();
308 if (tempContainer.getSite() == null) {
309 tempContainer.setSite(containerIp);
310 }
311
312 vorhanden = false;
313 for (int j = 0; j < containers.size() && vorhanden == false; j++) {
314 if (tempContainer.toString().compareTo(
315 containers.get(j).toString()) == 0) {
316 vorhanden = true;
317 }
318 }
319 if (vorhanden == false) {
320 containers.add(tempContainer);
321 }
322 }
323 } catch (Exception e) {
324 try {
325 capi.rollbackTransaction(tx);
326 } catch (Exception e1) {
327 }
328 }
329
330 if (containers.size() == 0) {
331 throw new ContainerNotPublishedException(name);
332 }
333
334 ContainerRef[] containerArray = new ContainerRef[containers.size()];
335
336 for (int i = 0; i < containers.size(); i++) {
337 containerArray[i] = containers.get(i);
338 }
339
340 return containerArray;
341 } catch (XCoreException xce) {
342 throw new LookupException(xce);
343 }
344 }
345
346
347
348
349
350
351 public ContainerRef[] lookup(Hashtable list)
352 throws ContainerNotPublishedException, LookupException {
353 return lookup(null, list);
354 }
355
356
357
358
359
360
361
362 public ContainerRef[] lookup(String name, Hashtable list)
363 throws ContainerNotPublishedException, LookupException {
364 Transaction tx = null;
365 ArrayList<ContainerRef> containers = new ArrayList<ContainerRef>();
366 ArrayList<ContainerRef> containers2 = new ArrayList<ContainerRef>();
367 String containerName = null;
368 URI containerIp = null;
369
370 try {
371 try {
372 ContainerRef rem_cref = capi.lookupContainer(null, remoteCapi,
373 "LookupContainerDetails");
374 ContainerRef metaCref = LookupManager
375 .lookupMetaContainer(rem_cref);
376
377 tx = capi.createTransaction(remoteCapi, Capi.INFINITE_TIMEOUT);
378
379 int count = 0;
380 containers2.clear();
381 for (Enumeration enumeration = list.keys(); enumeration
382 .hasMoreElements();) {
383 String key = (String) enumeration.nextElement();
384 String value = (String) list.get(key);
385
386 LindaSelector ts = new LindaSelector(Capi.INFINITE,
387 new Tuple(new AtomicEntry<ContainerRef>(
388 ContainerRef.class),
389 new AtomicEntry<String>(key),
390 new AtomicEntry<String>(value)));
391 Entry[] entries1 = capi.read(rem_cref, 0, tx, ts);
392
393 for (Entry entry : entries1) {
394 Tuple t1 = (Tuple) entry;
395
396 Entry[] e = t1.toArray();
397
398 AtomicEntry ae1 = (AtomicEntry) e[0];
399 AtomicEntry ae2 = (AtomicEntry) e[1];
400 AtomicEntry ae3 = (AtomicEntry) e[2];
401
402 ContainerRef xcref = (ContainerRef) ae1.getValue();
403 String s1 = (String) ae2.getValue();
404 String s2 = (String) ae3.getValue();
405
406
407
408
409
410 containerName = this.getContainerName(xcref);
411
412 if ((name != null && containerName.compareTo(name) == 0)
413 || name == null) {
414 try {
415 xcref = this.lookup(containerName)[0];
416 if (count == 0) {
417 containers.add(xcref);
418 } else {
419 containers2.add(xcref);
420 }
421 } catch (ContainerNotPublishedException cnfe) {
422
423 }
424 }
425 }
426 if (count == 0) {
427 } else {
428 containers.retainAll(containers2);
429 }
430
431 count++;
432 }
433
434 capi.commitTransaction(tx);
435 } catch (Exception e) {
436 try {
437 capi.rollbackTransaction(tx);
438 } catch (Exception e1) {
439 }
440 }
441
442 if (containers.size() == 0) {
443 throw new ContainerNotPublishedException(
444 "searched for meta information");
445 }
446
447 ContainerRef[] containerArray = new ContainerRef[containers.size()];
448
449 for (int i = 0; i < containers.size(); i++) {
450 containerArray[i] = containers.get(i);
451 }
452
453 return containerArray;
454 } catch (XCoreException xce) {
455 throw new LookupException(xce);
456 }
457 }
458
459
460
461
462
463
464 public void updateDescription(ContainerRef cref)
465 throws ContainerNotPublishedException, LookupException {
466 Transaction tx = null;
467 try {
468 tx = capi.createTransaction(remoteCapi, Capi.INFINITE_TIMEOUT);
469
470 this.updateDescription(cref, tx);
471
472 capi.commitTransaction(tx);
473 } catch (XCoreException xce) {
474 try {
475 capi.rollbackTransaction(tx);
476 } catch (Exception e) {
477
478 }
479
480 throw new LookupException(xce);
481 }
482 }
483
484 /***
485 * @param cref
486 * @param tx
487 * @throws LookupException
488 */
489 private void updateDescription(ContainerRef cref, Transaction tx)
490 throws LookupException {
491 try {
492 String name = this.getContainerName(cref);
493 ContainerRef metaInfo = this.getMetaInfoCref(cref);
494 ContainerRef lookup_cref_def;
495 try {
496 lookup_cref_def = capi.lookupContainer(null, remoteCapi,
497 "LookupContainerDetails");
498
499 try {
500 capi.destroy(lookup_cref_def, 0, tx,
501 new KeySelector<String>("lookup", name));
502 } catch (CountNotMetException cnme) {
503
504 }
505 } catch (InvalidContainerException e) {
506 lookup_cref_def = capi.createContainer(null, remoteCapi,
507 "LookupContainerDetails", IContainer.INFINITE_SIZE,
508 new KeyCoordinator(new KeyCoordinator.KeyType("lookup",
509 String.class)), new LindaCoordinator());
510 }
511
512 if (metaInfo != null) {
513 ContainerRef metaCref = LookupManager.lookupMetaContainer(cref);
514
515 String containerName = (String) ((AtomicEntry) capi.read(
516 metaCref, 0, null, new KeySelector<String>("system",
517 "name"))[0]).getValue();
518
519 LindaSelector ts = new LindaSelector(Capi.INFINITE, new Tuple(
520 null, null));
521
522 Entry[] entries1 = capi.read(metaInfo, 0, null, ts);
523
524 for (Entry entry : entries1) {
525 Tuple tuple = (Tuple) entry;
526
527 Entry[] e = tuple.toArray();
528
529 AtomicEntry ae1 = (AtomicEntry) e[0];
530 AtomicEntry ae2 = (AtomicEntry) e[1];
531
532 String eins = (String) ae1.getValue();
533 String zwei = (String) ae2.getValue();
534
535 Entry a1 = new AtomicEntry<ContainerRef>(cref);
536 Entry a2 = new AtomicEntry<String>(eins);
537 Entry a3 = new AtomicEntry<String>(zwei);
538
539 Tuple t1 = new Tuple(a1, a2, a3);
540
541
542
543 capi.write(lookup_cref_def, 0, tx, t1);
544 }
545 }
546 } catch (XCoreException xce) {
547 throw new LookupException(xce);
548 }
549 }
550
551
552
553
554
555
556 public ContainerRef[] publishedContainers() throws LookupException {
557 Transaction tx = null;
558 ArrayList<ContainerRef> containers = new ArrayList<ContainerRef>();
559 ContainerRef tempContainer = null;
560 String containerName = null;
561 URI containerIp = null;
562
563 try {
564 ContainerRef rem_cref = capi.lookupContainer(null, remoteCapi,
565 "LookupContainer");
566
567 tx = capi.createTransaction(remoteCapi, Capi.INFINITE_TIMEOUT);
568
569 Entry[] entries1 = capi.read(rem_cref, 0, tx, new RandomSelector(
570 RandomSelector.CNT_ALL));
571
572 capi.commitTransaction(tx);
573
574 if (entries1.length > 0) {
575 Tuple t1 = (Tuple) entries1[0];
576
577 Entry[] e = t1.toArray();
578
579 AtomicEntry ae1 = (AtomicEntry) e[0];
580 AtomicEntry ae2 = (AtomicEntry) e[1];
581 AtomicEntry ae3 = (AtomicEntry) e[2];
582
583 containerName = (String) ae1.getValue();
584 tempContainer = (ContainerRef) ae2.getValue();
585 containerIp = (URI) ae3.getValue();
586 if (tempContainer.getSite() == null) {
587 tempContainer.setSite(containerIp);
588 }
589
590 containers.add(tempContainer);
591 }
592 } catch (Exception e) {
593 try {
594 capi.rollbackTransaction(tx);
595 } catch (Exception e1) {
596 }
597 }
598
599 if (containers.size() == 0) {
600 return null;
601 }
602
603 ContainerRef[] containerArray = new ContainerRef[containers.size()];
604
605 for (int i = 0; i < containers.size(); i++) {
606 containerArray[i] = containers.get(i);
607 }
608
609 return containerArray;
610 }
611
612 /***
613 * @param cref
614 * @return
615 * @throws XCoreException
616 */
617 private String getContainerName(ContainerRef cref) throws XCoreException {
618 ContainerRef metaCref = LookupManager.lookupMetaContainer(cref);
619 String containerName = (String) ((AtomicEntry) capi.read(metaCref, 0,
620 null, new KeySelector<String>("system", "name"))[0]).getValue();
621
622 return containerName;
623 }
624
625 /***
626 * @param cref
627 * @return
628 * @throws XCoreException
629 */
630 private ContainerRef getMetaInfoCref(ContainerRef cref)
631 throws XCoreException {
632 ContainerRef metaCref = LookupManager.lookupMetaContainer(cref);
633 try {
634 return (ContainerRef) ((AtomicEntry) capi.read(metaCref, 0, null,
635 new KeySelector<String>("system", "meta_information"))[0])
636 .getValue();
637 } catch (CountNotMetException cnme) {
638 return null;
639 }
640 }
641 }