KickJava   Java API By Example, From Geeks To Geeks.

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


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.util;
57
58 import java.io.File JavaDoc;
59 import java.io.FileInputStream JavaDoc;
60 import java.io.IOException JavaDoc;
61 import java.io.InputStream JavaDoc;
62 import java.net.MalformedURLException JavaDoc;
63 import java.net.URL JavaDoc;
64 import java.util.ArrayList JavaDoc;
65 import java.util.Iterator JavaDoc;
66 import java.util.List JavaDoc;
67
68 import org.apache.commons.collections.Predicate;
69 import org.apache.log4j.Level;
70 import org.apache.log4j.Logger;
71 import org.apache.log4j.Priority;
72 import org.objectstyle.cayenne.conf.Configuration;
73
74 /**
75  * Utility class to find resources (files, etc.), using a preconfigured strategy.
76  *
77  * @author Andrei Adamchik
78  */

79 public class ResourceLocator {
80
81     private static Logger logObj;
82
83     // Create a Predicate that will enable logging only when
84
// Configuration.isLoggingConfigured() returns true.
85
// The passed predicate argument is ignored.
86
static {
87         Predicate p = new Predicate() {
88
89             public boolean evaluate(Object JavaDoc o) {
90                 return Configuration.isLoggingConfigured();
91             }
92         };
93
94         logObj = new PredicateLogger(ResourceLocator.class, p);
95     }
96
97     /** properties for enabling/disabling certain lookup strategies */
98     protected boolean skipAbsolutePath;
99     protected boolean skipClasspath;
100     protected boolean skipCurrentDirectory;
101     protected boolean skipHomeDirectory;
102
103     /** additional lookup paths (as Strings) */
104     protected List JavaDoc additionalClassPaths;
105     protected List JavaDoc additionalFilesystemPaths;
106
107     /** ClassLoader used for resource loading */
108     protected ClassLoader JavaDoc classLoader;
109
110     /**
111      * Returns a resource as InputStream if it is found in CLASSPATH or <code>null</code>
112      * otherwise. Lookup is normally performed in all JAR and ZIP files and directories
113      * available to the ClassLoader.
114      */

115     public static InputStream JavaDoc findResourceInClasspath(String JavaDoc name) {
116         try {
117             URL JavaDoc url = findURLInClasspath(name);
118             if (url != null) {
119                 logObj.debug("resource found in classpath: " + url);
120                 return url.openStream();
121             }
122             else {
123                 logObj.debug("resource not found in classpath: " + name);
124                 return null;
125             }
126         }
127         catch (IOException JavaDoc ioex) {
128             return null;
129         }
130     }
131
132     /**
133      * Returns a resource as InputStream if it is found in the filesystem or
134      * <code>null</code> otherwise. Lookup is first performed relative to the user's
135      * home directory (as defined by "user.home" system property), and then relative to
136      * the current directory.
137      */

138     public static InputStream JavaDoc findResourceInFileSystem(String JavaDoc name) {
139         try {
140             File JavaDoc file = findFileInFileSystem(name);
141             if (file != null) {
142                 logObj.debug("resource found in file system: " + file);
143                 return new FileInputStream JavaDoc(file);
144             }
145             else {
146                 logObj.debug("resource not found in file system: " + name);
147                 return null;
148             }
149         }
150         catch (IOException JavaDoc ioex) {
151             return null;
152         }
153     }
154
155     /**
156      * Looks up a file in the filesystem. First looks in the user home directory, then in
157      * the current directory.
158      *
159      * @return file object matching the name, or null if file can not be found or if it is
160      * not readable.
161      * @see #findFileInHomeDirectory(String)
162      * @see #findFileInCurrentDirectory(String)
163      */

164     public static File JavaDoc findFileInFileSystem(String JavaDoc name) {
165         File JavaDoc file = findFileInHomeDirectory(name);
166
167         if (file == null) {
168             file = findFileInCurrentDirectory(name);
169         }
170
171         if (file != null) {
172             logObj.debug("file found in file system: " + file);
173         }
174         else {
175             logObj.debug("file not found in file system: " + name);
176         }
177
178         return file;
179     }
180
181     /**
182      * Looks up a file in the user home directory.
183      *
184      * @return file object matching the name, or <code>null</code> if <code>file</code>
185      * cannot be found or is not readable.
186      */

187     public static File JavaDoc findFileInHomeDirectory(String JavaDoc name) {
188         // look in home directory
189
String JavaDoc homeDirPath = System.getProperty("user.home") + File.separator + name;
190
191         try {
192
193             File JavaDoc file = new File JavaDoc(homeDirPath);
194             if (file.exists() && file.canRead()) {
195                 logObj.debug("file found in home directory: " + file);
196             }
197             else {
198                 file = null;
199                 logObj.debug("file not found in home directory: " + name);
200             }
201
202             return file;
203         }
204         catch (SecurityException JavaDoc se) {
205             logObj.debug("permission denied reading file: " + homeDirPath, se);
206             return null;
207         }
208     }
209
210     /**
211      * Looks up a file in the current directory.
212      *
213      * @return file object matching the name, or <code>null</code> if <code>file</code>
214      * can not be found is not readable.
215      */

216     public static File JavaDoc findFileInCurrentDirectory(String JavaDoc name) {
217         // look in the current directory
218
String JavaDoc currentDirPath = System.getProperty("user.dir") + File.separator + name;
219
220         try {
221
222             File JavaDoc file = new File JavaDoc(currentDirPath);
223
224             if (file.exists() && file.canRead()) {
225                 logObj.debug("file found in current directory: " + file);
226             }
227             else {
228                 logObj.debug("file not found in current directory: " + name);
229                 file = null;
230             }
231
232             return file;
233         }
234         catch (SecurityException JavaDoc se) {
235             logObj.debug("permission denied reading file: " + currentDirPath, se);
236             return null;
237         }
238     }
239
240     /**
241      * Looks up the URL for the named resource using this class' ClassLoader.
242      */

243     public static URL JavaDoc findURLInClasspath(String JavaDoc name) {
244         ClassLoader JavaDoc classLoader = ResourceLocator.class.getClassLoader();
245         if (classLoader == null) {
246             classLoader = ClassLoader.getSystemClassLoader();
247         }
248         return findURLInClassLoader(name, classLoader);
249     }
250
251     /**
252      * Looks up the URL for the named resource using the specified ClassLoader.
253      */

254     public static URL JavaDoc findURLInClassLoader(String JavaDoc name, ClassLoader JavaDoc loader) {
255         URL JavaDoc url = loader.getResource(name);
256
257         if (url != null) {
258             logObj.debug("URL found with classloader: " + url);
259         }
260         else {
261             logObj.debug("URL not found with classloader: " + name);
262         }
263
264         return url;
265     }
266
267     /**
268      * Returns a base URL as a String from which this class was loaded. This is normally a
269      * JAR or a file URL, but it is ClassLoader dependent.
270      */

271     public static String JavaDoc classBaseUrl(Class JavaDoc aClass) {
272         String JavaDoc pathToClass = aClass.getName().replace('.', '/') + ".class";
273         ClassLoader JavaDoc classLoader = aClass.getClassLoader();
274
275         if (classLoader == null) {
276             classLoader = ClassLoader.getSystemClassLoader();
277         }
278
279         URL JavaDoc selfUrl = classLoader.getResource(pathToClass);
280
281         if (selfUrl == null) {
282             return null;
283         }
284
285         String JavaDoc urlString = selfUrl.toExternalForm();
286         return urlString.substring(0, urlString.length() - pathToClass.length());
287     }
288
289     /**
290      * Creates new ResourceLocator with default lookup policy including user home
291      * directory, current directory and CLASSPATH.
292      */

293     public ResourceLocator() {
294         super();
295         this.setClassLoader(this.getClass().getClassLoader());
296         this.additionalClassPaths = new ArrayList JavaDoc();
297         this.additionalFilesystemPaths = new ArrayList JavaDoc();
298     }
299
300     /**
301      * Returns an InputStream on the found resource using the lookup strategy configured
302      * for this ResourceLocator or <code>null</code> if no readable resource can be
303      * found for the given name.
304      */

305     public InputStream JavaDoc findResourceStream(String JavaDoc name) {
306         URL JavaDoc url = findResource(name);
307         if (url == null) {
308             return null;
309         }
310
311         try {
312             return url.openStream();
313         }
314         catch (IOException JavaDoc ioex) {
315             logObj.debug("Error reading URL, ignoring", ioex);
316             return null;
317         }
318     }
319
320     /**
321      * Returns a resource URL using the lookup strategy configured for this
322      * Resourcelocator or <code>null</code> if no readable resource can be found for the
323      * given name.
324      */

325     public URL JavaDoc findResource(String JavaDoc name) {
326         if (!willSkipAbsolutePath()) {
327             File JavaDoc f = new File JavaDoc(name);
328             if (f.isAbsolute() && f.exists()) {
329                 logObj.debug("File found at absolute path: " + name);
330                 try {
331                     return f.toURL();
332                 }
333                 catch (MalformedURLException JavaDoc ex) {
334                     // ignoring
335
logObj.debug("Malformed url, ignoring.", ex);
336                 }
337             }
338             else {
339                 logObj.debug("No file at absolute path: " + name);
340             }
341         }
342
343         if (!willSkipHomeDirectory()) {
344             File JavaDoc f = findFileInHomeDirectory(name);
345             if (f != null) {
346
347                 try {
348                     return f.toURL();
349                 }
350                 catch (MalformedURLException JavaDoc ex) {
351                     // ignoring
352
logObj.debug("Malformed url, ignoring", ex);
353                 }
354             }
355         }
356
357         if (!willSkipCurrentDirectory()) {
358             File JavaDoc f = findFileInCurrentDirectory(name);
359             if (f != null) {
360
361                 try {
362                     return f.toURL();
363                 }
364                 catch (MalformedURLException JavaDoc ex) {
365                     // ignoring
366
logObj.debug("Malformed url, ignoring", ex);
367                 }
368             }
369         }
370
371         if (!additionalFilesystemPaths.isEmpty()) {
372             logObj.debug("searching additional paths: " + this.additionalFilesystemPaths);
373             Iterator JavaDoc pi = this.additionalFilesystemPaths.iterator();
374             while (pi.hasNext()) {
375                 File JavaDoc f = new File JavaDoc((String JavaDoc) pi.next(), name);
376                 logObj.debug("searching for: " + f.getAbsolutePath());
377                 if (f.exists()) {
378                     try {
379                         return f.toURL();
380                     }
381                     catch (MalformedURLException JavaDoc ex) {
382                         // ignoring
383
logObj.debug("Malformed URL, ignoring.", ex);
384                     }
385                 }
386             }
387         }
388
389         if (!willSkipClasspath()) {
390
391             // start with custom classpaths and then move to the default one
392
if (!this.additionalClassPaths.isEmpty()) {
393                 logObj.debug("searching additional classpaths: "
394                         + this.additionalClassPaths);
395                 Iterator JavaDoc cpi = this.additionalClassPaths.iterator();
396                 while (cpi.hasNext()) {
397                     String JavaDoc fullName = cpi.next() + "/" + name;
398                     logObj.debug("searching for: " + fullName);
399                     URL JavaDoc url = findURLInClassLoader(fullName, classLoader);
400                     if (url != null) {
401                         return url;
402                     }
403                 }
404             }
405
406             URL JavaDoc url = findURLInClassLoader(name, classLoader);
407             if (url != null) {
408                 return url;
409             }
410         }
411
412         return null;
413     }
414
415     /**
416      * Returns a directory resource URL using the lookup strategy configured for this
417      * ResourceLocator or <code>null</code> if no readable resource can be found for the
418      * given name. The returned resource is assumed to be a directory, so the returned URL
419      * will be in a directory format (with "/" at the end).
420      */

421     public URL JavaDoc findDirectoryResource(String JavaDoc name) {
422         URL JavaDoc url = findResource(name);
423         if (url == null) {
424             return null;
425         }
426
427         try {
428             String JavaDoc urlSt = url.toExternalForm();
429             return (urlSt.endsWith("/")) ? url : new URL JavaDoc(urlSt + "/");
430         }
431         catch (MalformedURLException JavaDoc ex) {
432             // ignoring...
433
logObj.debug("Malformed URL, ignoring.", ex);
434             return null;
435         }
436     }
437
438     /**
439      * Returns true if no lookups are performed in the user home directory.
440      */

441     public boolean willSkipHomeDirectory() {
442         return skipHomeDirectory;
443     }
444
445     /**
446      * Sets "skipHomeDirectory" property.
447      */

448     public void setSkipHomeDirectory(boolean skipHomeDir) {
449         this.skipHomeDirectory = skipHomeDir;
450     }
451
452     /**
453      * Returns true if no lookups are performed in the current directory.
454      */

455     public boolean willSkipCurrentDirectory() {
456         return skipCurrentDirectory;
457     }
458
459     /**
460      * Sets "skipCurrentDirectory" property.
461      */

462     public void setSkipCurrentDirectory(boolean skipCurDir) {
463         this.skipCurrentDirectory = skipCurDir;
464     }
465
466     /**
467      * Returns true if no lookups are performed in the classpath.
468      */

469     public boolean willSkipClasspath() {
470         return skipClasspath;
471     }
472
473     /**
474      * Sets "skipClasspath" property.
475      */

476     public void setSkipClasspath(boolean skipClasspath) {
477         this.skipClasspath = skipClasspath;
478     }
479
480     /**
481      * Returns the ClassLoader associated with this ResourceLocator.
482      */

483     public ClassLoader JavaDoc getClassLoader() {
484         return classLoader;
485     }
486
487     /**
488      * Sets ClassLoader used to locate resources. If <code>null</code> is passed, the
489      * ClassLoader of the ResourceLocator class will be used.
490      */

491     public void setClassLoader(ClassLoader JavaDoc classLoader) {
492         if (classLoader == null) {
493             classLoader = this.getClass().getClassLoader();
494             if (classLoader == null) {
495                 classLoader = ClassLoader.getSystemClassLoader();
496             }
497         }
498
499         this.classLoader = classLoader;
500     }
501
502     /**
503      * Returns true if no lookups are performed using path as absolute path.
504      */

505     public boolean willSkipAbsolutePath() {
506         return skipAbsolutePath;
507     }
508
509     /**
510      * Sets "skipAbsolutePath" property.
511      */

512     public void setSkipAbsolutePath(boolean skipAbsPath) {
513         this.skipAbsolutePath = skipAbsPath;
514     }
515
516     /**
517      * Adds a custom path for class path lookups. Format should be "my/package/name"
518      * <i>without </i> leading "/".
519      */

520     public void addClassPath(String JavaDoc customPath) {
521         this.additionalClassPaths.add(customPath);
522     }
523
524     /**
525      * Adds the given String as a custom path for filesystem lookups. The path can be
526      * relative or absolute and is <i>not </i> checked for existence.
527      *
528      * @throws IllegalArgumentException if <code>path</code> is <code>null</code>.
529      */

530     public void addFilesystemPath(String JavaDoc path) {
531         if (path != null) {
532             this.additionalFilesystemPaths.add(path);
533         }
534         else {
535             throw new IllegalArgumentException JavaDoc("Path must not be null.");
536         }
537     }
538
539     /**
540      * Adds the given directory as a path for filesystem lookups. The directory is checked
541      * for existence.
542      *
543      * @throws IllegalArgumentException if <code>path</code> is <code>null</code>,
544      * not a directory or not readable.
545      */

546     public void addFilesystemPath(File JavaDoc path) {
547         if (path != null && path.isDirectory()) {
548             this.addFilesystemPath(path.getPath());
549         }
550         else {
551             throw new IllegalArgumentException JavaDoc("Path '" + path + "' is not a directory.");
552         }
553     }
554
555     /**
556      * Custom logger that can be dynamically turned on/off by evaluating a Predicate.
557      */

558     protected static class PredicateLogger extends Logger {
559
560         private Logger _target;
561         private Predicate _predicate;
562
563         private PredicateLogger(String JavaDoc name) {
564             super(name);
565         }
566
567         public PredicateLogger(Class JavaDoc clazz, Predicate condition) {
568             this(clazz.getName(), condition);
569         }
570
571         public PredicateLogger(String JavaDoc name, Predicate condition) {
572             this(name);
573             _target = Logger.getLogger(name);
574             _predicate = condition;
575         }
576
577         public void debug(Object JavaDoc arg0, Throwable JavaDoc arg1) {
578             this.log(Level.DEBUG, arg0, arg1);
579         }
580
581         public void debug(Object JavaDoc arg0) {
582             this.log(Level.DEBUG, arg0);
583         }
584
585         public void info(Object JavaDoc arg0, Throwable JavaDoc arg1) {
586             this.log(Level.INFO, arg0, arg1);
587         }
588
589         public void info(Object JavaDoc arg0) {
590             this.log(Level.INFO, arg0);
591         }
592
593         public void warn(Object JavaDoc arg0, Throwable JavaDoc arg1) {
594             this.log(Level.WARN, arg0, arg1);
595         }
596
597         public void warn(Object JavaDoc arg0) {
598             this.log(Level.WARN, arg0);
599         }
600
601         public void error(Object JavaDoc arg0, Throwable JavaDoc arg1) {
602             this.log(Level.ERROR, arg0, arg1);
603         }
604
605         public void error(Object JavaDoc arg0) {
606             this.log(Level.ERROR, arg0);
607         }
608
609         public void fatal(Object JavaDoc arg0, Throwable JavaDoc arg1) {
610             this.log(Level.FATAL, arg0, arg1);
611         }
612
613         public void fatal(Object JavaDoc arg0) {
614             this.log(Level.FATAL, arg0);
615         }
616
617         public void log(Priority arg0, Object JavaDoc arg1, Throwable JavaDoc arg2) {
618             if (_predicate.evaluate(arg1)) {
619                 _target.log(arg0, arg1);
620             }
621         }
622
623         public void log(Priority arg0, Object JavaDoc arg1) {
624             if (_predicate.evaluate(arg1)) {
625                 _target.log(arg0, arg1);
626             }
627         }
628
629     }
630
631 }
Popular Tags