KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > util > ResourceLocator


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.util;
21
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.net.MalformedURLException JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34
35 /**
36  * Utility class to find resources (files, etc.), using a preconfigured strategy.
37  *
38  * @author Andrus Adamchik
39  */

40 public class ResourceLocator {
41
42     private static Log logObj = LogFactory.getLog(ResourceLocator.class);
43
44     // properties for enabling/disabling certain lookup strategies
45
protected boolean skipAbsolutePath;
46     protected boolean skipClasspath;
47     protected boolean skipCurrentDirectory;
48     protected boolean skipHomeDirectory;
49
50     // additional lookup paths (as Strings)
51
protected List JavaDoc additionalClassPaths;
52     protected List JavaDoc additionalFilesystemPaths;
53
54     // ClassLoader used for resource loading
55
protected ClassLoader JavaDoc classLoader;
56
57     /**
58      * Returns a resource as InputStream if it is found in CLASSPATH or <code>null</code>
59      * otherwise. Lookup is normally performed in all JAR and ZIP files and directories
60      * available to the ClassLoader.
61      */

62     public static InputStream JavaDoc findResourceInClasspath(String JavaDoc name) {
63         try {
64             URL JavaDoc url = findURLInClasspath(name);
65             if (url != null) {
66                 logObj.debug("resource found in classpath: " + url);
67                 return url.openStream();
68             }
69             else {
70                 logObj.debug("resource not found in classpath: " + name);
71                 return null;
72             }
73         }
74         catch (IOException JavaDoc ioex) {
75             return null;
76         }
77     }
78
79     /**
80      * Returns a resource as InputStream if it is found in the filesystem or
81      * <code>null</code> otherwise. Lookup is first performed relative to the user's
82      * home directory (as defined by "user.home" system property), and then relative to
83      * the current directory.
84      */

85     public static InputStream JavaDoc findResourceInFileSystem(String JavaDoc name) {
86         try {
87             File JavaDoc file = findFileInFileSystem(name);
88             if (file != null) {
89                 logObj.debug("resource found in file system: " + file);
90                 return new FileInputStream JavaDoc(file);
91             }
92             else {
93                 logObj.debug("resource not found in file system: " + name);
94                 return null;
95             }
96         }
97         catch (IOException JavaDoc ioex) {
98             return null;
99         }
100     }
101
102     /**
103      * Looks up a file in the filesystem. First looks in the user home directory, then in
104      * the current directory.
105      *
106      * @return file object matching the name, or null if file can not be found or if it is
107      * not readable.
108      * @see #findFileInHomeDirectory(String)
109      * @see #findFileInCurrentDirectory(String)
110      */

111     public static File JavaDoc findFileInFileSystem(String JavaDoc name) {
112         File JavaDoc file = findFileInHomeDirectory(name);
113
114         if (file == null) {
115             file = findFileInCurrentDirectory(name);
116         }
117
118         if (file != null) {
119             logObj.debug("file found in file system: " + file);
120         }
121         else {
122             logObj.debug("file not found in file system: " + name);
123         }
124
125         return file;
126     }
127
128     /**
129      * Looks up a file in the user home directory.
130      *
131      * @return file object matching the name, or <code>null</code> if <code>file</code>
132      * cannot be found or is not readable.
133      */

134     public static File JavaDoc findFileInHomeDirectory(String JavaDoc name) {
135         // look in home directory
136
String JavaDoc homeDirPath = System.getProperty("user.home") + File.separator + name;
137
138         try {
139
140             File JavaDoc file = new File JavaDoc(homeDirPath);
141             if (file.exists() && file.canRead()) {
142                 logObj.debug("file found in home directory: " + file);
143             }
144             else {
145                 file = null;
146                 logObj.debug("file not found in home directory: " + name);
147             }
148
149             return file;
150         }
151         catch (SecurityException JavaDoc se) {
152             logObj.debug("permission denied reading file: " + homeDirPath, se);
153             return null;
154         }
155     }
156
157     /**
158      * Looks up a file in the current directory.
159      *
160      * @return file object matching the name, or <code>null</code> if <code>file</code>
161      * can not be found is not readable.
162      */

163     public static File JavaDoc findFileInCurrentDirectory(String JavaDoc name) {
164         // look in the current directory
165
String JavaDoc currentDirPath = System.getProperty("user.dir") + File.separator + name;
166
167         try {
168
169             File JavaDoc file = new File JavaDoc(currentDirPath);
170
171             if (file.exists() && file.canRead()) {
172                 logObj.debug("file found in current directory: " + file);
173             }
174             else {
175                 logObj.debug("file not found in current directory: " + name);
176                 file = null;
177             }
178
179             return file;
180         }
181         catch (SecurityException JavaDoc se) {
182             logObj.debug("permission denied reading file: " + currentDirPath, se);
183             return null;
184         }
185     }
186
187     /**
188      * Looks up the URL for the named resource using this class' ClassLoader.
189      */

190     public static URL JavaDoc findURLInClasspath(String JavaDoc name) {
191         ClassLoader JavaDoc classLoader = ResourceLocator.class.getClassLoader();
192         if (classLoader == null) {
193             classLoader = ClassLoader.getSystemClassLoader();
194         }
195         return findURLInClassLoader(name, classLoader);
196     }
197
198     /**
199      * Looks up the URL for the named resource using the specified ClassLoader.
200      */

201     public static URL JavaDoc findURLInClassLoader(String JavaDoc name, ClassLoader JavaDoc loader) {
202         URL JavaDoc url = loader.getResource(name);
203
204         if (url != null) {
205             logObj.debug("URL found with classloader: " + url);
206         }
207         else {
208             logObj.debug("URL not found with classloader: " + name);
209         }
210
211         return url;
212     }
213
214     /**
215      * Returns a base URL as a String from which this class was loaded. This is normally a
216      * JAR or a file URL, but it is ClassLoader dependent.
217      */

218     public static String JavaDoc classBaseUrl(Class JavaDoc aClass) {
219         String JavaDoc pathToClass = aClass.getName().replace('.', '/') + ".class";
220         ClassLoader JavaDoc classLoader = aClass.getClassLoader();
221
222         if (classLoader == null) {
223             classLoader = ClassLoader.getSystemClassLoader();
224         }
225
226         URL JavaDoc selfUrl = classLoader.getResource(pathToClass);
227
228         if (selfUrl == null) {
229             return null;
230         }
231
232         String JavaDoc urlString = selfUrl.toExternalForm();
233         return urlString.substring(0, urlString.length() - pathToClass.length());
234     }
235
236     /**
237      * Creates new ResourceLocator with default lookup policy including user home
238      * directory, current directory and CLASSPATH.
239      */

240     public ResourceLocator() {
241         this.additionalClassPaths = new ArrayList JavaDoc();
242         this.additionalFilesystemPaths = new ArrayList JavaDoc();
243     }
244
245     /**
246      * Returns an InputStream on the found resource using the lookup strategy configured
247      * for this ResourceLocator or <code>null</code> if no readable resource can be
248      * found for the given name.
249      */

250     public InputStream JavaDoc findResourceStream(String JavaDoc name) {
251         URL JavaDoc url = findResource(name);
252         if (url == null) {
253             return null;
254         }
255
256         try {
257             return url.openStream();
258         }
259         catch (IOException JavaDoc ioex) {
260             logObj.debug("Error reading URL, ignoring", ioex);
261             return null;
262         }
263     }
264
265     /**
266      * Returns a resource URL using the lookup strategy configured for this
267      * Resourcelocator or <code>null</code> if no readable resource can be found for the
268      * given name.
269      */

270     public URL JavaDoc findResource(String JavaDoc name) {
271         if (!willSkipAbsolutePath()) {
272             File JavaDoc f = new File JavaDoc(name);
273             if (f.isAbsolute() && f.exists()) {
274                 logObj.debug("File found at absolute path: " + name);
275                 try {
276                     return f.toURL();
277                 }
278                 catch (MalformedURLException JavaDoc ex) {
279                     // ignoring
280
logObj.debug("Malformed url, ignoring.", ex);
281                 }
282             }
283             else {
284                 logObj.debug("No file at absolute path: " + name);
285             }
286         }
287
288         if (!willSkipHomeDirectory()) {
289             File JavaDoc f = findFileInHomeDirectory(name);
290             if (f != null) {
291
292                 try {
293                     return f.toURL();
294                 }
295                 catch (MalformedURLException JavaDoc ex) {
296                     // ignoring
297
logObj.debug("Malformed url, ignoring", ex);
298                 }
299             }
300         }
301
302         if (!willSkipCurrentDirectory()) {
303             File JavaDoc f = findFileInCurrentDirectory(name);
304             if (f != null) {
305
306                 try {
307                     return f.toURL();
308                 }
309                 catch (MalformedURLException JavaDoc ex) {
310                     // ignoring
311
logObj.debug("Malformed url, ignoring", ex);
312                 }
313             }
314         }
315
316         if (!additionalFilesystemPaths.isEmpty()) {
317             logObj.debug("searching additional paths: " + this.additionalFilesystemPaths);
318             Iterator JavaDoc pi = this.additionalFilesystemPaths.iterator();
319             while (pi.hasNext()) {
320                 File JavaDoc f = new File JavaDoc((String JavaDoc) pi.next(), name);
321                 logObj.debug("searching for: " + f.getAbsolutePath());
322                 if (f.exists()) {
323                     try {
324                         return f.toURL();
325                     }
326                     catch (MalformedURLException JavaDoc ex) {
327                         // ignoring
328
logObj.debug("Malformed URL, ignoring.", ex);
329                     }
330                 }
331             }
332         }
333
334         if (!willSkipClasspath()) {
335
336             // start with custom classpaths and then move to the default one
337
if (!this.additionalClassPaths.isEmpty()) {
338                 logObj.debug("searching additional classpaths: "
339                         + this.additionalClassPaths);
340                 Iterator JavaDoc cpi = this.additionalClassPaths.iterator();
341                 while (cpi.hasNext()) {
342                     String JavaDoc fullName = cpi.next() + "/" + name;
343                     logObj.debug("searching for: " + fullName);
344                     URL JavaDoc url = findURLInClassLoader(fullName, getClassLoader());
345                     if (url != null) {
346                         return url;
347                     }
348                 }
349             }
350
351             URL JavaDoc url = findURLInClassLoader(name, getClassLoader());
352             if (url != null) {
353                 return url;
354             }
355         }
356
357         return null;
358     }
359
360     /**
361      * Returns a directory resource URL using the lookup strategy configured for this
362      * ResourceLocator or <code>null</code> if no readable resource can be found for the
363      * given name. The returned resource is assumed to be a directory, so the returned URL
364      * will be in a directory format (with "/" at the end).
365      */

366     public URL JavaDoc findDirectoryResource(String JavaDoc name) {
367         URL JavaDoc url = findResource(name);
368         if (url == null) {
369             return null;
370         }
371
372         try {
373             String JavaDoc urlSt = url.toExternalForm();
374             return (urlSt.endsWith("/")) ? url : new URL JavaDoc(urlSt + "/");
375         }
376         catch (MalformedURLException JavaDoc ex) {
377             // ignoring...
378
logObj.debug("Malformed URL, ignoring.", ex);
379             return null;
380         }
381     }
382
383     /**
384      * Returns true if no lookups are performed in the user home directory.
385      */

386     public boolean willSkipHomeDirectory() {
387         return skipHomeDirectory;
388     }
389
390     /**
391      * Sets "skipHomeDirectory" property.
392      */

393     public void setSkipHomeDirectory(boolean skipHomeDir) {
394         this.skipHomeDirectory = skipHomeDir;
395     }
396
397     /**
398      * Returns true if no lookups are performed in the current directory.
399      */

400     public boolean willSkipCurrentDirectory() {
401         return skipCurrentDirectory;
402     }
403
404     /**
405      * Sets "skipCurrentDirectory" property.
406      */

407     public void setSkipCurrentDirectory(boolean skipCurDir) {
408         this.skipCurrentDirectory = skipCurDir;
409     }
410
411     /**
412      * Returns true if no lookups are performed in the classpath.
413      */

414     public boolean willSkipClasspath() {
415         return skipClasspath;
416     }
417
418     /**
419      * Sets "skipClasspath" property.
420      */

421     public void setSkipClasspath(boolean skipClasspath) {
422         this.skipClasspath = skipClasspath;
423     }
424
425     /**
426      * Returns the ClassLoader associated with this ResourceLocator.
427      */

428     public ClassLoader JavaDoc getClassLoader() {
429         ClassLoader JavaDoc loader = this.classLoader;
430
431         if (loader == null) {
432             loader = Thread.currentThread().getContextClassLoader();
433         }
434
435         if (loader == null) {
436             loader = getClass().getClassLoader();
437         }
438
439         if (loader == null) {
440             loader = ClassLoader.getSystemClassLoader();
441         }
442
443         return loader;
444     }
445
446     /**
447      * Sets ClassLoader used to locate resources. If <code>null</code> is passed, the
448      * ClassLoader of the ResourceLocator class will be used.
449      */

450     public void setClassLoader(ClassLoader JavaDoc classLoader) {
451         this.classLoader = classLoader;
452     }
453
454     /**
455      * Returns true if no lookups are performed using path as absolute path.
456      */

457     public boolean willSkipAbsolutePath() {
458         return skipAbsolutePath;
459     }
460
461     /**
462      * Sets "skipAbsolutePath" property.
463      */

464     public void setSkipAbsolutePath(boolean skipAbsPath) {
465         this.skipAbsolutePath = skipAbsPath;
466     }
467
468     /**
469      * Adds a custom path for class path lookups. Format should be "my/package/name"
470      * <i>without </i> leading "/".
471      */

472     public void addClassPath(String JavaDoc customPath) {
473         this.additionalClassPaths.add(customPath);
474     }
475
476     /**
477      * Adds the given String as a custom path for filesystem lookups. The path can be
478      * relative or absolute and is <i>not </i> checked for existence.
479      *
480      * @throws IllegalArgumentException if <code>path</code> is <code>null</code>.
481      */

482     public void addFilesystemPath(String JavaDoc path) {
483         if (path != null) {
484             this.additionalFilesystemPaths.add(path);
485         }
486         else {
487             throw new IllegalArgumentException JavaDoc("Path must not be null.");
488         }
489     }
490
491     /**
492      * Adds the given directory as a path for filesystem lookups. The directory is checked
493      * for existence.
494      *
495      * @throws IllegalArgumentException if <code>path</code> is <code>null</code>,
496      * not a directory or not readable.
497      */

498     public void addFilesystemPath(File JavaDoc path) {
499         if (path != null && path.isDirectory()) {
500             this.addFilesystemPath(path.getPath());
501         }
502         else {
503             throw new IllegalArgumentException JavaDoc("Path '" + path + "' is not a directory.");
504         }
505     }
506 }
507
Popular Tags