001    package calhoun.util;
002    
003    import java.io.BufferedReader;
004    import java.io.File;
005    import java.io.FileInputStream;
006    import java.io.FileNotFoundException;
007    import java.io.IOException;
008    import java.io.InputStream;
009    import java.io.InputStreamReader;
010    import java.io.PrintWriter;
011    import java.io.StringWriter;
012    
013    import org.apache.commons.logging.Log;
014    import org.apache.commons.logging.LogFactory;
015    
016    /**
017     * The ResourceLoader loads for resources by trying each of the following mechanisms:
018     * <ul>
019     * <li>Treating the resourceID as a file name and opening it in the file system
020     * <li>Loading a class resource with the specified resourceID
021     * <li>Loading a system resource with the specified resourceID
022     * </ul>  
023     */
024    public class ResourceLoader {
025    
026            private static final Log log = LogFactory.getLog(ResourceLoader.class);
027    
028            private static ResourceFinder[] resourceFinders = { new FileSystem(), new ClassResource(), new SystemResource() }; 
029    
030            /**
031             * Opens an InputStream by trying each of the defined ResourceFinders.
032             */     
033            public static InputStream openInputStream(Class cls, String resourceID)
034            {       
035                    log.debug("Attempting to load resource "+ resourceID);
036                    resourceID = resourceID.replace('\\', '/');
037                    for ( int i = 0; i < resourceFinders.length; ++i ) {
038                            log.debug("\tTrying resource finder "+ resourceFinders[i]);
039                            InputStream is = resourceFinders[i].openResource(cls, resourceID);
040                            if ( is != null ) {
041                                    log.debug("\tResource found");
042                                    return is;                      
043                            }
044                    }
045                    throw new ConfigException("Resource '" + resourceID + "' not found for " + cls);
046            }
047    
048            public static String openTextResource(Class cls, String resourceId) {
049                    try {
050                            BufferedReader reader = new BufferedReader(new InputStreamReader(openInputStream(cls, resourceId)));
051                            StringWriter writer = new StringWriter();
052                            PrintWriter print = new PrintWriter(writer);
053                            String line;
054                            while ( ( line = reader.readLine() ) != null ) {
055                                    print.println(line);
056                            }
057                            print.flush();
058                            return writer.toString();
059                    }
060                    catch (IOException x) {
061                            throw new ErrorException(x);
062                    }
063            }
064    
065            public interface ResourceFinder
066            {
067                    /**
068                     * @return null if the resource cannot be found
069                     */
070                    public InputStream openResource(Class cls, String resourceID);
071            }
072            
073            static class FileSystem
074                    implements ResourceFinder
075            {
076                    public InputStream openResource(Class cls, String resourceID)
077                    {
078                            File file = new File(resourceID);
079                            if ( !file.exists() || !file.isFile() )
080                                    return null;
081                            try
082                            {
083                                    return new FileInputStream(file);
084                            }
085                            catch (FileNotFoundException x)
086                            {
087                                    log.warn("Unable to open existing file as resource", x);
088                                    return null;
089                            }
090                    }               
091            }
092            
093            static class ClassResource
094                    implements ResourceFinder
095            {
096                    public InputStream openResource(Class cls, String resourceID)
097                    {
098                            return cls.getResourceAsStream(resourceID);
099                    }               
100            }
101    
102            static class SystemResource
103                    implements ResourceFinder
104            {
105                    public InputStream openResource(Class cls, String resourceID)
106                    {
107                            return cls.getClassLoader().getResourceAsStream(resourceID);
108                    }               
109            }
110    }