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.util.Collection;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.Map;
36 import java.util.Set;
37
38 import org.openrdf.elmo.RdfTypeFactory;
39
40
41
42
43
44
45
46 public class HierarchicalRoleMapper<URI> {
47
48 private DirectMapper<URI> directMapper;
49
50 private TypeMapper<URI> typeMapper;
51
52 private SimpleRoleMapper<URI> simpleRoleMapper;
53
54 private Map<Class<?>, Set<Class<?>>> subclasses;
55
56 public HierarchicalRoleMapper(DirectMapper<URI> directMapper,
57 TypeMapper<URI> typeMapper, SimpleRoleMapper<URI> simpleRoleMapper) {
58 this.directMapper = directMapper;
59 this.typeMapper = typeMapper;
60 this.simpleRoleMapper = simpleRoleMapper;
61 subclasses = new HashMap<Class<?>, Set<Class<?>>>(256);
62 }
63
64 public void setRdfTypeFactory(RdfTypeFactory<URI> vf) {
65 simpleRoleMapper.setRdfTypeFactory(vf);
66 }
67
68 public Class<?>[] findBaseRoles() {
69 return simpleRoleMapper.findBaseRoles();
70 }
71
72 public Class<?>[] findRoles(URI type) {
73 return simpleRoleMapper.findRoles(type);
74 }
75
76 public Collection<Class<?>> findRoles(Collection<URI> types,
77 Collection<Class<?>> classes) {
78 return simpleRoleMapper.findRoles(types, classes);
79 }
80
81 public boolean isTypeRecorded(URI type) {
82 return simpleRoleMapper.isTypeRecorded(type);
83 }
84
85 public Collection<URI> findTypes(Class<?> javaClass,
86 Collection<URI> rdfTypes) {
87 return typeMapper.findTypes(javaClass, rdfTypes);
88 }
89
90
91
92
93
94
95
96 public URI findType(Class<?> role) {
97 return typeMapper.findType(role);
98 }
99
100 public Collection<URI> findSubTypes(Class<?> role, Collection<URI> rdfTypes) {
101 findTypes(role, rdfTypes);
102 Set<Class<?>> subset = subclasses.get(role);
103 if (subset == null)
104 return rdfTypes;
105 for (Class<?> c : subset) {
106 findSubTypes(c, rdfTypes);
107 }
108 return rdfTypes;
109 }
110
111 public synchronized void recordRole(Class<?> role, URI type) {
112 assert type != null;
113 directMapper.recordRole(role, type);
114 recordClassHierarchy(role);
115 typeMapper.recordRole(role, type);
116
117 Set<Class<?>> superRoles = getSuperRoles(role);
118 Set<Class<?>> newRoles = new HashSet<Class<?>>(superRoles.size() + 1);
119 newRoles.addAll(superRoles);
120 newRoles.add(role);
121 newRoles = simpleRoleMapper.recordRoles(newRoles, type);
122 for (Class<?> r : directMapper.getDirectRoles(type)) {
123 addRolesInSubclasses(r, newRoles);
124 }
125 }
126
127 public void recordBaseRole(Class<?> role) {
128 URI type = simpleRoleMapper.getBaseType();
129 directMapper.recordRole(role, type);
130 recordClassHierarchy(role);
131 typeMapper.recordRole(role, type);
132 simpleRoleMapper.recordBaseRole(role);
133 }
134
135
136
137
138
139
140
141 private void recordClassHierarchy(Class<?> role) {
142 for (Class<?> sup : role.getInterfaces()) {
143 Set<Class<?>> set = subclasses.get(sup);
144 if (set == null)
145 subclasses.put(sup, set = new HashSet<Class<?>>());
146 if (!set.contains(role)) {
147 set.add(role);
148 recordClassHierarchy(sup);
149 }
150 }
151 }
152
153 private Set<Class<?>> getSuperRoles(Class<?> role) {
154 Class[] interfaces = role.getInterfaces();
155 if (interfaces.length == 0)
156 return Collections.EMPTY_SET;
157 Set<Class<?>> superRoles = new HashSet<Class<?>>();
158 for (Class<?> sup : interfaces) {
159 Set<Class<?>> sr = getSuperRoles(sup);
160 addRelatedRoles(sr, sup, superRoles);
161 }
162 return superRoles;
163 }
164
165 private void addRolesInSubclasses(Class<?> role, Set<Class<?>> newRoles) {
166 Set<Class<?>> subset = subclasses.get(role);
167 if (subset == null)
168 return;
169 for (Class<?> sub : subset) {
170 Set<Class<?>> subRoles = new HashSet<Class<?>>();
171 subRoles = addRelatedRoles(newRoles, sub, subRoles);
172 addRolesInSubclasses(sub, subRoles);
173 }
174 }
175
176 private Set<Class<?>> addRelatedRoles(Set<Class<?>> existing,
177 Class<?> role, Set<Class<?>> roles) {
178 roles.addAll(existing);
179 Set<URI> set = directMapper.getDirectTypes(role);
180 if (set != null) {
181 for (URI uri : set) {
182 simpleRoleMapper.recordRoles(existing, uri);
183 for (Class<?> c : simpleRoleMapper.findRoles(uri)) {
184 roles.add(c);
185 }
186 }
187 }
188 return roles;
189 }
190 }