View Javadoc

1   /*
2    * Copyright (c) 2007, Peter Mika 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.scutter;
30  
31  /** Utility methods for Elmo
32   * @author Peter Mika (pmika@cs.vu.nl)
33   */
34  
35  import info.aduna.collections.iterators.Iterators;
36  
37  import java.io.IOException;
38  import java.io.InputStream;
39  import java.net.MalformedURLException;
40  import java.net.URL;
41  import java.util.List;
42  
43  import javax.servlet.ServletConfig;
44  import javax.servlet.ServletContext;
45  import javax.servlet.ServletException;
46  import javax.servlet.http.HttpServletRequest;
47  
48  import org.apache.commons.httpclient.HttpClient;
49  import org.apache.commons.httpclient.HttpException;
50  import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
51  import org.apache.commons.httpclient.methods.GetMethod;
52  import org.apache.commons.httpclient.methods.HeadMethod;
53  import org.openrdf.OpenRDFException;
54  import org.openrdf.elmo.ElmoManager;
55  import org.openrdf.elmo.ElmoManagerFactory;
56  import org.openrdf.elmo.ElmoModule;
57  import org.openrdf.elmo.RoleMapper;
58  import org.openrdf.elmo.sesame.SesameManagerFactory;
59  import org.openrdf.model.URI;
60  import org.openrdf.repository.Repository;
61  import org.openrdf.repository.RepositoryConnection;
62  import org.openrdf.repository.RepositoryException;
63  import org.openrdf.repository.http.HTTPRepository;
64  import org.slf4j.Logger;
65  import org.slf4j.LoggerFactory;
66  
67  public class Util {
68  
69  	//servlet parameter names used for init and config parameters
70  	public final static String SERVLET_SERVER_PARAMETER = "server";
71  
72  	public final static String SERVLET_REPOSITORY_PARAMETER = "repository";
73  
74  	public final static String SERVLET_USERNAME_PARAMETER = "username";
75  
76  	public final static String SERVLET_PASSWORD_PARAMETER = "password";
77  	
78  	public final static String CONTEXT_SERVER_PARAMETER = SERVLET_SERVER_PARAMETER;
79  
80  	public final static String CONTEXT_REPOSITORY_PARAMETER = SERVLET_REPOSITORY_PARAMETER;
81  		
82  	public final static String CONTEXT_USERNAME_PARAMETER = SERVLET_USERNAME_PARAMETER;
83  
84  	public final static String CONTEXT_PASSWORD_PARAMETER = SERVLET_PASSWORD_PARAMETER;
85  
86  	//request attribute names
87  	public final static String REQUEST_REPOSITORY_ATTRIBUTE = "sesame";
88  
89  	protected static Logger _logger = LoggerFactory.getLogger(Util.class);
90  
91  	private static HttpClient _httpClient;
92  
93  	static {
94  
95  		MultiThreadedHttpConnectionManager mthc = new MultiThreadedHttpConnectionManager();
96  		mthc.getParams().setDefaultMaxConnectionsPerHost(50);
97  		mthc.getParams().setMaxTotalConnections(150);
98  		_httpClient = new HttpClient(mthc);
99  	}
100 
101 	/** Retrieve a document from the given URL using HTTP GET 
102 	 * 
103 	 * @param url
104 	 * @return Document as stream
105 	 * @throws HttpException
106 	 * @throws IOException
107 	 * @see org.apache.commons.httpclient.methods.GetMethod
108 	 */
109 	public static InputStream getDocumentAsInputStream(String url)
110 			throws HttpException, IOException {
111 		//Execute a GET method on the URL
112 		GetMethod get = new GetMethod(url);
113 		get.setFollowRedirects(true);
114 		get.addRequestHeader("User-Agent",
115 				"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 4.0)");
116 		_httpClient.executeMethod(get);
117 		return get.getResponseBodyAsStream();
118 	}
119 
120 	/** Retrieve a document from the given URL using HTTP GET. The method  
121 	 * getDocumentAsInputStream is preferred over this one, because reading a document
122 	 * requires to buffer a document of unknown size.
123 	 * 
124 	 * @param url
125 	 * @return Document as String
126 	 * @throws HttpException
127 	 * @throws IOException
128 	 * @see #getDocumentAsInputStream
129 	 * 
130 	 */
131 	public static String getDocumentAsString(String url) throws HttpException,
132 			IOException {
133 		String result = "";
134 		//Execute a GET method on the URL
135 		GetMethod get = new GetMethod(url);
136 		get.setFollowRedirects(true);
137 		get.addRequestHeader("User-Agent",
138 				"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 4.0)");
139 		try {
140 			_httpClient.executeMethod(get);
141 			result = get.getResponseBodyAsString();
142 		} finally {
143 			get.releaseConnection();
144 		}
145 		return result;
146 	}
147 	
148 	/** Determine the value for the Content-Length header using a HEAD call
149 	 * 
150 	 * @param url
151 	 * @return
152 	 * @throws HttpException
153 	 */
154 	public static int getContentLength(String url) throws HttpException, IOException {
155 		int result = 0;
156 		//Execute a GET method on the URL
157 		HeadMethod head = new HeadMethod(url);
158 		head.setFollowRedirects(true);
159 		head.addRequestHeader("User-Agent",
160 				"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 4.0)");
161 		try {
162 			_httpClient.executeMethod(head);
163 	        // Retrieve just the Content-Length header value.
164 	        String length =
165 	            head.getResponseHeader("Content-Length").getValue();
166 	        result = Integer.parseInt(length);
167 		} catch (NumberFormatException nfe) {
168 			//header not found
169 		} finally {
170 			head.releaseConnection();
171 		}
172 		return result;
173 	}
174 	
175 	
176 	private static Repository getLocalRepository(String name) throws RepositoryException {
177 		/*
178 		RepositoryManager manager = RepositoryManager.getDefaultInstance();
179 		
180 		Repository repository = manager.getRepository(name);
181 		repository.initialize();
182 		
183 		return repository;
184 		*/
185 		throw new RuntimeException("Not implemented");
186 	}
187 	
188 	private static Repository getRemoteRepository(String sesameServer, String repositoryID) throws RepositoryException {
189 		Repository repository = new HTTPRepository(sesameServer, repositoryID);
190 		repository.initialize();
191 		
192 		return repository;
193 	}
194 	
195 	public static ElmoManager initManager(Repository repository) {
196 		ElmoManagerFactory factory = new SesameManagerFactory(new ElmoModule(), repository);
197 		ElmoManager manager = factory.createElmoManager();
198 
199 		return manager;
200 	}
201 	
202 	/** Initialize a remote Elmo repository using the location and name
203 	 * 
204 	 * @param repositoryLocation String containing a URL
205 	 * @param repositoryName Repository name
206 	 * @return Repository
207 	 * @throws Exception if parameter is missing, invalid or initilization failed
208 	 * @see org.openrdf.elmo.repository.ElmoRepository#getRepository(URL, String)
209 	 */
210 	public static Repository initRepository(String repositoryLocation,
211 			String repositoryName) throws Exception {
212 		return initRepository(repositoryLocation, repositoryName, null, null);
213 	}
214 
215 	
216 	/**
217 	 * Initialize a remote Elmo repository using (optional) username and password.
218 	 * Performs some sanity checks on the repository location and name.
219 	 *  
220 	 * @param repositoryLocation
221 	 *            URL of the server
222 	 * @param repositoryName
223 	 *            Repository name
224 	 * @param username
225 	 *            Optional username
226 	 * @param password
227 	 *            Optional password
228 	 * @return Repository
229 	 * @throws Exception
230 	 *             if parameter is missing, invalid or initilization failed
231 	 */
232 			
233 	public static Repository initRepository(String repositoryLocation,
234 			String repositoryName, String username, String password)
235 			throws Exception {
236 		Repository repository = null;
237 		
238 		//Check parameters
239 		if ((repositoryLocation == null || repositoryLocation.equals("")) &&
240 			repositoryName != null && !repositoryName.equals("")) {
241 			//try getting the repository from the Sesame server in the same JVM
242 		
243 			
244 			repository = getLocalRepository(repositoryName);
245 			
246 		} else {
247 			
248 			try {
249 				URL repositoryURL = new URL(repositoryLocation);
250 			} catch (MalformedURLException mue) {
251 				throw new Exception("Repository location contains a malformed URL");
252 			}
253 			if (repositoryName == null || repositoryName.equals("")) {
254 				throw new Exception("Repository name missing");
255 			}
256 	
257 			repository = getRemoteRepository(repositoryLocation, repositoryName);
258 			
259 		}
260 	
261 		return repository;
262 	}
263 	
264 	
265 
266 	/**
267 	 * Initialize an Elmo repository from servlet request. First try to find a
268 	 * SesameRepository as a request attribute , if fails try to initialize one
269 	 * using request parameter. The attribute and init parameter names to
270 	 * specified are defined as constants in this class.
271 	 * 
272 	 * @param request
273 	 *            Request with parameters
274 	 * @return Repository
275 	 * @throws ServletException
276 	 *             if parameters are missing or repository failed to initialize
277 	 * @see #REQUEST_REPOSITORY_ATTRIBUTE
278 	 * @see #SERVLET_SERVER_PARAMETER
279 	 * @see #SERVLET_REPOSITORY_PARAMETER
280 	 * @see #SERVLET_USERNAME_PARAMETER
281 	 * @see #SERVLET_USERNAME_PARAMETER
282 	 */
283 	public static Repository initRepository(HttpServletRequest request)
284 			throws ServletException {
285 		String repositoryLocation = null;
286 		String repositoryName = null;
287 		String userName = null;
288 		String password = null;
289 		
290 		Repository repository = null;
291 		//Try first to find an object in the request
292 		if (request.getAttribute(REQUEST_REPOSITORY_ATTRIBUTE) != null) {
293 			repository = (Repository) request
294 					.getAttribute(REQUEST_REPOSITORY_ATTRIBUTE);
295 		} else {
296 			//SERVER and REPOSITORY
297 			repositoryLocation = request.getParameter(SERVLET_SERVER_PARAMETER);
298 			repositoryName = request.getParameter(SERVLET_REPOSITORY_PARAMETER);
299 
300 			if (request.getParameter(SERVLET_USERNAME_PARAMETER) != null
301 					&& request.getParameter(SERVLET_PASSWORD_PARAMETER) != null) {
302 				//USERNAME and PASSWORD
303 				userName = request.getParameter(SERVLET_USERNAME_PARAMETER);
304 				password = request.getParameter(SERVLET_PASSWORD_PARAMETER);
305 			}
306 
307 			try {
308 				repository = Util.initRepository(repositoryLocation,
309 						repositoryName, userName, password);
310 			} catch (Exception e) {
311 				throw new ServletException("Repository failed to initialize", e);
312 			}
313 		}
314 		return repository;
315 	}
316 	
317 	/**
318 	 * Initialize an Elmo repository from servlet initialization parameters and 
319 	 * if that fails from the context initialization parameters.
320 	 * 
321 	 * The init parameter names to specified are defined as constants in this
322 	 * class.
323 	 * 
324 	 * @param config
325 	 *            ServletConfig instance
326 	 * @return Repository
327 	 * @throws ServletException
328 	 *             if parameters are missing or repository failed to initialize
329 	 * @see #SERVLET_SERVER_PARAMETER
330 	 * @see #SERVLET_REPOSITORY_PARAMETER
331 	 * @see #SERVLET_USERNAME_PARAMETER
332 	 * @see #SERVLET_PASSWORD_PARAMETER
333 	 * @see #CONTEXT_SERVER_PARAMETER
334 	 * @see #CONTEXT_REPOSITORY_PARAMETER
335 	 * @see #CONTEXT_USERNAME_PARAMETER
336 	 * @see #CONTEXT_PASSWORD_PARAMETER
337 
338 	 */
339 	public static Repository initRepository(ServletConfig config)
340 			throws ServletException {
341 		String repositoryLocation = null;
342 		String repositoryName = null;
343 		String userName = null;
344 		String password = null;
345 		
346 		Repository repository = null;
347 			
348 		repositoryLocation = config.getInitParameter(SERVLET_SERVER_PARAMETER);
349 		repositoryName = config.getInitParameter(SERVLET_REPOSITORY_PARAMETER);
350 		
351 		if (config.getInitParameter(SERVLET_USERNAME_PARAMETER) != null
352 				&& config.getInitParameter(SERVLET_PASSWORD_PARAMETER) != null) {
353 			//USERNAME and PASSWORD
354 			userName = config.getInitParameter(SERVLET_USERNAME_PARAMETER);
355 			password = config.getInitParameter(SERVLET_PASSWORD_PARAMETER);
356 		}
357 
358 		try {
359 			repository = Util.initRepository(repositoryLocation, repositoryName,
360 					userName, password);
361 			return repository;
362 		} catch (Exception e) {
363 			//ignore
364 		}
365 		
366 		//try context parameters
367 		ServletContext context = config.getServletContext();
368 		repositoryLocation = context.getInitParameter(CONTEXT_SERVER_PARAMETER);
369 		repositoryName = context.getInitParameter(CONTEXT_REPOSITORY_PARAMETER);
370 		
371 		if (context.getInitParameter(CONTEXT_USERNAME_PARAMETER) != null
372 				&& context.getInitParameter(CONTEXT_PASSWORD_PARAMETER) != null) {
373 			//USERNAME and PASSWORD
374 			userName = context.getInitParameter(CONTEXT_USERNAME_PARAMETER);
375 			password = context.getInitParameter(CONTEXT_PASSWORD_PARAMETER);
376 		} else {
377 			userName = null;
378 			password = null;
379 		}
380 
381 		try {
382 			repository = Util.initRepository(repositoryLocation, repositoryName,
383 					userName, password);
384 		} catch (Exception e) {
385 			throw new ServletException("Repository failed to initialize", e);
386 		}
387 		
388 		return repository;
389 	}
390 		
391 	
392 
393 	/**
394 	 * Initialize an Elmo repository from either servlet request parameters or
395 	 * servlet initialization parameters. First try to find a ElmoRepository
396 	 * object in the request. If not present, try to initialize one based on
397 	 * request parameters. If this also fails, try to use servlet init
398 	 * parameters and lastly the context initialization paratemers. 
399 	 * The attribute, request and init parameter names to specified
400 	 * are defined as constants in this class.
401 	 * 
402 	 * @param servlet
403 	 *            Servlet instance
404 	 * @param request
405 	 *            Request with parameters
406 	 * @return Repository
407 	 * @throws ServletException
408 	 *             if parameters are missing or repository failed to initialize
409 	 * @see #REQUEST_REPOSITORY_ATTRIBUTE
410 	 * @see #SERVLET_SERVER_PARAMETER
411 	 * @see #SERVLET_REPOSITORY_PARAMETER
412 	 * @see #SERVLET_USERNAME_PARAMETER
413 	 * @see #SERVLET_USERNAME_PARAMETER
414 	 * @see #CONTEXT_SERVER_PARAMETER
415 	 * @see #CONTEXT_REPOSITORY_PARAMETER
416 	 * @see #CONTEXT_USERNAME_PARAMETER
417 	 * @see #CONTEXT_USERNAME_PARAMETER
418 	 */
419 	public static Repository initRepository(ServletConfig config,
420 			HttpServletRequest request) throws ServletException {
421 		Repository repository = null;
422 		//first try to initialize a repository from the request parameters
423 		try {
424 			repository = initRepository(request);
425 
426 		} catch (ServletException se) {
427 			//ignore
428 		}
429 		//if fails, try the initialization parameters
430 		if (repository == null) {
431 			repository = initRepository(config);
432 		}
433 		return repository;
434 	}
435 
436 	public static void copyRepositoryContent(Repository source, Repository target)
437 			throws OpenRDFException, IOException {
438 		// TODO: is this efficient?
439 		RepositoryConnection sourceCon = null;
440 		RepositoryConnection targetCon = null;
441 	
442 		try {
443 			sourceCon = source.getConnection();
444 			targetCon = target.getConnection();
445 			targetCon.add(sourceCon.getStatements(null, null, null, true));
446 		} 
447 		finally {
448 			if (sourceCon != null)
449 				sourceCon.close();
450 			if (targetCon != null)
451 				targetCon.close();
452 	
453 		}
454 	}
455 
456 	/**
457 	 * Find the ontological type (rdfs:Class) for a Java Class
458 	 * 
459 	 * @param c
460 	 * @return URI of the class
461 	 */
462 	public static URI getType(Class c) {
463 		// TODO: simplify?
464 		SesameManagerFactory factory = new SesameManagerFactory(
465 				new ElmoModule());
466 		try {
467 			RoleMapper<URI> mapper = factory.getRoleMapper();
468 			return mapper.findType(c);
469 		} finally {
470 			factory.close();
471 		}
472 	}
473 
474 	/** Get all instances of type T from a given repository
475 	 * 
476 	 * @param <T>
477 	 * @param rep
478 	 * @param cl
479 	 * @return
480 	 */
481 	public static <T extends org.openrdf.concepts.rdfs.Resource> List<T> getAllInstances(ElmoManager manager, Class<T> cl) {
482 		//SesameManagerFactory factory = new SesameManagerFactory(rep);
483 		//SesameManager manager = factory.createElmoManager();
484 		Iterable<T> query = manager.findAll(cl);
485 		return Iterators.asList(query.iterator());
486 	}
487 
488 
489 }