View Javadoc

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 	 * (non-Javadoc)
134 	 * 
135 	 * @see org.xvsm.interfaces.lookup.ILookup#publish(org.xvsm.core.ContainerRef)
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 				// URI testuri = TransportManagerInstance.getInstance()
177 				// .getDefaultListener().getUri();
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 	 * (non-Javadoc)
227 	 * 
228 	 * @see org.xvsm.interfaces.lookup.ILookup#unpublish(org.xvsm.core.ContainerRef)
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 				// e.printStackTrace();
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 	 * (non-Javadoc)
272 	 * 
273 	 * @see org.xvsm.interfaces.lookup.ILookup#lookup(java.lang.String)
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 	 * (non-Javadoc)
348 	 * 
349 	 * @see org.xvsm.interfaces.lookup.ILookup#lookup(java.util.Hashtable)
350 	 */
351 	public ContainerRef[] lookup(Hashtable list)
352 			throws ContainerNotPublishedException, LookupException {
353 		return lookup(null, list);
354 	}
355 
356 	/*
357 	 * (non-Javadoc)
358 	 * 
359 	 * @see org.xvsm.interfaces.lookup.ILookup#lookup(java.lang.String,
360 	 *      java.util.Hashtable)
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 //						if (xcref.getSite() == null) {
407 //							xcref.setSite(s2);
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 	 * (non-Javadoc)
461 	 * 
462 	 * @see org.xvsm.interfaces.lookup.ILookup#updateDescription(org.xvsm.core.ContainerRef)
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 					// t1.addSelectors(new
541 					// KeySelector<String>("lookup",name));
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 	 * (non-Javadoc)
553 	 * 
554 	 * @see org.xvsm.interfaces.lookup.ILookup#publishedContainers()
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 }