View Javadoc

1   package org.xvsm.lookup;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.lang.reflect.Constructor;
6   import java.lang.reflect.InvocationTargetException;
7   import java.net.MalformedURLException;
8   import java.net.URI;
9   import java.net.URISyntaxException;
10  import java.net.URL;
11  import java.net.URLClassLoader;
12  import java.util.ArrayList;
13  import java.util.Hashtable;
14  import java.util.Iterator;
15  import java.util.List;
16  
17  import org.jdom.Document;
18  import org.jdom.Element;
19  import org.jdom.JDOMException;
20  import org.jdom.input.SAXBuilder;
21  import org.xvsm.coordinators.LindaCoordinator;
22  import org.xvsm.core.AtomicEntry;
23  import org.xvsm.core.Capi;
24  import org.xvsm.core.ContainerRef;
25  import org.xvsm.core.Entry;
26  import org.xvsm.core.Tuple;
27  import org.xvsm.interfaces.container.IContainer;
28  import org.xvsm.interfaces.lookup.ILookup;
29  import org.xvsm.interfaces.lookup.ILookupManager;
30  import org.xvsm.internal.exceptions.CountNotMetException;
31  import org.xvsm.internal.exceptions.XCoreException;
32  import org.xvsm.lookup.exceptions.ContainerAlreadyPublishedException;
33  import org.xvsm.lookup.exceptions.ContainerNotPublishedException;
34  import org.xvsm.lookup.exceptions.LookupException;
35  import org.xvsm.selectors.KeySelector;
36  
37  /***
38   * manages the various implementations of the lookup-services. The configuration
39   * is done via xml config files or environment variables. (see constructors)
40   * 
41   * @author Hannu-Daniel Goiss
42   */
43  public class LookupManager implements ILookupManager {
44  	private LookupTuple[] lookups = null;
45  	private URI site = null;
46  	private Capi capi;
47  	private boolean abbrechen = true;
48  
49  	/***
50  	 * xml-config file constructor, that uses the default file "config.xml"
51  	 * 
52  	 * @param site
53  	 * @throws LookupException
54  	 */
55  	public LookupManager(URI site) throws LookupException {
56  		this(site, new File("config.xml"));
57  	}
58  
59  	/***
60  	 * constructor using a variable to configure the LookupManager. the
61  	 * functionality is the same as when using the xml config file constructor
62  	 * 
63  	 * @param site
64  	 * @param table
65  	 * @throws LookupException
66  	 */
67  	public LookupManager(URI site, Hashtable<String, String> table)
68  			throws LookupException {
69  		ArrayList<LookupTuple> templookups = new ArrayList<LookupTuple>();
70  		Class cls = null;
71  		ILookup lookup;
72  
73  		try {
74  			capi = new Capi();
75  			this.site = site;
76  
77  			try {
78  				for (int i = 1;; i++) {
79  					String lookupimplementation = table.get("Lookup" + i);
80  					if (lookupimplementation == null) {
81  						throw new IndexOutOfBoundsException();
82  					}
83  
84  					String jarFile = table.get(lookupimplementation
85  							+ ".JarFile");
86  
87  					String abbrechenString = table.get("AskAllUnits");
88  					if (abbrechenString == null
89  							|| abbrechenString.compareTo("true") != 0) {
90  						abbrechen = false;
91  					} else {
92  						abbrechen = true;
93  					}
94  
95  					if (jarFile != null) {
96  						URL[] urls = { new URL(jarFile) };
97  						ClassLoader urlc = new URLClassLoader(urls, getClass()
98  								.getClassLoader());
99  						cls = Class.forName(lookupimplementation, true, urlc);
100 					} else {
101 						cls = Class.forName(lookupimplementation);
102 					}
103 
104 					Constructor c = cls.getConstructor(new Class[] { URI.class,
105 							Hashtable.class });
106 					lookup = (ILookup) c
107 							.newInstance(new Object[] { site, table });
108 
109 					templookups.add(new LookupTuple(i, lookup));
110 				}
111 			} catch (IndexOutOfBoundsException ioobe) {
112 			}
113 			lookups = new LookupTuple[templookups.size()];
114 			templookups.toArray(lookups);
115 			java.util.Arrays.sort(lookups);
116 			startLookupManager();
117 		} catch (ClassNotFoundException cnfe) {
118 			throw new LookupException(cnfe);
119 		} catch (InstantiationException ie) {
120 			throw new LookupException(ie);
121 		} catch (IllegalAccessException iae) {
122 			throw new LookupException(iae);
123 		} catch (NoSuchMethodException nsme) {
124 			throw new LookupException(nsme);
125 		} catch (InvocationTargetException ite) {
126 			throw new LookupException(ite);
127 		} catch (MalformedURLException mue) {
128 			throw new LookupException(mue);
129 		} catch (XCoreException xce) {
130 			throw new LookupException(xce);
131 		}
132 	}
133 
134 	/***
135 	 * constructor using a xml config file to configure the LookupManager. the
136 	 * functionality is the same as when using the the environment variable
137 	 * constructor
138 	 * 
139 	 * @param site
140 	 * @param file
141 	 * @throws LookupException
142 	 */
143 	public LookupManager(URI site, File file) throws LookupException {
144 		ArrayList<LookupTuple> templookups = new ArrayList<LookupTuple>();
145 		Class cls = null;
146 		ILookup lookup;
147 
148 		this.validateXML(file);
149 
150 		try {
151 			capi = new Capi();
152 			this.site = site;
153 			SAXBuilder builder = new SAXBuilder();
154 			Document doc = builder.build(file);
155 
156 			Element root = doc.getRootElement();
157 
158 			Element propertiesElement = root.getChild("Properties");
159 
160 			abbrechen = false;
161 			try {
162 				List properties = propertiesElement.getChildren("Property");
163 				Iterator propertiesIterator = properties.iterator();
164 
165 				while (propertiesIterator.hasNext()) {
166 					Element propertyElement = (Element) propertiesIterator
167 							.next();
168 
169 					try {
170 						if (propertyElement.getAttribute("Key").getValue()
171 								.compareTo("AskAllUnits") == 0) {
172 							String abbrechenString = propertyElement
173 									.getTextTrim();
174 							if (abbrechenString.compareTo("true") == 0) {
175 								abbrechen = true;
176 							}
177 						}
178 					} catch (NullPointerException npe) {
179 					}
180 				}
181 			} catch (NullPointerException npe2) {
182 			}
183 
184 			List lookupmanager = root.getChildren("Lookup");
185 
186 			Iterator i = lookupmanager.iterator();
187 			while (i.hasNext()) {
188 				int prioritaet;
189 				String lookupimplementation = "";
190 				boolean jarFileSpecified = true;
191 				String jarFile = "";
192 				Element lookupelement = (Element) i.next();
193 				lookupimplementation = lookupelement.getChild("LookupName")
194 						.getTextTrim();
195 				prioritaet = lookupelement.getAttribute("Priority")
196 						.getIntValue();
197 
198 				try {
199 					jarFile = lookupelement.getChild("JarFile").getTextTrim();
200 				} catch (NullPointerException e) {
201 					jarFileSpecified = false;
202 				}
203 
204 				if (jarFileSpecified == true) {
205 					URL[] urls = { new URL(jarFile) };
206 					ClassLoader urlc = new URLClassLoader(urls, getClass()
207 							.getClassLoader());
208 					cls = Class.forName(lookupimplementation, true, urlc);
209 				} else {
210 					cls = Class.forName(lookupimplementation);
211 				}
212 
213 				Constructor c = cls.getConstructor(new Class[] { URI.class,
214 						Element.class });
215 
216 				lookup = (ILookup) c.newInstance(new Object[] { site,
217 						lookupelement.getChild("LookupUnitSpecific") });
218 
219 				templookups.add(new LookupTuple(prioritaet, lookup));
220 			}
221 			lookups = new LookupTuple[templookups.size()];
222 			templookups.toArray(lookups);
223 			java.util.Arrays.sort(lookups);
224 			startLookupManager();
225 		} catch (XCoreException xce) {
226 			throw new LookupException(xce);
227 		} catch (IOException ioe) {
228 			throw new LookupException(ioe);
229 		} catch (ClassNotFoundException cnfe) {
230 			throw new LookupException(cnfe);
231 		} catch (InstantiationException ie) {
232 			throw new LookupException(ie);
233 		} catch (IllegalAccessException iae) {
234 			throw new LookupException(iae);
235 		} catch (JDOMException je) {
236 			throw new LookupException(je);
237 		} catch (NoSuchMethodException nsme) {
238 			throw new LookupException(nsme);
239 		} catch (InvocationTargetException ite) {
240 			throw new LookupException(ite);
241 		}
242 	}
243 
244 	private void startLookupManager() throws XCoreException {
245 		/*
246 		 * TODO: Kommentar entfernen, sobald Parameter in PreContainerDestroy
247 		 * Aspect nicht mehr null ist. #
248 		 * 
249 		 * 
250 		 * GlobalAspect aspect = new LookupAspect(this); 
251 		 * List<IPoint> p = new ArrayList<IPoint>();
252 		 * p.add(GlobalIPoint.PreContainerDestroy);
253 		 * capi.addAspect(null, p, aspect);
254 		 */
255 	}
256 
257 	/*
258 	 * (non-Javadoc)
259 	 * 
260 	 * @see org.xvsm.interfaces.lookup.ILookupManager#lookup(java.lang.String)
261 	 */
262 	public ContainerRef[] lookup(String name)
263 			throws ContainerNotPublishedException, LookupException {
264 		ArrayList<ContainerRef> containerlist = new ArrayList<ContainerRef>();
265 		ContainerRef[] containers = null;
266 
267 		/*
268 		 * try { Capi capi = new Capi(); try { ContainerRef cref =
269 		 * capi.lookupContainer(null, this.site, name); if
270 		 * (this.getGepublished(cref) == true) { containerlist.add(cref); } }
271 		 * catch (InvalidContainerException ice) { } } catch (XCoreException
272 		 * xce) { throw new LookupException(xce); }
273 		 */
274 		for (int i = 0; (containerlist.size() == 0 || abbrechen == false)
275 				&& i < lookups.length; i++) {
276 			try {
277 				containers = lookups[i].getLookup().lookup(name);
278 
279 				for (ContainerRef c : containers) {
280 					if (containerlist.contains(c) == false)
281 						containerlist.add(c);
282 				}
283 			} catch (Exception e) {
284 				// e.printStackTrace();
285 			}
286 		}
287 
288 		if (containerlist.size() == 0) {
289 			throw new ContainerNotPublishedException(name);
290 		}
291 		containers = new ContainerRef[containerlist.size()];
292 		containerlist.toArray(containers);
293 		return containers;
294 	}
295 
296 	/*
297 	 * (non-Javadoc)
298 	 * 
299 	 * @see org.xvsm.interfaces.lookup.ILookupManager#lookup(java.util.Hashtable)
300 	 */
301 	public ContainerRef[] lookup(Hashtable list)
302 			throws ContainerNotPublishedException, LookupException {
303 		ArrayList<ContainerRef> containerlist = new ArrayList<ContainerRef>();
304 		ContainerRef[] containers = new ContainerRef[0];
305 
306 		for (int i = 0; (containerlist.size() == 0 || abbrechen == false)
307 				&& i < lookups.length; i++) {
308 			try {
309 				containers = lookups[i].getLookup().lookup(list);
310 
311 				for (ContainerRef c : containers) {
312 					if (containerlist.contains(c) == false)
313 						containerlist.add(c);
314 				}
315 			} catch (Exception e) {
316 				e.printStackTrace();
317 			}
318 		}
319 
320 		if (containerlist.size() == 0) {
321 			throw new ContainerNotPublishedException("searched for description");
322 		}
323 		containers = new ContainerRef[containerlist.size()];
324 		containerlist.toArray(containers);
325 		return containers;
326 	}
327 
328 	/*
329 	 * (non-Javadoc)
330 	 * 
331 	 * @see org.xvsm.interfaces.lookup.ILookupManager#lookup(java.lang.String,
332 	 *      java.util.Hashtable)
333 	 */
334 	public ContainerRef[] lookup(String name, Hashtable list)
335 			throws ContainerNotPublishedException, LookupException {
336 		ArrayList<ContainerRef> containerlist = new ArrayList<ContainerRef>();
337 		ContainerRef[] containers = new ContainerRef[0];
338 
339 		for (int i = 0; (containerlist.size() == 0 || abbrechen == false)
340 				&& i < lookups.length; i++) {
341 			try {
342 				containers = lookups[i].getLookup().lookup(name, list);
343 
344 				for (ContainerRef c : containers) {
345 					if (containerlist.contains(c) == false)
346 						containerlist.add(c);
347 				}
348 			} catch (Exception e) {
349 			}
350 		}
351 
352 		if (containerlist.size() == 0) {
353 			throw new ContainerNotPublishedException(name
354 					+ " AND searched for description");
355 		}
356 		containers = new ContainerRef[containerlist.size()];
357 		containerlist.toArray(containers);
358 		return containers;
359 	}
360 
361 	/*
362 	 * (non-Javadoc)
363 	 * 
364 	 * @see org.xvsm.interfaces.lookup.ILookupManager#publish(org.xvsm.core.ContainerRef)
365 	 */
366 	public void publish(ContainerRef cref)
367 			throws ContainerAlreadyPublishedException, LookupException {
368 		ContainerAlreadyPublishedException cape1 = null;
369 		LookupException le1 = null;
370 		ContainerRef crefPublish = cref;
371 
372 		for (int i = 0; i < lookups.length; i++) {
373 			try {
374 				lookups[i].getLookup().publish(crefPublish);
375 			} catch (LookupException le) {
376 				le1 = le;
377 			} catch (ContainerAlreadyPublishedException cape) {
378 				cape1 = cape;
379 			}
380 		}
381 		if (cape1 != null) {
382 			throw cape1;
383 		}
384 		if (le1 != null) {
385 			throw le1;
386 		}
387 	}
388 
389 	public void publish(String name) throws ContainerAlreadyPublishedException,
390 			LookupException {
391 		ContainerAlreadyPublishedException cape1 = null;
392 		LookupException le1 = null;
393 
394 		for (int i = 0; i < lookups.length; i++) {
395 			try {
396 				lookups[i].getLookup().publish(new ContainerRef());
397 			} catch (LookupException le) {
398 				le1 = le;
399 			} catch (ContainerAlreadyPublishedException cape) {
400 				cape1 = cape;
401 			}
402 		}
403 		if (cape1 != null) {
404 			throw cape1;
405 		}
406 		if (le1 != null) {
407 			throw le1;
408 		}
409 	}
410 
411 	/*
412 	 * (non-Javadoc)
413 	 * 
414 	 * @see org.xvsm.interfaces.lookup.ILookupManager#unpublish(org.xvsm.core.ContainerRef)
415 	 */
416 	public void unpublish(ContainerRef cref)
417 			throws ContainerNotPublishedException, LookupException {
418 		ContainerNotPublishedException cnpe1 = null;
419 		LookupException le1 = null;
420 
421 		try {
422 			this.setGepublished(cref, false);
423 		} catch (XCoreException xce) {
424 			throw new LookupException(xce);
425 		}
426 
427 		for (int i = 0; i < lookups.length; i++) {
428 			try {
429 				lookups[i].getLookup().unpublish(cref);
430 			} catch (ContainerNotPublishedException cnpe) {
431 				cnpe1 = cnpe;
432 			} catch (LookupException le) {
433 				le1 = le;
434 			}
435 		}
436 		if (cnpe1 != null) {
437 			throw cnpe1;
438 		}
439 		if (le1 != null) {
440 			throw le1;
441 		}
442 	}
443 
444 	/*
445 	 * (non-Javadoc)
446 	 * 
447 	 * @see org.xvsm.interfaces.lookup.ILookupManager#updateDescription(org.xvsm.core.ContainerRef)
448 	 */
449 	public void updateDescription(ContainerRef cref)
450 			throws ContainerNotPublishedException, LookupException {
451 		ContainerNotPublishedException cnpe1 = null;
452 		LookupException le1 = null;
453 
454 		for (int i = 0; i < lookups.length; i++) {
455 			try {
456 				lookups[i].getLookup().updateDescription(cref);
457 			} catch (ContainerNotPublishedException cnpe) {
458 				cnpe1 = cnpe;
459 			} catch (LookupException le) {
460 				le1 = le;
461 			}
462 		}
463 		if (cnpe1 != null) {
464 			throw cnpe1;
465 		}
466 		if (le1 != null) {
467 			throw le1;
468 		}
469 	}
470 
471 	/*
472 	 * (non-Javadoc)
473 	 * 
474 	 * @see org.xvsm.interfaces.lookup.ILookupManager#publishedContainers()
475 	 */
476 	public ContainerRef[] publishedContainers() throws LookupException {
477 		ArrayList<ContainerRef> containerlist = new ArrayList<ContainerRef>();
478 		ContainerRef[] containers = null;
479 		LookupException le1 = null;
480 
481 //		for (int i = 0; i < lookups.length; i++) {
482 //			try {
483 //				containers = lookups[i].getLookup().publishedContainers();
484 //
485 //				for (ContainerRef c : containers) {
486 //					if (containerlist.contains(c) == false)
487 //						containerlist.add(c);
488 //				}
489 //			} catch (LookupException le) {
490 //				le1 = le;
491 //			}
492 //		}
493 
494 		if (containerlist.size() == 0 && le1 == null) {
495 			return null;
496 		} else if (le1 != null && containerlist.size() == 0) {
497 			throw le1;
498 		}
499 
500 		containers = new ContainerRef[containerlist.size()];
501 		containerlist.toArray(containers);
502 		return containers;
503 	}
504 
505 	private void setGepublished(ContainerRef cref, boolean gepublished)
506 			throws XCoreException {
507 		ContainerRef metaCref = LookupManager.lookupMetaContainer(cref);
508 
509 		capi.shift(metaCref, null,
510 				new AtomicEntry<Boolean>(gepublished, Boolean.class,
511 						new KeySelector<String>("system", "gepublished")));
512 	}
513 
514 	public boolean getGepublished(ContainerRef cref) throws XCoreException {
515 		ContainerRef metaCref = LookupManager.lookupMetaContainer(cref);
516 
517 		try {
518 			return (Boolean) ((AtomicEntry) capi.read(metaCref, 0, null,
519 					new KeySelector<String>("system", "gepublished"))[0])
520 					.getValue();
521 		} catch (CountNotMetException cnme) {
522 			return false;
523 		}
524 	}
525 
526 	private void validateXML(File file) throws LookupException {
527 		/*
528 		 * String schema = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<xs:schema
529 		 * xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">" + " <xs:import
530 		 * namespace=\"http://www.w3.org/XML/1998/namespace\"
531 		 * schemaLocation=\"http://www.w3.org/2001/xml.xsd\"/>" + " <xs:element
532 		 * name=\"LookupManager\">" + " <xs:complexType>" + " <xs:sequence>" + "
533 		 * <xs:element name=\"Lookup\" type=\"LookupUnit\" minOccurs=\"1\"
534 		 * maxOccurs=\"unbounded\">" + " <xs:unique name=\"dummy1\">" + "
535 		 * <xs:selector xpath=\"LookupManager/LookupUnit\"/>" + " <xs:field
536 		 * xpath=\"@LookupName\"/>" + " </xs:unique>" + " </xs:element>" + "
537 		 * </xs:sequence>" + " </xs:complexType>" + " </xs:element>" + "
538 		 * <xs:complexType name=\"LookupUnit\">" + " <xs:sequence>" + "
539 		 * <xs:element name=\"LookupName\" type=\"xs:string\"/>" + " <xs:element
540 		 * name=\"JarFile\" type=\"xs:string\" minOccurs=\"0\"/>" + "
541 		 * <xs:element name=\"LookupUnitSpecific\"/>" + " </xs:sequence>" + "
542 		 * <xs:attribute name=\"Priority\" type=\"xs:int\" use=\"required\"/>" + "
543 		 * </xs:complexType>" + "</xs:schema>";
544 		 * 
545 		 * try { Validator validator = SchemaFactory.newInstance(
546 		 * XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema( new StreamSource(new
547 		 * StringReader(schema))).newValidator();
548 		 * 
549 		 * validator.validate(new StreamSource(new FileReader(file))); } catch
550 		 * (FileNotFoundException fnfe) { throw new LookupException("File " +
551 		 * file.getName() + " could not be found"); } catch (IOException ioe) {
552 		 * throw new LookupException(ioe); } catch (SAXException saxe) { throw
553 		 * new LookupException(saxe); }
554 		 */
555 	}
556 
557 	public static ContainerRef lookupMetaContainer(ContainerRef cref)
558 			throws LookupException {
559 		ContainerRef metaCref = null;
560 
561 		try {
562 			metaCref = new ContainerRef(new URI(cref.asURI().toASCIIString()
563 					+ "/meta"));
564 		} catch (URISyntaxException use) {
565 			throw new LookupException(use);
566 		}
567 
568 		metaCref.setSite(cref.getSite());
569 
570 		return metaCref;
571 	}
572 
573 	/***
574 	 * @param cref
575 	 * @param key
576 	 * @param value
577 	 * @throws XCoreException
578 	 */
579 	public void addMetaInfo(ContainerRef cref, String key, String value)
580 			throws XCoreException {
581 		ContainerRef metaCref = LookupManager.lookupMetaContainer(cref);
582 		ContainerRef info = null;
583 
584 		try {
585 			info = (ContainerRef) ((AtomicEntry) capi.read(metaCref, 0, null,
586 					new KeySelector<String>("system", "meta_information"))[0])
587 					.getValue();
588 		} catch (CountNotMetException cnme) {
589 			info = capi.createContainer(null, null, null,
590 					IContainer.INFINITE_SIZE, new LindaCoordinator());
591 			capi.write(metaCref, 0, null, new AtomicEntry<ContainerRef>(info,
592 					ContainerRef.class, new KeySelector<String>("system",
593 							"meta_information")));
594 		}
595 
596 		Entry a1 = new AtomicEntry<String>(key);
597 		Entry a2 = new AtomicEntry<String>(value);
598 		Tuple t1 = new Tuple(a1, a2);
599 
600 		capi.shift(info, null, t1);
601 	}
602 }