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 package org.openrdf.elmo.sesame;
30
31 import java.io.File;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.net.URL;
35 import java.util.ArrayList;
36 import java.util.Enumeration;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Map;
40
41 import javax.persistence.PersistenceException;
42 import javax.persistence.spi.PersistenceProvider;
43 import javax.persistence.spi.PersistenceUnitInfo;
44 import javax.xml.parsers.DocumentBuilder;
45 import javax.xml.parsers.DocumentBuilderFactory;
46 import javax.xml.parsers.ParserConfigurationException;
47
48 import org.openrdf.elmo.ElmoModule;
49 import org.w3c.dom.Document;
50 import org.w3c.dom.Element;
51 import org.w3c.dom.Node;
52 import org.w3c.dom.NodeList;
53 import org.w3c.dom.Text;
54 import org.xml.sax.SAXException;
55
56
57
58
59
60
61
62
63 public class SesamePersistenceProvider implements PersistenceProvider {
64
65 public final static String PERSISTENCE_XML = "META-INF/persistence.xml";
66
67 private static final String PROVIDER_NAME = SesamePersistenceProvider.class.getName();
68
69 public SesameManagerFactory createContainerEntityManagerFactory(
70 PersistenceUnitInfo info, Map map) {
71 if (!PROVIDER_NAME.equals(info.getPersistenceProviderClassName()))
72 return null;
73 try {
74 ClassLoader cl = info.getClassLoader();
75 List<String> names = info.getManagedClassNames();
76 List<Class<?>> types = new ArrayList<Class<?>>(names.size());
77 for (String name : names) {
78 types.add(Class.forName(name, true, cl));
79 }
80 Map props = new HashMap();
81 props.putAll(info.getProperties());
82 if (map != null) {
83 props.putAll(map);
84 }
85 return createSesameManagerFactory(props, types);
86 } catch (Exception e) {
87 throw new PersistenceException(e);
88 }
89 }
90
91 public SesameManagerFactory createEntityManagerFactory(String emName,
92 Map map) {
93 try {
94 Element unit = findPresistenceUnit(emName);
95 NodeList providers = unit.getElementsByTagName("provider");
96 if (providers.getLength() > 0) {
97 Element provider = (Element) providers.item(0);
98 if (!PROVIDER_NAME.equals(getTextContent(provider)))
99 return null;
100 }
101 ClassLoader cl = Thread.currentThread().getContextClassLoader();
102 NodeList names = unit.getElementsByTagName("class");
103 List<Class<?>> types = new ArrayList<Class<?>>(names.getLength());
104 for (int i = 0, n = names.getLength(); i < n; i++) {
105 String name = getTextContent(names.item(i));
106 types.add(Class.forName(name, true, cl));
107 }
108 Map props = new HashMap();
109 props.putAll(getProperties(unit));
110 if (map != null) {
111 props.putAll(map);
112 }
113 return createSesameManagerFactory(props, types);
114 } catch (Exception e) {
115 throw new PersistenceException(e);
116 }
117 }
118
119 private String getTextContent(Node node) {
120 node.normalize();
121 Text text = (Text) node.getFirstChild();
122 return text.getData().trim();
123 }
124
125 private SesameManagerFactory createSesameManagerFactory(
126 Map<String, String> props, List<Class<?>> types) throws Exception {
127 ElmoModule module = new ElmoModule();
128 if (types != null) {
129 for (Class<?> type : types) {
130 module.recordRole(type);
131 }
132 }
133 if (props.containsKey("resources")) {
134 String resources = props.get("resources");
135 for (String resource : resources.trim().split("[,\\s]+")) {
136 module.addResources(resource);
137 }
138 }
139 return createSesameManagerFactory(module, props);
140 }
141
142 private SesameManagerFactory createSesameManagerFactory(ElmoModule module,
143 Map<String, String> props) throws Exception {
144 String id = props.get("repositoryId");
145 if (id != null && props.containsKey("dataDir")) {
146 File dataDir = new File(props.get("dataDir"));
147 return new SesameManagerFactory(module, dataDir, id);
148 }
149 if (id != null && props.containsKey("serverUrl")) {
150 URL server = new URL(props.get("serverUrl"));
151 return new SesameManagerFactory(module, server, id);
152 }
153 if (id != null && props.containsKey("applicationId")) {
154 String appId = props.get("applicationId");
155 return new SesameManagerFactory(module, appId, id);
156 }
157 return new SesameManagerFactory(module);
158 }
159
160 private Element findPresistenceUnit(String emName) throws SAXException,
161 IOException, ParserConfigurationException {
162 ClassLoader cl = Thread.currentThread().getContextClassLoader();
163 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
164 DocumentBuilder parser = dbf.newDocumentBuilder();
165 Enumeration<URL> resources = cl.getResources(PERSISTENCE_XML);
166 while (resources.hasMoreElements()) {
167 URL url = resources.nextElement();
168 InputStream stream = url.openStream();
169 try {
170 Document doc = parser.parse(stream);
171 NodeList list = doc.getElementsByTagName("persistence-unit");
172 for (int i = 0, n = list.getLength(); i < n; i++) {
173 Element item = (Element) list.item(i);
174 if (emName.equals(item.getAttribute("name")))
175 return item;
176 }
177 } finally {
178 stream.close();
179 }
180 }
181 throw new IllegalArgumentException(
182 "Cannot find persistence-unit with name: " + emName);
183 }
184
185 private Map<String, String> getProperties(Element unit) {
186 Map<String, String> properties = new HashMap<String, String>();
187 NodeList list = unit.getElementsByTagName("property");
188 for (int i = 0, n = list.getLength(); i < n; i++) {
189 Element item = (Element) list.item(i);
190 properties.put(item.getAttribute("name"), item
191 .getAttribute("value"));
192 }
193 return properties;
194 }
195
196 }