View Javadoc

1   package com.zmicer.utils;
2   
3   import com.zmicer.utils.junit.ZmicerTestUtils;
4   import org.apache.log4j.Logger;
5   
6   import java.io.File;
7   import java.net.URL;
8   import java.util.List;
9   import java.util.Locale;
10  import java.util.MissingResourceException;
11  import java.util.ResourceBundle;
12  
13  /**
14   * The class is necessary for operating with resources (resource bundles, xml files etc.) - everything what could be called -
15   * it is a resource of my application.
16   *
17   * $Author:: zmicer             $<br/>
18   * $Rev:: 57                    $<br/> * $Date:: 2007-08-23 09:16:37 #$<br/>
19   */
20  public class ResourceUtils                              
21  {
22      /**
23       * Logger instance.
24       */
25      final public static Logger LOG = Logger.getLogger(ZmicerUtilsConstants.LoggingCategory.OBTAIN_RESOURCES.toString());
26  
27      /**
28       * Get ResourceBundle for the given base name. All the possible class loaders may help in the retrieving ResourceBundle,
29       * are used here.
30       * todo [zmicer]: seems to be this method could be adjusted to become more comprehensive.
31       *
32       * @param resourceName the base name of resource (e.g. when the file with bundle properties is called "JPatterns.properties",
33       *                 the base name would be "JPatterns"). Can not be null (otherwise <code>IllegalArgumentException</code> would
34       *                 appear). Be noticed the full name of the resource is allowed to be used here - in this case we would obtain it too.
35       *
36       * @return the ResourceBundle if exists or null.
37       *
38       * todo [zmicer]: please define all the features are implemented here. Update the unit tests.
39       * todo [zmicer]: code duplicate in the comparisson with the method above
40       */
41      public static ResourceBundle getResourceBundle(final String resourceName)
42      {
43          InputArgumentUtils.checkStrings(true, resourceName);
44  
45          LoggingUtils.debug(LOG, ResourceUtils.class, "Trying to obtain resource [" + resourceName + "] using classloaders.");
46          final Locale defaultLocale = Locale.getDefault();
47          final List<ClassLoader> loaders = ClassLoaderUtils.retrieveActualClassLoaders();
48          int counter = 0;
49          for (final ClassLoader loader : loaders)
50          {
51              try
52              {
53                  final ResourceBundle resourceBundle = ResourceBundle.getBundle(resourceName, defaultLocale, loader);
54                  // make this check in any case (e.g. behaviour of getBundle method could be changed)
55                  if (null != resourceBundle)
56                  {
57                      final ClassLoaderUtils.ClassLoaderTypes type = ClassLoaderUtils.ClassLoaderTypes.getTypeByOrdNumber(counter);
58                      LoggingUtils.debug(LOG, ResourceUtils.class, "The ResourceBundle with the name [" + resourceName +
59                          ((null != type) ? "] was obtained via the ClassLoader [" + type.toString() : "] (the name is a base name)"));
60                      return resourceBundle;
61                  }
62              }
63              catch (MissingResourceException ex)
64              {
65                  // oops, exception occured.
66              }
67              counter++;
68          }
69          LoggingUtils.debug(LOG, ResourceUtils.class, "Can not obtain resource [" + resourceName + "] using classloaders.");
70  
71          ResourceBundle result = FileUtils.getResourceBundleViaFile(resourceName);
72          if (null != result)
73          {
74              return result;
75          }
76  
77          // todo [zmicer]: fix this ASAP!
78          // B: trying to find this using the base path to the test data folder wich one is in the class path
79          final String testDataFolderName = ZmicerTestUtils.getFolderWithTestData();
80          if (null == testDataFolderName)
81          {
82              return null;
83          }
84          final String testDataFolderBaseName = FileUtils.getFolderBaseName(testDataFolderName);
85          if (!resourceName.contains(testDataFolderBaseName))
86          {
87              // the guarantee this reqursive method would be finished.
88              return getResourceBundle(testDataFolderBaseName + File.separator + resourceName.replace(".", File.separator));
89          }
90  
91          // C: trying to find this using the full path to the test data folder wich one is in the class path
92          if (!resourceName.contains(testDataFolderName))
93          {
94              // note [zmicer]: we need check if this is reqursive call - in this case we need to remove the test data folder base name which
95              // was added at the previous call (see section B)
96              final int index = resourceName.indexOf(testDataFolderBaseName);
97              String newResourceName = resourceName;
98              if (index == 0)
99              {
100                 newResourceName = resourceName.substring(testDataFolderBaseName.length() + 1);
101             }
102             // the guarantee this reqursive method would be finished.
103             return getResourceBundle(testDataFolderName + File.separator + newResourceName.replace(".", File.separator));
104         }
105 
106         // D: the case when for tests we need the default bundles to be found here:
107         // todo [zmicer]: think over how to avoid this test related functionality here?
108         // D.a: obtain the real, base name of the resource
109         String newResourceName = resourceName;
110         if (resourceName.indexOf(testDataFolderBaseName) == 0)
111         {
112             newResourceName = resourceName.substring(testDataFolderBaseName.length() + 1);
113         }
114         else if (resourceName.indexOf(testDataFolderName) == 0)
115         {
116             newResourceName = resourceName.substring(testDataFolderName.length() + 1);
117         }
118         result = FileUtils.getResourceBundleViaFile(
119             FileUtils.constructPath(ZmicerTestUtils.getFolderWithCommonTestData(), newResourceName));
120         if (null != result)
121         {
122             return result;
123         }
124 
125         LoggingUtils.debug(LOG, ResourceUtils.class, "Can not retrive the ResourceBundle with the base name [" + resourceName + "] using all the possible classloaders and " +
126             "FileInputStream - the name doesn't specify the correct ResourceName");
127         return null;
128     }
129 
130     /**
131      * Get resource as <code>URL</code> object.
132      *
133      * @param name the name of the resource to be found. Can not be null (otherwise <code>IllegalArgumentException</code>
134      *                 would appear).
135      *
136      * @return URL for the found resource or null
137      * todo [zmicer]: please define all the features are implemented here. Update the unit tests.
138      * todo [zmicer]: code duplicate in the comparisson with the method above
139      */
140     public static URL getResource(final String name)
141     {
142         InputArgumentUtils.checkStrings(true, name);
143         // A: trying the provided resource name without changes
144         LoggingUtils.debug(LOG, ResourceUtils.class, "Trying to obtain resource [" + name + "] using classloaders.");
145         final List<ClassLoader> loaders = ClassLoaderUtils.retrieveActualClassLoaders();
146         int counter = 0;
147         for (final ClassLoader loader : loaders)
148         {
149             try
150             {
151                 // note [zmicer]: get the resource but before this we need to replace File separator to the resource separator "/" -
152                 // it is done according to the Java Docs to the java.lang.ClassLoader.getResource() method
153                 final URL url = loader.getResource(name.replace(File.separator, "/"));
154                 // check in any case
155                 if (null != url)
156                 {
157                     final ClassLoaderUtils.ClassLoaderTypes type = ClassLoaderUtils.ClassLoaderTypes.getTypeByOrdNumber(counter);
158                     LoggingUtils.debug(LOG, ResourceUtils.class, "The resource with the name [" + name +
159                         ((null != url) ? "] was found via the ClassLoader [" + type.toString() : "]"));
160                     return url;
161                 }
162             }
163             catch (MissingResourceException ex)
164             {
165                 // oops, exception occured.
166             }
167             counter++;
168         }
169         LoggingUtils.debug(LOG, ResourceUtils.class, "Can not obtain resource [" + name + "] using classloaders.");
170 
171         // check the case it is the full path to the resource.
172         LoggingUtils.debug(LOG, ResourceUtils.class, "Trying to obtain resource [" + name + "] using File class facility");
173         final File resourceFile = new File(name);
174         if (resourceFile.isFile())
175         {
176             try
177             {
178                 LoggingUtils.debug(LOG, ResourceUtils.class, "The Resource with the name [" + name +
179                     "] was obtained via the File class");
180                 return resourceFile.toURL();
181             }
182             catch (Exception ex)
183             {
184                 // oops, exception occured.
185             }
186         }
187         LoggingUtils.debug(LOG, ResourceUtils.class, "Can not obtain resource [" + name + "] using File class facility.");
188 
189         // B: trying to find this using the full path to the test data folder wich one is in the class path
190         // todo [zmicer]: fix this!!
191         if (null == ZmicerTestUtils.getFolderWithTestData())
192         {
193             return null;
194         }
195         final String testDataFolderBaseName = FileUtils.getFolderBaseName(ZmicerTestUtils.getFolderWithTestData());
196         if (!name.contains(testDataFolderBaseName))
197         {
198             // the guarantee this reqursive method would be finished.
199             return getResource(testDataFolderBaseName + File.separator + name);
200         }
201 
202         // C: trying to find this using the full path to the test data folder wich one is in the class path
203         if (!name.contains(ZmicerTestUtils.getFolderWithTestData()))
204         {
205             // note [zmicer]: we need check if this is reqursive call - in this case we need to remove the test data folder base name which
206             // was added at the previous call (see section B)
207             final int index = name.indexOf(testDataFolderBaseName);
208             String newResourceName = name;
209             if (index == 0)
210             {
211                 newResourceName = name.substring(testDataFolderBaseName.length() + 1);
212             }
213 
214             // the guarantee this reqursive method would be finished.
215             return getResource(ZmicerTestUtils.getFolderWithTestData() + File.separator + newResourceName);
216         }
217 
218         LoggingUtils.debug(LOG, ResourceUtils.class, "Can not retrieve the resource with the name [" + name + "] using all the possible " +
219             "classloaders and File class facilities");
220         return null;
221     }
222 }