View Javadoc

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 }