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.rolemapper;
30
31 import java.lang.reflect.AnnotatedElement;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.concurrent.ConcurrentHashMap;
38 import java.util.concurrent.CopyOnWriteArrayList;
39
40 import org.openrdf.elmo.RdfTypeFactory;
41 import org.openrdf.elmo.annotations.complementOf;
42 import org.openrdf.elmo.annotations.intersectionOf;
43 import org.openrdf.elmo.annotations.oneOf;
44
45
46
47
48
49
50
51 public class ComplexMapper<URI> {
52 private HierarchicalRoleMapper<URI> roleMapper;
53
54 private RdfTypeFactory<URI> vf;
55
56 private Map<Class<?>, AnnotatedElement> complements;
57
58 private Map<Class<?>, AnnotatedElement> intersections;
59
60 private Map<URI, List<Class<?>>> instances;
61
62 public ComplexMapper(HierarchicalRoleMapper<URI> roleMapper) {
63 this.roleMapper = roleMapper;
64 complements = new ConcurrentHashMap<Class<?>, AnnotatedElement>();
65 intersections = new ConcurrentHashMap<Class<?>, AnnotatedElement>();
66 instances = new ConcurrentHashMap<URI, List<Class<?>>>(256);
67 }
68
69 public void setRdfTypeFactory(RdfTypeFactory<URI> vf) {
70 this.vf = vf;
71 roleMapper.setRdfTypeFactory(vf);
72 }
73
74 public Collection<URI> findSubTypes(Class<?> role, Collection<URI> rdfTypes) {
75 return roleMapper.findSubTypes(role, rdfTypes);
76 }
77
78 public URI findType(Class<?> role) {
79 return roleMapper.findType(role);
80 }
81
82 public Collection<URI> findTypes(Class<?> javaClass, Collection<URI> rdfTypes) {
83 return roleMapper.findTypes(javaClass, rdfTypes);
84 }
85
86 public boolean isTypeRecorded(URI type) {
87 return roleMapper.isTypeRecorded(type);
88 }
89
90 public boolean isIndividualRolesPresent(URI instance) {
91 return !instances.isEmpty() && instances.containsKey(instance);
92 }
93
94 public Collection<Class<?>> findIndividualRoles(URI instance,
95 Collection<Class<?>> classes) {
96 List<Class<?>> list = instances.get(instance);
97 if (list != null) {
98 classes.addAll(list);
99 }
100 return classes;
101 }
102
103 public Class<?>[] findBaseRoles() {
104 return findRoles(null);
105 }
106
107 public Class<?>[] findRoles(URI type) {
108 Class<?>[] classes;
109 if (type == null) {
110 classes = roleMapper.findBaseRoles();
111 } else {
112 classes = roleMapper.findRoles(type);
113 }
114 if (complements.isEmpty())
115 return classes;
116 int size = classes.length + complements.size() + intersections.size();
117 List<Class<?>> result = new ArrayList<Class<?>>(size);
118 result.addAll(Arrays.asList(classes));
119 addIntersectionsAndComplements(result);
120 if (result.size() == classes.length)
121 return classes;
122 return result.toArray(new Class<?>[result.size()]);
123 }
124
125 public Collection<Class<?>> findRoles(Collection<URI> types,
126 Collection<Class<?>> classes) {
127 Collection<Class<?>> roles = roleMapper.findRoles(types, classes);
128 addIntersectionsAndComplements(roles);
129 return roles;
130 }
131
132 public void recordRole(Class<?> role, URI rdfType) {
133 roleMapper.recordRole(role, rdfType);
134 }
135
136 public void recordBaseRole(Class<?> role) {
137 roleMapper.recordBaseRole(role);
138 }
139
140 public synchronized void recordRole(Class<?> role, AnnotatedElement elm) {
141 if (elm.isAnnotationPresent(complementOf.class)) {
142 complements.put(role, elm);
143 }
144 if (elm.isAnnotationPresent(intersectionOf.class)) {
145 intersections.put(role, elm);
146 }
147 if (elm.isAnnotationPresent(oneOf.class)) {
148 oneOf ann = elm.getAnnotation(oneOf.class);
149 for (String instance : ann.value()) {
150 URI uri = vf.createRdfType(instance);
151 List<Class<?>> list = instances.get(uri);
152 if (list == null) {
153 list = new CopyOnWriteArrayList<Class<?>>();
154 instances.put(uri, list);
155 }
156 list.add(role);
157 }
158 }
159 }
160
161 private void addIntersectionsAndComplements(Collection<Class<?>> roles) {
162 for (Map.Entry<Class<?>, AnnotatedElement> e : intersections.entrySet()) {
163 Class<?> inter = e.getKey();
164 AnnotatedElement elm = e.getValue();
165 Class<?>[] of = elm.getAnnotation(intersectionOf.class).value();
166 if (!roles.contains(inter) && intersects(roles, of))
167 roles.add(inter);
168 }
169 boolean complementAdded = false;
170 for (Map.Entry<Class<?>, AnnotatedElement> e : complements.entrySet()) {
171 Class<?> comp = e.getKey();
172 AnnotatedElement elm = e.getValue();
173 Class<?> of = elm.getAnnotation(complementOf.class).value();
174 if (!roles.contains(comp) && !contains(roles, of)) {
175 complementAdded = true;
176 roles.add(comp);
177 }
178 }
179 if (complementAdded) {
180 for (Map.Entry e : intersections.entrySet()) {
181 Class<?> inter = (Class<?>) e.getKey();
182 AnnotatedElement elm = (AnnotatedElement) e.getValue();
183 Class<?>[] of = elm.getAnnotation(intersectionOf.class).value();
184 if (!roles.contains(inter) && intersects(roles, of))
185 roles.add(inter);
186 }
187 }
188 }
189
190 private boolean intersects(Collection<Class<?>> roles, Class<?>[] ofs) {
191 for (Class<?> of : ofs) {
192 if (!contains(roles, of))
193 return false;
194 }
195 return true;
196 }
197
198 private boolean contains(Collection<Class<?>> roles, Class<?> of) {
199 for (Class<?> type : roles) {
200 if (of.isAssignableFrom(type))
201 return true;
202 }
203 return false;
204 }
205 }