View Javadoc

1   /*
2    * Copyright (c) 2007, James Leigh All rights reserved.
3    * 
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted provided that the following conditions are met:
6    * 
7    * - Redistributions of source code must retain the above copyright notice, this
8    *   list of conditions and the following disclaimer.
9    * - Redistributions in binary form must reproduce the above copyright notice,
10   *   this list of conditions and the following disclaimer in the documentation
11   *   and/or other materials provided with the distribution. 
12   * - Neither the name of the openrdf.org nor the names of its contributors may
13   *   be used to endorse or promote products derived from this software without
14   *   specific prior written permission.
15   * 
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26   * POSSIBILITY OF SUCH DAMAGE.
27   * 
28   */
29  package org.openrdf.elmo.rolemapper;
30  
31  import java.util.Arrays;
32  import java.util.Collection;
33  import java.util.HashSet;
34  import java.util.Map;
35  import java.util.Set;
36  import java.util.concurrent.ConcurrentHashMap;
37  
38  import org.openrdf.elmo.RdfTypeFactory;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  
42  /**
43   * Tracks recorded roles and maps them to their subject type.
44   * 
45   * @author James Leigh
46   * 
47   */
48  public class SimpleRoleMapper<URI> {
49  
50  	/** http://www.w3.org/2000/01/rdf-schema" target="alexandria_uri">http://www.w3.org/2000/01/rdf-schema#Resource */
51  	private static final String BASE_TYPE = "http://www.w3.org/2000/01/rdf-schema#Resource";
52  
53  	private final Logger logger = LoggerFactory.getLogger(SimpleRoleMapper.class);
54  
55  	private URI baseType;
56  
57  	private Map<URI, Object> roles; // javancss cannot parse Map<URI, Class<?>[]>
58  
59  	public SimpleRoleMapper() {
60  		roles = new ConcurrentHashMap<URI, Object>(256);
61  	}
62  
63  	public void setRdfTypeFactory(RdfTypeFactory<URI> vf) {
64  		baseType = vf.createRdfType(BASE_TYPE);
65  		roles.put(baseType, new Class<?>[0]);
66  	}
67  
68  	public URI getBaseType() {
69  		return baseType;
70  	}
71  
72  	public Class<?>[] findBaseRoles() {
73  		return (Class<?>[]) roles.get(baseType);
74  	}
75  
76  	public Class<?>[] findRoles(URI type) {
77  		Class<?>[] classes = (Class<?>[]) roles.get(type);
78  		if (classes == null) {
79  			logger.warn("Unregistered type {}", type);
80  			return findBaseRoles();
81  		}
82  		return classes;
83  	}
84  
85  	public Collection<Class<?>> findRoles(Collection<URI> types,
86  			Collection<Class<?>> classes) {
87  		for (URI type : types) {
88  			Class<?>[] javaClass = (Class<?>[]) roles.get(type);
89  			if (javaClass == null) {
90  				logger.warn("Unregistered type {}", type);
91  			} else {
92  				classes.addAll(Arrays.asList(javaClass));
93  			}
94  		}
95  		if (classes.isEmpty() || types.isEmpty()) {
96  			classes.addAll(Arrays.asList(findBaseRoles()));
97  			return classes;
98  		}
99  		return classes;
100 	}
101 
102 	public boolean isTypeRecorded(URI type) {
103 		return roles.containsKey(type);
104 	}
105 
106 	public synchronized Set<Class<?>> recordRoles(Set<Class<?>> role, URI uri) {
107 		Class<?>[] set = (Class<?>[]) roles.get(uri);
108 		Set<Class<?>> changed = new HashSet<Class<?>>();
109 		if (set == null) {
110 			Class<?>[] bar = (Class<?>[]) roles.get(baseType);
111 			if (bar == null) {
112 				changed = role;
113 			} else {
114 				changed.addAll(Arrays.asList(bar));
115 				changed.addAll(role);
116 			}
117 		} else {
118 			changed.addAll(Arrays.asList(set));
119 			changed.addAll(role);
120 		}
121 		if (set == null || changed.size() != set.length)
122 			roles.put(uri, changed.toArray(new Class<?>[changed.size()]));
123 		return changed;
124 
125 	}
126 
127 	public synchronized void recordBaseRole(Class<?> role) {
128 		for (Map.Entry<URI, Object> e : roles.entrySet()) {
129 			Class<?>[] set = (Class<?>[]) e.getValue();
130 			boolean contains = false;
131 			for (Class<?> c : set) {
132 				if (role.equals(c)) {
133 					contains = true;
134 					break;
135 				}
136 			}
137 			if (contains)
138 				continue;
139 			Class<?>[] ar = set;
140 			set = new Class<?>[ar.length + 1];
141 			System.arraycopy(ar, 0, set, 0, ar.length);
142 			set[ar.length] = role;
143 			e.setValue(set);
144 		}
145 	}
146 }