001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.core.io;
018:
019: import java.io.File;
020: import java.io.FileNotFoundException;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.net.URI;
024: import java.net.URISyntaxException;
025: import java.net.URL;
026:
027: import org.springframework.core.NestedIOException;
028: import org.springframework.util.ResourceUtils;
029:
030: /**
031: * Convenience base class for {@link Resource} implementations,
032: * pre-implementing typical behavior.
033: *
034: * <p>The "exists" method will check whether a File or InputStream can
035: * be opened; "isOpen" will always return false; "getURL" and "getFile"
036: * throw an exception; and "toString" will return the description.
037: *
038: * @author Juergen Hoeller
039: * @since 28.12.2003
040: */
041: public abstract class AbstractResource implements Resource {
042:
043: /**
044: * This implementation checks whether a File can be opened,
045: * falling back to whether an InputStream can be opened.
046: * This will cover both directories and content resources.
047: */
048: public boolean exists() {
049: // Try file existence: can we find the file in the file system?
050: try {
051: return getFile().exists();
052: } catch (IOException ex) {
053: // Fall back to stream existence: can we open the stream?
054: try {
055: InputStream is = getInputStream();
056: is.close();
057: return true;
058: } catch (Throwable isEx) {
059: return false;
060: }
061: }
062: }
063:
064: /**
065: * This implementation always returns <code>false</code>.
066: */
067: public boolean isOpen() {
068: return false;
069: }
070:
071: /**
072: * This implementation throws a FileNotFoundException, assuming
073: * that the resource cannot be resolved to a URL.
074: */
075: public URL getURL() throws IOException {
076: throw new FileNotFoundException(getDescription()
077: + " cannot be resolved to URL");
078: }
079:
080: /**
081: * This implementation builds a URI based on the URL returned
082: * by {@link #getURL()}.
083: */
084: public URI getURI() throws IOException {
085: URL url = getURL();
086: try {
087: return ResourceUtils.toURI(url);
088: } catch (URISyntaxException ex) {
089: throw new NestedIOException("Invalid URI [" + url + "]", ex);
090: }
091: }
092:
093: /**
094: * This implementation throws a FileNotFoundException, assuming
095: * that the resource cannot be resolved to an absolute file path.
096: */
097: public File getFile() throws IOException {
098: throw new FileNotFoundException(getDescription()
099: + " cannot be resolved to absolute file path");
100: }
101:
102: /**
103: * This implementation throws a FileNotFoundException, assuming
104: * that relative resources cannot be created for this resource.
105: */
106: public Resource createRelative(String relativePath)
107: throws IOException {
108: throw new FileNotFoundException(
109: "Cannot create a relative resource for "
110: + getDescription());
111: }
112:
113: /**
114: * This implementation always throws IllegalStateException,
115: * assuming that the resource does not carry a filename.
116: */
117: public String getFilename() throws IllegalStateException {
118: throw new IllegalStateException(getDescription()
119: + " does not carry a filename");
120: }
121:
122: /**
123: * This implementation returns the description of this resource.
124: * @see #getDescription()
125: */
126: public String toString() {
127: return getDescription();
128: }
129:
130: /**
131: * This implementation compares description strings.
132: * @see #getDescription()
133: */
134: public boolean equals(Object obj) {
135: return (obj == this || (obj instanceof Resource && ((Resource) obj)
136: .getDescription().equals(getDescription())));
137: }
138:
139: /**
140: * This implementation returns the description's hash code.
141: * @see #getDescription()
142: */
143: public int hashCode() {
144: return getDescription().hashCode();
145: }
146:
147: }
|