1 package org.lcsim.util.xml;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.InvocationTargetException;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9 import org.jdom.Element;
10 import org.jdom.JDOMException;
11
12
13
14
15
16
17 public class DefaultElementFactory implements ElementFactory
18 {
19 private List<Class> classes = new ArrayList<Class>();
20 private Map<Class,String> packageMap = new HashMap<Class,String>();
21
22
23
24
25 public DefaultElementFactory()
26 {}
27
28 public <T> T createElement(Class<T> c, Element node, String type) throws JDOMException, ElementCreationException
29 {
30 if (type != null)
31 {
32 Class<T> cand = getElementClass(c,type);
33 if (cand != null) return create(cand,node);
34 }
35 for (Class cand : classes)
36 {
37 if (c.isAssignableFrom(cand)) return create((Class<? extends T>) cand,node);
38 }
39 throw new ElementCreationException("Unknown element "+c);
40 }
41
42 public void register(Class elementClass,String packageName)
43 {
44 packageMap.put(elementClass,packageName);
45 }
46
47
48
49
50
51
52 public void register(Class elementClass)
53 {
54 classes.add(0,elementClass);
55 }
56 private <T> T create(Class<T> type, Element node) throws ElementCreationException
57 {
58 try
59 {
60 Constructor<T> c = type.getDeclaredConstructor(Element.class);
61 c.setAccessible(true);
62 return c.newInstance(node);
63 }
64 catch (NoSuchMethodException x)
65 {
66 throw new ElementCreationException("Could not create element: "+type,x);
67 }
68 catch (InvocationTargetException x)
69 {
70 throw new ElementCreationException("Could not create element: "+type,x.getCause());
71 }
72 catch (InstantiationException x)
73 {
74 throw new ElementCreationException("Could not create element: "+type,x.getCause());
75 }
76 catch (IllegalAccessException x)
77 {
78 throw new ElementCreationException("Could not create element: "+type,x);
79 }
80 }
81 public <T> Class<T> getElementClass(Class<T> type, String name) throws ElementCreationException
82 {
83 String packageName = packageMap.get(type);
84 if (packageName == null) return null;
85 String key = packageName+"."+name;
86 try
87 {
88 Class result = Class.forName(key);
89 if (!type.isAssignableFrom(result)) throw new ElementCreationException("Element "+key+" is of wrong type");
90 return (Class<T>) result;
91 }
92 catch (ClassNotFoundException x)
93 {
94 return null;
95 }
96 }
97 }