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 info.aduna.platform.Platform;
32 import info.aduna.platform.PlatformFactory;
33
34 import java.io.File;
35 import java.io.IOException;
36 import java.lang.ref.WeakReference;
37 import java.net.URL;
38 import java.util.Locale;
39 import java.util.Map;
40 import java.util.WeakHashMap;
41
42 import javax.persistence.EntityManagerFactory;
43 import javax.xml.namespace.QName;
44
45 import org.openrdf.elmo.ElmoBehaviourFactory;
46 import org.openrdf.elmo.ElmoManagerFactory;
47 import org.openrdf.elmo.ElmoModule;
48 import org.openrdf.elmo.Entity;
49 import org.openrdf.elmo.LiteralManager;
50 import org.openrdf.elmo.RoleMapper;
51 import org.openrdf.elmo.dynacode.ClassFactory;
52 import org.openrdf.elmo.exceptions.ElmoIOException;
53 import org.openrdf.elmo.exceptions.ElmoInitializationException;
54 import org.openrdf.elmo.impl.ElmoEntityCompositor;
55 import org.openrdf.elmo.impl.ElmoMapperClassFactory;
56 import org.openrdf.elmo.impl.InstanceBehaviourFactory;
57 import org.openrdf.model.Literal;
58 import org.openrdf.model.Resource;
59 import org.openrdf.model.URI;
60 import org.openrdf.model.ValueFactory;
61 import org.openrdf.query.QueryLanguage;
62 import org.openrdf.repository.Repository;
63 import org.openrdf.repository.RepositoryException;
64 import org.openrdf.repository.config.RepositoryConfigException;
65 import org.openrdf.repository.contextaware.ContextAwareConnection;
66 import org.openrdf.repository.flushable.FlushableRepository;
67 import org.openrdf.repository.loader.LoaderRepository;
68 import org.openrdf.repository.loader.LoaderRepositoryFactory;
69 import org.openrdf.repository.sail.SailRepository;
70 import org.openrdf.rio.RDFParseException;
71 import org.openrdf.sail.memory.MemoryStore;
72
73
74
75
76
77
78
79 public class SesameManagerFactory implements ElmoManagerFactory, EntityManagerFactory {
80 private static Map<ClassLoader, WeakReference<ClassFactory>> definers = new WeakHashMap<ClassLoader, WeakReference<ClassFactory>>();
81
82 private static Map<ClassLoader, WeakReference<ClassFactory>> inferencingDefiners = new WeakHashMap<ClassLoader, WeakReference<ClassFactory>>();
83
84 private boolean sharedDefiner = true;
85
86 private ClassFactory definer;
87
88 private ElmoEntityCompositor resolver;
89
90 private LoaderRepository repository;
91
92 private QName[] context;
93
94 private LiteralManager<URI, Literal> literalManager;
95
96 private QueryLanguage ql = QueryLanguage.SPARQL;
97
98 private boolean openned = true;
99
100 private boolean inferencing = false;
101
102 private ElmoMapperClassFactory propertyMapper;
103
104 private RoleMapper<URI> mapper;
105
106 private boolean shutDownRepositoryOnClose = false;
107
108
109
110
111 @Deprecated
112 public SesameManagerFactory(Repository repository) {
113 this(new ElmoModule(), repository);
114 }
115
116 public SesameManagerFactory(ElmoModule module) {
117 try {
118 Repository repository = new SailRepository(new MemoryStore());
119 repository.initialize();
120 shutDownRepositoryOnClose = true;
121 setRepository(new LoaderRepository(repository));
122 setElmoModule(module);
123 } catch (RepositoryException e) {
124 throw new ElmoInitializationException(e);
125 }
126 }
127
128 public SesameManagerFactory(ElmoModule module, Repository repository) {
129 setRepository(new LoaderRepository(repository));
130 if (module != null) {
131 setElmoModule(module);
132 } else {
133 new NullPointerException("ElmoModule is null").printStackTrace();
134 }
135 }
136
137 public SesameManagerFactory(ElmoModule module, URL server, String repositoryId) {
138 try {
139 LoaderRepositoryFactory loader = new LoaderRepositoryFactory(server);
140 LoaderRepository repository = loader.createRepository(repositoryId);
141 shutDownRepositoryOnClose = true;
142 setRepository(repository);
143 setElmoModule(module);
144 } catch (RepositoryConfigException e) {
145 throw new ElmoInitializationException(e);
146 } catch (RepositoryException e) {
147 throw new ElmoInitializationException(e);
148 }
149 }
150
151 public SesameManagerFactory(ElmoModule module, File dataDir, String repositoryId) {
152 try {
153 LoaderRepositoryFactory loader = new LoaderRepositoryFactory(dataDir);
154 LoaderRepository repository = loader.createRepository(repositoryId);
155 shutDownRepositoryOnClose = true;
156 setRepository(repository);
157 setElmoModule(module);
158 } catch (RepositoryConfigException e) {
159 throw new ElmoInitializationException(e);
160 } catch (RepositoryException e) {
161 throw new ElmoInitializationException(e);
162 }
163 }
164
165 public SesameManagerFactory(ElmoModule module, String appId,
166 String repositoryId) {
167 this(module, getDataDir(appId), repositoryId);
168 }
169
170 public Repository getRepository() {
171 return repository;
172 }
173
174 public QueryLanguage getQueryLanguage() {
175 return ql;
176 }
177
178 public void setQueryLanguage(QueryLanguage ql) {
179 this.ql = ql;
180 }
181
182 public void setInferencingEnabled(boolean enabled) {
183 inferencing = enabled;
184 if (enabled) {
185 propertyMapper
186 .setElmoPropertyFactoryClass(InferencingPropertyFactory.class);
187 } else {
188 propertyMapper
189 .setElmoPropertyFactoryClass(SesamePropertyFactory.class);
190 }
191 if (sharedDefiner) {
192 setClassDefiner(getSharedDefiner(definer.getParent()));
193 } else {
194 setClassDefiner(new ClassFactory(definer.getParent()));
195 }
196 }
197
198 public RoleMapper<URI> getRoleMapper() {
199 return mapper;
200 }
201
202 public LiteralManager<URI, Literal> getLiteralManager() {
203 return literalManager;
204 }
205
206 public boolean isOpen() {
207 return openned;
208 }
209
210 public void close() {
211 try {
212 if (shutDownRepositoryOnClose) {
213 repository.shutDown();
214 } else {
215 repository.clearLoadedContexts();
216 }
217 } catch (RepositoryException e) {
218 throw new ElmoIOException(e);
219 }
220 openned = false;
221 }
222
223 public SesameManager createEntityManager() {
224 return createElmoManager();
225 }
226
227 public SesameManager createEntityManager(Map properties) {
228 return createElmoManager();
229 }
230
231 public SesameManager createElmoManager() {
232 return createElmoManager(null);
233 }
234
235 public SesameManager createElmoManager(Locale locale) {
236 if (!openned)
237 throw new IllegalStateException("SesameManagerFactory is closed");
238 SesameResourceManager rolesManager;
239 ContextAwareConnection conn;
240 try {
241 conn = new ContextAwareConnection(new FlushableRepository(repository));
242 conn.setQueryLanguage(ql);
243 rolesManager = new SesameResourceManager();
244 rolesManager.setConnection(conn);
245 rolesManager.setValueFactory(repository.getValueFactory());
246 rolesManager.setRoleMapper(mapper);
247 if (context != null && context.length > 0) {
248 Resource[] resources = createResource(rolesManager, context);
249 conn.setAddContexts(resources[0]);
250 conn.setRemoveContexts(resources[0]);
251 conn.setReadContexts(resources);
252 }
253 } catch (RepositoryException e) {
254 throw new ElmoInitializationException(e);
255 }
256 SesameManager manager = new SesameManager();
257 manager.setConnection(conn);
258 manager.setLocale(locale);
259 manager.setElmoClassResolver(resolver);
260 manager.setLiteralManager(literalManager);
261 manager.setRoleMapper(mapper);
262 manager.setResourceManager(rolesManager);
263 return manager;
264 }
265
266 private static File getDataDir(String appId) {
267 Platform platform = PlatformFactory.getPlatform();
268 return platform.getApplicationDataDir(appId);
269 }
270
271 private void setRepository(LoaderRepository repository) {
272 ClassLoader cl = Thread.currentThread().getContextClassLoader();
273 if (cl == null)
274 cl = getClass().getClassLoader();
275 this.repository = repository;
276 ValueFactory vf = repository.getValueFactory();
277 literalManager = new SesameLiteralManager(vf);
278 propertyMapper = new ElmoMapperClassFactory();
279 propertyMapper.setElmoPropertyFactoryClass(SesamePropertyFactory.class);
280 resolver = new ElmoEntityCompositor();
281 resolver.setBehaviourClassResolver(propertyMapper);
282 resolver.addFactoryClass(InstanceBehaviourFactory.class);
283 resolver.addFactoryClass(InstanceBehaviourFactory.class, Entity.class);
284 setClassLoader(cl);
285 if (sharedDefiner) {
286 setClassDefiner(getSharedDefiner(cl));
287 } else {
288 setClassDefiner(new ClassFactory(cl));
289 }
290 }
291
292 private void setClassLoader(ClassLoader cl) {
293 literalManager.setClassLoader(cl);
294 ValueFactory vf = repository.getValueFactory();
295 SesameRoleMapperFactory factory = new SesameRoleMapperFactory(vf);
296 factory.setClassLoader(cl);
297 mapper = factory.createRoleMapper();
298 mapper.recordRole(SesameEntitySupport.class);
299 }
300
301 private void setElmoModule(ElmoModule module) {
302 for (ElmoModule.Association e : module.getLiterals()) {
303 literalManager.recordType(e.getJavaClass(), e.getRdfType());
304 }
305 for (ElmoModule.Association e : module.getRoles()) {
306 if (e.getRdfType() == null) {
307 mapper.recordRole(e.getJavaClass());
308 } else {
309 mapper.recordRole(e.getJavaClass(), e.getRdfType());
310 }
311 }
312 for (ElmoModule.Association e : module.getFactories()) {
313 if (e.getRdfType() == null) {
314 mapper.recordFactory(e.getJavaClass());
315 } else {
316 mapper.recordFactory(e.getJavaClass(), e.getRdfType());
317 }
318 }
319 for (ElmoBehaviourFactory<?> f : module.getRecordedFactoryInstances()) {
320 if (sharedDefiner) {
321 sharedDefiner = false;
322 setClassDefiner(new ClassFactory(definer.getParent()));
323 }
324 resolver.addBehaviourFactory(f);
325 }
326 if (module.getContext() != null) {
327 context = new QName[1 + module.getContexts().size()];
328 context[0] = module.getContext();
329 for (int i=1; i<context.length; i++) {
330 context[i] = module.getContexts().get(i-1);
331 }
332 }
333 for (Map.Entry<URL, String> e : module.getDatasets().entrySet()) {
334 loadContext(e.getKey(), e.getValue());
335 }
336 for (String path : module.getResources()) {
337 loadResources(path);
338 }
339 }
340
341 private Resource[] createResource(SesameResourceManager rolesManager,
342 QName... context) {
343 Resource[] result = new Resource[context.length];
344 for (int i = 0; i < result.length; i++) {
345 result[i] = rolesManager.createResource(context[i]);
346 }
347 return result;
348 }
349
350 private void loadResources(String path) throws ElmoInitializationException {
351 try {
352 repository.loadResources(path);
353 } catch (RepositoryException e) {
354 throw new ElmoInitializationException(e);
355 } catch (RDFParseException e) {
356 throw new ElmoInitializationException(e);
357 } catch (IOException e) {
358 throw new ElmoInitializationException(e);
359 }
360 }
361
362 private void loadContext(URL dataset, String context)
363 throws ElmoInitializationException {
364 try {
365 ValueFactory vf = repository.getValueFactory();
366 repository.loadContext(dataset, vf.createURI(context));
367 } catch (RepositoryException e) {
368 throw new ElmoInitializationException(e);
369 } catch (RDFParseException e) {
370 throw new ElmoInitializationException(e);
371 } catch (IOException e) {
372 throw new ElmoInitializationException(e);
373 }
374 }
375
376 private ClassFactory getSharedDefiner(ClassLoader cl) {
377 ClassFactory definer = null;
378 if (inferencing) {
379 synchronized (inferencingDefiners) {
380 WeakReference<ClassFactory> ref = inferencingDefiners.get(cl);
381 if (ref != null) {
382 definer = ref.get();
383 }
384 if (definer == null) {
385 definer = new ClassFactory(cl);
386 inferencingDefiners.put(cl,
387 new WeakReference<ClassFactory>(definer));
388 }
389 }
390 } else {
391 synchronized (definers) {
392 WeakReference<ClassFactory> ref = definers.get(cl);
393 if (ref != null) {
394 definer = ref.get();
395 }
396 if (definer == null) {
397 definer = new ClassFactory(cl);
398 definers.put(cl, new WeakReference<ClassFactory>(definer));
399 }
400 }
401 }
402 return definer;
403 }
404
405 private void setClassDefiner(ClassFactory definer) {
406 this.definer = definer;
407 propertyMapper.setClassDefiner(definer);
408 resolver.setClassDefiner(definer);
409 }
410 }