View Javadoc

1   package org.openrdf.elmo.rolemapper;
2   
3   import java.lang.reflect.AnnotatedElement;
4   import java.lang.reflect.Method;
5   import java.util.Collection;
6   
7   import org.openrdf.elmo.RdfTypeFactory;
8   import org.openrdf.elmo.RoleMapper;
9   import org.openrdf.elmo.annotations.complementOf;
10  import org.openrdf.elmo.annotations.factory;
11  import org.openrdf.elmo.annotations.intersectionOf;
12  import org.openrdf.elmo.annotations.oneOf;
13  import org.openrdf.elmo.annotations.rdf;
14  
15  public class RoleMapperImpl<URI> implements RoleMapper<URI> {
16  	private RdfTypeFactory<URI> vf;
17  
18  	private ComplexMapper<URI> roleMapper;
19  
20  	public RoleMapperImpl(ComplexMapper<URI> roleMapper) {
21  		this.roleMapper = roleMapper;
22  	}
23  
24  	public void setRdfTypeFactory(RdfTypeFactory<URI> vf) {
25  		this.vf = vf;
26  		roleMapper.setRdfTypeFactory(vf);
27  	}
28  
29  	public Class<?>[] findBaseRoles() {
30  		return roleMapper.findBaseRoles();
31  	}
32  
33  	public Collection<Class<?>> findIndividualRoles(URI instance,
34  			Collection<Class<?>> classes) {
35  		return roleMapper.findIndividualRoles(instance, classes);
36  	}
37  
38  	public Class<?>[] findRoles(URI type) {
39  		return roleMapper.findRoles(type);
40  	}
41  
42  	public Collection<Class<?>> findRoles(Collection<URI> types,
43  			Collection<Class<?>> roles) {
44  		return roleMapper.findRoles(types, roles);
45  	}
46  
47  	public Collection<URI> findSubTypes(Class<?> role, Collection<URI> rdfTypes) {
48  		return roleMapper.findSubTypes(role, rdfTypes);
49  	}
50  
51  	public URI findType(Class<?> concept) {
52  		return roleMapper.findType(concept);
53  	}
54  
55  	public Collection<URI> findTypes(Class<?> role, Collection<URI> rdfTypes) {
56  		return roleMapper.findTypes(role, rdfTypes);
57  	}
58  
59  	public boolean isIndividualRolesPresent(URI instance) {
60  		return roleMapper.isIndividualRolesPresent(instance);
61  	}
62  
63  	public boolean isTypeRecorded(URI type) {
64  		return roleMapper.isTypeRecorded(type);
65  	}
66  
67  	public void recordFactory(Class<?> javaClass) {
68  		assert javaClass.isAnnotationPresent(factory.class) : javaClass;
69  		boolean hasFactory = false;
70  		for (Method method : javaClass.getMethods()) {
71  			if (method.isAnnotationPresent(factory.class)) {
72  				Class<?> rtype = method.getReturnType();
73  				if (!rtype.isAnnotationPresent(factory.class)) {
74  					recordRole(rtype, javaClass, null);
75  					hasFactory = true;
76  				}
77  			}
78  		}
79  		if (!hasFactory)
80  			throw new IllegalArgumentException("Class has now factory methods");
81  		recordRole(javaClass, javaClass, null);
82  	}
83  
84  	public void recordFactory(Class<?> javaClass, String type) {
85  		assert javaClass.isAnnotationPresent(factory.class) : javaClass;
86  		boolean hasFactory = false;
87  		URI uri = vf.createRdfType(type);
88  		for (Method method : javaClass.getMethods()) {
89  			if (method.isAnnotationPresent(factory.class)) {
90  				Class<?> rtype = method.getReturnType();
91  				if (!rtype.isAnnotationPresent(factory.class)) {
92  					recordRole(rtype, javaClass, uri);
93  					hasFactory = true;
94  				}
95  			}
96  		}
97  		if (!hasFactory)
98  			throw new IllegalArgumentException("Class has now factory methods");
99  		recordRole(javaClass, javaClass, uri);
100 	}
101 
102 	public void recordRole(Class<?> role) {
103 		if (role.isAnnotationPresent(factory.class)) {
104 			recordFactory(role);
105 		} else {
106 			recordRole(role, role, null);
107 		}
108 	}
109 
110 	public void recordRole(Class<?> role, String type) {
111 		if (role.isAnnotationPresent(factory.class)) {
112 			recordFactory(role, type);
113 		} else {
114 			recordRole(role, role, vf.createRdfType(type));
115 		}
116 	}
117 
118 	private void recordRole(Class<?> role, AnnotatedElement elm, URI rdfType) {
119 		recordExplicitRoles(role, elm, rdfType);
120 		recordAliases(role, elm);
121 	}
122 
123 	private void recordExplicitRoles(Class<?> role, AnnotatedElement elm, URI rdfType) {
124 		boolean defaultType = elm.isAnnotationPresent(rdf.class);
125 		boolean complement = elm.isAnnotationPresent(complementOf.class);
126 		boolean intersec = elm.isAnnotationPresent(intersectionOf.class);
127 		boolean one = elm.isAnnotationPresent(oneOf.class);
128 		boolean annotated = defaultType;
129 		annotated = annotated || complement || intersec || one;
130 		URI defType = findDefaultType(role, elm);
131 		boolean useBaseType = !annotated;
132 		if (defType != null) {
133 			roleMapper.recordRole(role, defType);
134 			useBaseType = false;
135 		}
136 		if (rdfType != null) {
137 			roleMapper.recordRole(role, rdfType);
138 			useBaseType = false;
139 		}
140 		if (useBaseType) {
141 			roleMapper.recordBaseRole(role);
142 		}
143 		roleMapper.recordRole(role, elm);
144 	}
145 
146 	private URI findDefaultType(Class<?> role, AnnotatedElement elm) {
147 		if (elm.isAnnotationPresent(rdf.class)) {
148 			String[] values = elm.getAnnotation(rdf.class).value();
149 			if (values.length > 0) {
150 				return vf.createRdfType(values[0]);
151 			}
152 		}
153 		return null;
154 	}
155 
156 	private void recordAliases(Class<?> role, AnnotatedElement elm) {
157 		if (elm.isAnnotationPresent(rdf.class)) {
158 			String[] uris = elm.getAnnotation(rdf.class).value();
159 			for (int i = 1; i < uris.length; i++) {
160 				URI eqType = vf.createRdfType(uris[i]);
161 				recordExplicitRoles(role, elm, eqType);
162 			}
163 		}
164 	}
165 }