1 /* 2 * Copyright 2012 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.ci.config.load; 17 18 import java.io.File; 19 import java.io.FileNotFoundException; 20 import java.io.InputStream; 21 import java.net.URL; 22 import java.net.URLClassLoader; 23 24 import org.xml.sax.InputSource; 25 26 /** 27 * Manages locations to look for configuration files to load. 28 */ 29 public final class LocationManager 30 { 31 // ********************************* Fields ********************************* 32 33 // --- constants ------------------------------------------------------------ 34 35 // --- members -------------------------------------------------------------- 36 37 /** 38 * The locations to search for configuration files. 39 */ 40 private DynamicUrlClassLoader locations; 41 42 // ****************************** Initializer ******************************* 43 44 // ****************************** Constructors ****************************** 45 46 /** 47 * Convenience constructor if no class loader should be used as a parent. 48 */ 49 public LocationManager() 50 { 51 this(null); 52 } 53 54 /** 55 * Default constructor. 56 * 57 * @param parentClassLoader the parent class loader to delegate requests to. 58 * May be <code>null</code>. 59 */ 60 public LocationManager(final ClassLoader parentClassLoader) 61 { 62 locations = new DynamicUrlClassLoader(new URL[0], parentClassLoader); 63 } 64 65 // ****************************** Inner Classes ***************************** 66 67 /** 68 * Implementation allows to add new locations dynamically. 69 */ 70 private static final class DynamicUrlClassLoader extends URLClassLoader 71 { 72 private DynamicUrlClassLoader(final URL[] urls, 73 final ClassLoader parentClassLoader) 74 { 75 super(urls, parentClassLoader); 76 } 77 78 private void addUrl(final URL url) 79 { 80 super.addURL(url); 81 } 82 } 83 84 // ********************************* Methods ******************************** 85 86 // --- init ----------------------------------------------------------------- 87 88 // --- get&set -------------------------------------------------------------- 89 90 // --- business ------------------------------------------------------------- 91 92 /** 93 * Adds a file location to the manager to search for configuration files. 94 * 95 * @param file the file location to be added. May reference a folder or a JAR 96 * file. 97 * @throws NullPointerException if {@link file} is <code>null</code>. 98 * @throws IllegalArgumentException if {@code file} does not provide a valid 99 * URL. 100 */ 101 public void addLocation(final File file) throws NullPointerException, 102 IllegalArgumentException 103 { 104 try 105 { 106 final URL url = file.toURI().toURL(); 107 addLocation(url); 108 } 109 catch (final Exception e) 110 { 111 throw new IllegalArgumentException( 112 file.getAbsolutePath() 113 + " is not a valid file. Cannot create a URL location.", e); 114 } 115 } 116 117 /** 118 * Adds an URL location to the manager to search for configuration files. 119 * 120 * @param url the URL location to be added. May reference a folder or a JAR 121 * file. 122 */ 123 public void addLocation(final URL url) 124 { 125 locations.addUrl(url); 126 } 127 128 /** 129 * Opens a stream to the given resource, if the resource can be found at any 130 * location managed by this instance. 131 * <p> 132 * The client is responsible to close the resource. 133 * </p> 134 * 135 * @param resource the resource to open. 136 * @return the stream to the resource as an input source. 137 * @throws FileNotFoundException if the resource cannot be opened. 138 */ 139 public InputSource open(final String resource) throws FileNotFoundException 140 { 141 final URL url = locations.getResource(resource); 142 if (url != null) 143 { 144 final InputStream in = locations.getResourceAsStream(resource); 145 final InputSource source = new InputSource(in); 146 source.setSystemId(url.toExternalForm()); 147 return source; 148 } 149 150 throw new FileNotFoundException("Cannot find resource '" + resource + "'."); 151 } 152 153 // --- object basics -------------------------------------------------------- 154 155 }