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.dynabean.helpers;
30
31 import info.aduna.iteration.CloseableIteration;
32
33 import java.util.ArrayList;
34 import java.util.Collection;
35 import java.util.List;
36 import java.util.concurrent.ConcurrentHashMap;
37 import java.util.concurrent.ConcurrentMap;
38
39 import org.openrdf.elmo.exceptions.ElmoCompositionException;
40 import org.openrdf.elmo.sesame.SesameManager;
41 import org.openrdf.model.Resource;
42 import org.openrdf.model.Statement;
43 import org.openrdf.model.URI;
44 import org.openrdf.model.Value;
45 import org.openrdf.model.vocabulary.RDF;
46 import org.openrdf.model.vocabulary.RDFS;
47 import org.openrdf.query.QueryEvaluationException;
48 import org.openrdf.repository.RepositoryException;
49 import org.openrdf.repository.contextaware.ContextAwareConnection;
50
51
52
53
54
55
56
57 public class DynaClassInfoFactory {
58
59 private ConcurrentMap<Collection<URI>, DynaClassInfo> dynaClasses = new ConcurrentHashMap<Collection<URI>, DynaClassInfo>();
60
61 public DynaClassInfo findDyanClass(SesameManager manager, Resource resource) {
62 try {
63 Collection<URI> rdfTypes = new ArrayList<URI>();
64 ContextAwareConnection conn = manager.getConnection();
65 CloseableIteration<? extends Statement, RepositoryException> iter;
66 iter = conn.getStatements(resource, RDF.TYPE, null);
67 try {
68 while (iter.hasNext()) {
69 Value object = iter.next().getObject();
70 if (object instanceof URI)
71 rdfTypes.add((URI) object);
72 }
73 } finally {
74 iter.close();
75 }
76 if (dynaClasses.containsKey(rdfTypes))
77 return dynaClasses.get(rdfTypes);
78 DynaClassInfo c = buildDynaClass(manager, rdfTypes);
79 DynaClassInfo o = dynaClasses.putIfAbsent(rdfTypes, c);
80 if (o != null) {
81 c = o;
82 }
83 return c;
84 } catch (RepositoryException e) {
85 throw new ElmoCompositionException(e);
86 } catch (QueryEvaluationException e) {
87 throw new ElmoCompositionException(e);
88 }
89 }
90
91 public synchronized DynaClassInfo buildDynaClass(SesameManager manager,
92 Collection<URI> rdfTypes) throws RepositoryException,
93 QueryEvaluationException {
94 if (dynaClasses.containsKey(rdfTypes))
95 return dynaClasses.get(rdfTypes);
96 ContextAwareConnection conn = manager.getConnection();
97 RdfsClassInterpreter interpreter = new RdfsClassInterpreter(conn);
98 List<URI> list = new ArrayList<URI>(rdfTypes.size() + 1);
99 list.addAll(rdfTypes);
100 if (!rdfTypes.contains(RDFS.RESOURCE))
101 list.add(RDFS.RESOURCE);
102 List<URI> filtered = filterOutSuperclasses(conn, list);
103 DynaClassInfo c = new DynaClassInfo(filtered);
104 interpreter.interpetRdfClass(list, c);
105 dynaClasses.put(rdfTypes, c);
106 return c;
107 }
108
109 private List<URI> filterOutSuperclasses(ContextAwareConnection conn,
110 List<URI> types) throws RepositoryException {
111 if (types.size() < 2)
112 return types;
113 ArrayList<URI> list = new ArrayList<URI>(types.size());
114 for (int i = 0, n = types.size(); i < n; i++) {
115 URI c = types.get(i);
116 boolean isSubClass = false;
117 for (int j = 0, m = types.size(); j < m; j++) {
118 if (i == j)
119 continue;
120 URI d = types.get(j);
121 if (c.equals(d)) {
122 isSubClass = true;
123 break;
124 }
125 boolean subclass = conn.hasStatement(d, RDFS.SUBCLASSOF, c,
126 true);
127 if (subclass) {
128 isSubClass = true;
129 break;
130 }
131 }
132 if (!isSubClass)
133 list.add(c);
134 }
135 return list;
136 }
137
138 }