001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: ResourceFinderDirectories.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.resources;
009:
010: import com.uwyn.rife.resources.exceptions.CantOpenResourceStreamException;
011: import com.uwyn.rife.resources.exceptions.CantRetrieveResourceContentException;
012: import com.uwyn.rife.resources.exceptions.CouldntAccessResourceFileException;
013: import com.uwyn.rife.resources.exceptions.ResourceFinderErrorException;
014: import com.uwyn.rife.resources.exceptions.UnsupportedResourceProtocolException;
015: import com.uwyn.rife.tools.FileUtils;
016: import com.uwyn.rife.tools.InnerClassException;
017: import com.uwyn.rife.tools.InputStreamUser;
018: import com.uwyn.rife.tools.exceptions.FileUtilsErrorException;
019: import java.io.File;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.net.URL;
023: import java.net.URLConnection;
024: import java.net.URLDecoder;
025: import java.util.ArrayList;
026:
027: /**
028: * This class offers <code>ResourceFinder</code> capabilities for resources that
029: * are available through a collection of directories.
030: * <p>
031: * The resources are looked up in the same order as the order in which the
032: * directories were specified. This means that if a resource is found in the
033: * first directory but it is also present in the second, only the first one
034: * will match.
035: *
036: * @author Geert Bevin (gbevin[remove] at uwyn dot com)
037: * @version $Revision: 3634 $
038: * @see com.uwyn.rife.resources.ResourceFinder
039: * @since 1.0
040: */
041: public class ResourceFinderDirectories extends AbstractResourceFinder {
042: private ArrayList<File> mDirectories = null;
043:
044: /**
045: * Creates a new instance for the provided array of directories.
046: *
047: * @param directories the directories where the resources should be
048: * searched in.
049: *
050: * @since 1.0
051: */
052: public ResourceFinderDirectories(File[] directories) {
053: mDirectories = new ArrayList<File>();
054:
055: if (directories != null) {
056: for (File directory : directories) {
057: if (directory != null && directory.canRead()
058: && directory.isDirectory()) {
059: mDirectories.add(directory);
060: }
061: }
062: }
063: }
064:
065: public URL getResource(String name) {
066: File resource = null;
067: for (File directory : mDirectories) {
068: String local_name = name.replace('/', File.separatorChar);
069: resource = new File(directory.getAbsolutePath()
070: + File.separator + local_name);
071: if (resource.exists() && resource.canRead()
072: && resource.isFile()) {
073: try {
074: return resource.toURL();
075: } catch (IOException e) {
076: continue;
077: }
078: }
079: }
080:
081: return null;
082: }
083:
084: public <ResultType> ResultType useStream(URL resource,
085: InputStreamUser user) throws ResourceFinderErrorException,
086: InnerClassException {
087: if (null == resource || null == user) {
088: return null;
089: }
090:
091: InputStream stream = null;
092: try {
093: URLConnection connection = resource.openConnection();
094: connection.setUseCaches(false);
095: stream = connection.getInputStream();
096: return (ResultType) user.useInputStream(stream);
097: } catch (IOException e) {
098: throw new CantOpenResourceStreamException(resource, e);
099: } finally {
100: if (stream != null) {
101: try {
102: stream.close();
103: } catch (IOException e) {
104: // couldn't close stream since it probably already has been
105: // closed after an exception
106: // proceed without reporting an error message.
107: }
108: }
109: }
110: }
111:
112: public String getContent(URL resource, String encoding)
113: throws ResourceFinderErrorException {
114: if (null == resource) {
115: return null;
116: }
117:
118: try {
119: return FileUtils.readString(resource, encoding);
120: } catch (FileUtilsErrorException e) {
121: throw new CantRetrieveResourceContentException(resource,
122: encoding, e);
123: }
124: }
125:
126: public long getModificationTime(URL resource)
127: throws ResourceFinderErrorException {
128: if (null == resource) {
129: return -1;
130: }
131:
132: long modification_time = -1;
133:
134: String resource_protocol = resource.getProtocol();
135: String resource_filename = URLDecoder
136: .decode(resource.getFile());
137: if (resource_protocol.equals("file")) {
138: File resource_file = new File(resource_filename);
139: if (resource_file.exists() && resource_file.canRead()) {
140: modification_time = resource_file.lastModified();
141: } else {
142: throw new CouldntAccessResourceFileException(
143: resource_filename);
144: }
145: } else {
146: throw new UnsupportedResourceProtocolException(
147: resource_filename, resource_protocol);
148: }
149:
150: return modification_time;
151: }
152: }
|