1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 or later
5    * as published by the Free Software Foundation. This program is distributed
6    * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
7    * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *      http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * © CrossWire Bible Society, 2005 - 2016
18   *
19   */
20  package org.crosswire.common.util;
21  
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.net.URL;
25  import java.util.MissingResourceException;
26  
27  import org.crosswire.jsword.JSOtherMsg;
28  
29  /**
30   * Better implementations of the getResource methods with less ambiguity and
31   * that are less dependent on the specific class loader situation.
32   * 
33   * @see gnu.lgpl.License The GNU Lesser General Public License for details.
34   * @author Joe Walker
35   * @author DM Smith
36   */
37  public final class ResourceUtil {
38      /**
39       * Prevent Instantiation
40       */
41      private ResourceUtil() {
42      }
43  
44      /**
45       * Generic resource URL fetcher. One way or the other we'll find it! Either
46       * as a relative or an absolute reference.
47       * 
48       * @param search
49       *            The name of the resource (without a leading /) to find
50       * @return The requested resource
51       * @throws MissingResourceException
52       *             if the resource can not be found
53       */
54      public static URL getResource(String search) throws MissingResourceException {
55          return getResource(CallContext.getCallingClass(), search);
56      }
57  
58      /**
59       * Generic resource URL fetcher. One way or the other we'll find it! Either
60       * as a relative or an absolute reference.
61       * 
62       * @param <T> the type of the resource
63       * @param clazz the basis to search for the resource first.
64       * @param resourceName
65       *            The resource to find
66       * @return The requested resource
67       * @throws MissingResourceException
68       *             if the resource can not be found
69       */
70      public static <T> URL getResource(Class<T> clazz, String resourceName) throws MissingResourceException {
71          URL resource = CWClassLoader.instance(clazz).findResource(resourceName);
72  
73          if (resource == null) {
74              throw new MissingResourceException(JSOtherMsg.lookupText("Cannot find resource: {0}", resourceName), clazz.getName(), resourceName);
75          }
76  
77          return resource;
78      }
79  
80      /**
81       * Generic resource URL fetcher
82       * 
83       * @param search
84       *            The name of the resource (without a leading /) to find
85       * @return The requested resource
86       * @throws IOException
87       *             if there is a problem reading the file
88       * @throws MissingResourceException
89       *             if the resource can not be found
90       */
91      public static InputStream getResourceAsStream(String search) throws IOException, MissingResourceException {
92          return getResourceAsStream(CallContext.getCallingClass(), search);
93      }
94  
95      /**
96       * Generic resource URL fetcher
97       * 
98       * @param <T> the type of the resource
99       * @param clazz the basis to search for the resource first.
100      * @param search
101      *            The name of the resource (without a leading /) to find
102      * @return The requested resource
103      * @throws IOException
104      *             if there is a problem reading the file
105      * @throws MissingResourceException
106      *             if the resource can not be found
107      */
108     public static <T> InputStream getResourceAsStream(Class<T> clazz, String search) throws IOException, MissingResourceException {
109         return ResourceUtil.getResource(clazz, search).openStream();
110     }
111 
112     /**
113      * Get and load a properties file from the writable area or if that fails
114      * from the classpath (where a default ought to be stored)
115      * 
116      * @param subject
117      *            The name of the desired resource (without any extension)
118      * @return The found and loaded properties file
119      * @throws IOException
120      *             if the resource can not be loaded
121      */
122     public static PropertyMap getProperties(String subject) throws IOException {
123         return getProperties(CallContext.getCallingClass(), subject);
124     }
125 
126     /**
127      * Get and load a properties file from the writable area or if that fails
128      * from the classpath (where a default ought to be stored)
129      * 
130      * @param <T> the type of the resource
131      * @param clazz
132      *            The name of the desired resource
133      * @return The found and loaded properties file
134      * @throws IOException
135      *             if the resource can not be loaded
136      */
137     public static <T> PropertyMap getProperties(Class<T> clazz) throws IOException {
138         return getProperties(clazz, ClassUtil.getShortClassName(clazz));
139     }
140 
141     /**
142      * Get and load a properties file from the writable area or if that fails
143      * from the classpath (where a default ought to be stored)
144      * 
145      * @param <T> the type of the resource
146      * @param clazz
147      *            The name of the desired resource
148      * @param subject
149      *            The name of the desired resource (without any extension)
150      * @return The found and loaded properties file
151      * @throws IOException
152      *             if the resource can not be loaded
153      */
154     private static <T> PropertyMap getProperties(Class<T> clazz, String subject) throws IOException {
155         try {
156             String lookup = subject + FileUtil.EXTENSION_PROPERTIES;
157             InputStream in = getResourceAsStream(clazz, lookup);
158 
159             PropertyMap prop = new PropertyMap();
160             prop.load(in);
161             return prop;
162         } catch (MissingResourceException e) {
163             return new PropertyMap();
164         }
165     }
166 }
167