/** * $Id: ResourceFinder.java 105077 2012-02-24 22:54:29Z ottenhoff@longsight.com $ * $URL: https://source.sakaiproject.org/svn/entitybroker/trunk/utils/src/java/org/sakaiproject/entitybroker/util/spring/ResourceFinder.java $ * ResourceFinder.java - caching - May 29, 2008 11:59:02 AM - azeckoski ************************************************************************** * Copyright (c) 2008, 2009 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sakaiproject.entitybroker.util.spring; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; /** * Takes a path or list of paths to resources and turns them into different things (file/IS/resource), * this also allows us to look on a relative or absolute path and will automatically * check the typical places one might expect to put sakai config files<br/> * Checks the environmental and file paths first and then defaults to checking the classloaders<br/> * Allows us to find resources in our pack since the Sakai context classloader is wrong, * too bad it is not correct, that would be cool, but it is wrong and it is not cool<br/> * <br/> * Sample usage:<xmp> <property name="configLocation"> <bean class="org.sakaiproject.entitybroker.impl.util.ResourceFinder" factory-method="getResource"> <constructor-arg value="ehcache.xml" /> </bean> </property> * </xmp> * Just call whichever get* method you want to depending on the needed output<br/> * You can also get arrays of resources at once like so:<xmp> <property name="mappingLocations"> <bean class="org.sakaiproject.entitybroker.impl.util.ResourceFinder" factory-method="getResources"> <constructor-arg> <list> <value>org/sakaiproject/hierarchy/dao/hbm/HierarchyPersistentNode.hbm.xml</value> <value>org/sakaiproject/hierarchy/dao/hbm/HierarchyNodeMetaData.hbm.xml</value> </list> </constructor-arg> </bean> </property> * </xmp> * * * @author Aaron Zeckoski (aaron@caret.cam.ac.uk) */ public class ResourceFinder { public static String relativePath = "sakai/"; public static String environmentPathVariable = "sakai.home"; private static List<Resource> makeResources(List<String> paths) { List<Resource> rs = new ArrayList<Resource>(); if (paths != null && !paths.isEmpty()) { for (String path : paths) { try { Resource r = makeResource(path); rs.add(r); } catch (IllegalArgumentException e) { // do not add if not found, just skip System.out.println("WARN: " + e.getMessage() + ", continuing..."); } } } return rs; } private static Resource makeResource(String path) { if (path.startsWith("/")) { path = path.substring(1); } Resource r = null; // try the environment path first String envPath = getEnvironmentPath() + path; r = new FileSystemResource(envPath); if (! r.exists()) { // try the relative path next String relPath = getRelativePath() + path; r = new FileSystemResource(relPath); if (! r.exists()) { // now try the classloader ClassLoader cl = ResourceFinder.class.getClassLoader(); r = new ClassPathResource(path, cl); if (! r.exists()) { // finally try the system classloader cl = ClassLoader.getSystemClassLoader(); r = new ClassPathResource(path, cl); } } } if (! r.exists()) { throw new IllegalArgumentException("Could not find this resource ("+path+") in any of the checked locations"); } return r; } /** * Resolves a list of paths into resources relative to environmental defaults or relative paths or the classloader * @param paths a list of paths to resources (org/sakaiproject/mystuff/Thing.xml) * @return an array of Spring Resource objects */ public static Resource[] getResources(List<String> paths) { return makeResources(paths).toArray(new Resource[paths.size()]); } public static File[] getFiles(List<String> paths) { List<Resource> rs = makeResources(paths); File[] files = new File[rs.size()]; for (int i = 0; i < rs.size(); i++) { Resource r = rs.get(i); try { files[i] = r.getFile(); } catch (IOException e) { throw new RuntimeException("Failed to get file for: " + r.getFilename(), e); } } return files; } public static InputStream[] getInputStreams(List<String> paths) { List<Resource> rs = makeResources(paths); InputStream[] streams = new InputStream[rs.size()]; for (int i = 0; i < rs.size(); i++) { Resource r = rs.get(i); try { streams[i] = r.getInputStream(); } catch (IOException e) { throw new RuntimeException("Failed to get inputstream for: " + r.getFilename(), e); } } return streams; } /** * Resolve a path into a resource relative to environmental defaults or relative paths or the classloader * @param path a path to a resource (org/sakaiproject/mystuff/Thing.xml) * @return the Spring Resource object */ public static Resource getResource(String path) { return makeResource(path); } public static File getFile(String path) { Resource r = getResource(path); File f = null; try { f = r.getFile(); } catch (IOException e) { throw new RuntimeException("Failed to get file for: " + r.getFilename(), e); } return f; } public static InputStream getInputStream(String path) { Resource r = getResource(path); InputStream is = null; try { is = r.getInputStream(); } catch (IOException e) { throw new RuntimeException("Failed to get inputstream for: " + r.getFilename(), e); } return is; } protected static String getRelativePath() { File currentPath = new File(""); File f = new File(currentPath, relativePath); if (! f.exists() || ! f.isDirectory()) { f = new File(currentPath, "sakai"); if (! f.exists() || ! f.isDirectory()) { f = currentPath; } } String absPath = f.getAbsolutePath(); if (! absPath.endsWith(File.separatorChar + "")) { absPath += File.separatorChar; } return absPath; } protected static String getEnvironmentPath() { String envPath = System.getenv(environmentPathVariable); if (envPath == null) { envPath = System.getProperty(environmentPathVariable); if (envPath == null) { String container = getContainerHome(); if (container == null) { container = ""; } envPath = container + File.separatorChar + "sakai" + File.separatorChar; } } return envPath; } protected static String getContainerHome() { String catalina = System.getProperty("catalina.base"); if (catalina == null) { catalina = System.getProperty("catalina.home"); } return catalina; } }