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;
30  
31  import java.net.URL;
32  import java.util.ArrayList;
33  import java.util.Collections;
34  import java.util.HashMap;
35  import java.util.LinkedHashSet;
36  import java.util.List;
37  import java.util.Map;
38  import java.util.Set;
39  
40  import javax.xml.namespace.QName;
41  
42  /**
43   * Defines the Scope of an ElmoManager and its factory. This includes roles,
44   * literals, factories, datasets, and contexts.
45   * 
46   * @author James Leigh
47   * 
48   */
49  public class ElmoModule {
50  	public static class Association {
51  		private Class<?> javaClass;
52  
53  		private String rdfType;
54  
55  		public Association(Class<?> javaClass, String rdfType) {
56  			this.javaClass = javaClass;
57  			this.rdfType = rdfType;
58  		}
59  
60  		public Class<?> getJavaClass() {
61  			return javaClass;
62  		}
63  
64  		public String getRdfType() {
65  			return rdfType;
66  		}
67  	}
68  
69  	private ClassLoader cl;
70  
71  	private List<Association> literals = new ArrayList<Association>();
72  
73  	private List<Association> roles = new ArrayList<Association>();
74  
75  	private List<Association> factories = new ArrayList<Association>();
76  
77  	private QName context;
78  
79  	private List<QName> includedContexts = new ArrayList<QName>();
80  
81  	private Map<URL, String> datasets = new HashMap<URL, String>();
82  
83  	private List<String> resources = new ArrayList<String>();
84  
85  	public ElmoModule() {
86  		super();
87  		cl = Thread.currentThread().getContextClassLoader();
88  		if (cl == null) {
89  			cl = getClass().getClassLoader();
90  		}
91  	}
92  
93  	public ElmoModule(ClassLoader cl) {
94  		super();
95  		this.cl = cl;
96  	}
97  
98  	public ClassLoader getClassLoader() {
99  		return cl;
100 	}
101 
102 	public QName getContext() {
103 		return context;
104 	}
105 
106 	/**
107 	 * Sets the primary context of this module. This limits the readable scope
108 	 * to this and other included contexts and causes any add operations to be
109 	 * saved in this context.
110 	 * 
111 	 * @param context
112 	 * @return this
113 	 */
114 	public ElmoModule setContext(QName context) {
115 		this.context = context;
116 		return this;
117 	}
118 
119 	/**
120 	 * Include all the information from the given module in this module. 
121 	 * @param module to be included
122 	 * @return this
123 	 */
124 	public ElmoModule includeModule(ElmoModule module) {
125 		literals.addAll(module.literals);
126 		roles.addAll(module.roles);
127 		factories.addAll(module.factories);
128 		includedContexts.add(module.context);
129 		includedContexts.addAll(module.includedContexts);
130 		datasets.putAll(module.datasets);
131 		resources.addAll(module.resources);
132 		return this;
133 	}
134 
135 	public List<QName> getContexts() {
136 		return Collections.unmodifiableList(includedContexts);
137 	}
138 
139 	public List<Association> getLiterals() {
140 		return Collections.unmodifiableList(literals);
141 	}
142 
143 	/**
144 	 * Associates this literal type with the given datatype within this factory.
145 	 * 
146 	 * @param type
147 	 *            serializable class
148 	 * @param datatype
149 	 *            URI
150 	 */
151 	public ElmoModule addLiteral(Class<?> type, String datatype) {
152 		literals.add(new Association(type, datatype));
153 		return this;
154 	}
155 
156 	public List<Association> getRoles() {
157 		return Collections.unmodifiableList(roles);
158 	}
159 
160 	/**
161 	 * Associates this role with its default subject type.
162 	 * 
163 	 * @param role
164 	 *            concept or behaviour
165 	 */
166 	public ElmoModule addRole(Class<?> role) {
167 		roles.add(new Association(role, null));
168 		return this;
169 	}
170 
171 	/**
172 	 * Associates this role with the given subject type.
173 	 * 
174 	 * @param role
175 	 *            concept or behaviour
176 	 * @param type
177 	 *            URI
178 	 */
179 	public ElmoModule addRole(Class<?> role, String type) {
180 		roles.add(new Association(role, type));
181 		return this;
182 	}
183 
184 	public List<Association> getFactories() {
185 		return Collections.unmodifiableList(factories);
186 	}
187 
188 	/**
189 	 * Associates this factory with its default subject type.
190 	 * 
191 	 * @param role
192 	 *            concept or behaviour
193 	 */
194 	public ElmoModule addFactory(Class<?> role) {
195 		factories.add(new Association(role, null));
196 		return this;
197 	}
198 
199 	/**
200 	 * Associates this factory with the given subject type.
201 	 * 
202 	 * @param role
203 	 *            concept or behaviour
204 	 * @param type
205 	 *            URI
206 	 */
207 	public ElmoModule addFactory(Class<?> role, String type) {
208 		factories.add(new Association(role, type));
209 		return this;
210 	}
211 
212 	public Map<URL, String> getDatasets() {
213 		return datasets;
214 	}
215 
216 	/**
217 	 * Marks this dataset to be loaded into the repository under a context of the same URL.
218 	 * @param dataset
219 	 * @return this
220 	 */
221 	public ElmoModule addDataset(URL dataset) {
222 		return addDataset(dataset, dataset.toExternalForm());
223 	}
224 
225 	/**
226 	 * Marks this dataset to be loaded and replace any data in the given context.
227 	 * @param dataset
228 	 * @param context
229 	 * @return this
230 	 */
231 	public ElmoModule addDataset(URL dataset, String context) {
232 		datasets.put(dataset, context);
233 		return this;
234 	}
235 
236 	public List<String> getResources() {
237 		return resources;
238 	}
239 
240 	/**
241 	 * Load a dataset or a resource listing dataset - optionally assigned to a context
242 	 * @param path
243 	 * @return
244 	 */
245 	public ElmoModule addResources(String path) {
246 		resources.add(path);
247 		return this;
248 	}
249 
250 	@Override
251 	public int hashCode() {
252 		final int PRIME = 31;
253 		int result = 1;
254 		result = PRIME * result + factories.hashCode();
255 		result = PRIME * result + literals.hashCode();
256 		result = PRIME * result + roles.hashCode();
257 		result = PRIME * result + includedContexts.hashCode();
258 		result = PRIME * result + datasets.hashCode();
259 		result = PRIME * result + resources.hashCode();
260 		return result;
261 	}
262 
263 	@Override
264 	public boolean equals(Object obj) {
265 		if (this == obj)
266 			return true;
267 		if (obj == null)
268 			return false;
269 		if (getClass() != obj.getClass())
270 			return false;
271 		final ElmoModule other = (ElmoModule) obj;
272 		if (!factories.equals(other.factories))
273 			return false;
274 		if (!literals.equals(other.literals))
275 			return false;
276 		if (!roles.equals(other.roles))
277 			return false;
278 		if (!includedContexts.equals(other.includedContexts))
279 			return false;
280 		if (!datasets.equals(other.datasets))
281 			return false;
282 		if (!resources.equals(other.resources))
283 			return false;
284 		return true;
285 	}
286 
287 	@Override
288 	public String toString() {
289 		if (context != null)
290 			return context.toString();
291 		Set<Package> pkg = new LinkedHashSet<Package>();
292 		for (Association role : roles) {
293 			pkg.add(role.getJavaClass().getPackage());
294 		}
295 		return pkg.toString();
296 	}
297 }