001: /*
002: * Copyright 2002-2005 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.web.context.support;
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.URL;
024:
025: import javax.servlet.ServletContext;
026:
027: import org.springframework.core.io.AbstractResource;
028: import org.springframework.core.io.Resource;
029: import org.springframework.util.Assert;
030: import org.springframework.util.StringUtils;
031: import org.springframework.web.util.WebUtils;
032:
033: /**
034: * Resource implementation for ServletContext resources,
035: * interpreting relative paths within the web application root directory.
036: *
037: * <p>Always supports stream access and URL access, but only allows
038: * <code>java.io.File</code> access when the web application archive
039: * is expanded.
040: *
041: * @author Juergen Hoeller
042: * @since 28.12.2003
043: * @see javax.servlet.ServletContext#getResourceAsStream
044: * @see javax.servlet.ServletContext#getResource
045: * @see javax.servlet.ServletContext#getRealPath
046: */
047: public class ServletContextResource extends AbstractResource {
048:
049: private final ServletContext servletContext;
050:
051: private final String path;
052:
053: /**
054: * Create a new ServletContextResource.
055: * <p>The Servlet spec requires that resource paths start with a slash,
056: * even if many containers accept paths without leading slash too.
057: * Consequently, the given path will be prepended with a slash if it
058: * doesn't already start with one.
059: * @param servletContext the ServletContext to load from
060: * @param path the path of the resource
061: */
062: public ServletContextResource(ServletContext servletContext,
063: String path) {
064: // check ServletContext
065: Assert
066: .notNull(servletContext,
067: "Cannot resolve ServletContextResource without ServletContext");
068: this .servletContext = servletContext;
069:
070: // check path
071: Assert.notNull(path, "path is required");
072: if (!path.startsWith("/")) {
073: path = "/" + path;
074: }
075: this .path = StringUtils.cleanPath(path);
076: }
077:
078: /**
079: * Return the ServletContext for this resource.
080: */
081: public final ServletContext getServletContext() {
082: return servletContext;
083: }
084:
085: /**
086: * Return the path for this resource.
087: */
088: public final String getPath() {
089: return path;
090: }
091:
092: /**
093: * This implementation delegates to <code>ServletContext.getResourceAsStream</code>,
094: * but throws a FileNotFoundException if no resource found.
095: * @see javax.servlet.ServletContext#getResourceAsStream(String)
096: */
097: public InputStream getInputStream() throws IOException {
098: InputStream is = this .servletContext
099: .getResourceAsStream(this .path);
100: if (is == null) {
101: throw new FileNotFoundException("Could not open "
102: + getDescription());
103: }
104: return is;
105: }
106:
107: /**
108: * This implementation delegates to <code>ServletContext.getResource</code>,
109: * but throws a FileNotFoundException if no resource found.
110: * @see javax.servlet.ServletContext#getResource(String)
111: */
112: public URL getURL() throws IOException {
113: URL url = this .servletContext.getResource(this .path);
114: if (url == null) {
115: throw new FileNotFoundException(
116: getDescription()
117: + " cannot be resolved to URL because it does not exist");
118: }
119: return url;
120: }
121:
122: /**
123: * This implementation delegates to <code>ServletContext.getRealPath</code>,
124: * but throws a FileNotFoundException if not found or not resolvable.
125: * @see javax.servlet.ServletContext#getRealPath(String)
126: */
127: public File getFile() throws IOException {
128: String realPath = WebUtils.getRealPath(this .servletContext,
129: this .path);
130: return new File(realPath);
131: }
132:
133: /**
134: * This implementation creates a ServletContextResource, applying the given path
135: * relative to the path of the underlying file of this resource descriptor.
136: * @see org.springframework.util.StringUtils#applyRelativePath(String, String)
137: */
138: public Resource createRelative(String relativePath)
139: throws IOException {
140: String pathToUse = StringUtils.applyRelativePath(this .path,
141: relativePath);
142: return new ServletContextResource(this .servletContext,
143: pathToUse);
144: }
145:
146: /**
147: * This implementation returns the name of the file that this ServletContext
148: * resource refers to.
149: * @see org.springframework.util.StringUtils#getFilename(String)
150: */
151: public String getFilename() {
152: return StringUtils.getFilename(this .path);
153: }
154:
155: /**
156: * This implementation returns a description that includes the ServletContext
157: * resource location.
158: */
159: public String getDescription() {
160: return "ServletContext resource [" + this .path + "]";
161: }
162:
163: /**
164: * This implementation compares the underlying ServletContext resource locations.
165: */
166: public boolean equals(Object obj) {
167: if (obj == this ) {
168: return true;
169: }
170: if (obj instanceof ServletContextResource) {
171: ServletContextResource otherRes = (ServletContextResource) obj;
172: return (this .servletContext.equals(otherRes.servletContext) && this .path
173: .equals(otherRes.path));
174: }
175: return false;
176: }
177:
178: /**
179: * This implementation returns the hash code of the underlying
180: * ServletContext resource location.
181: */
182: public int hashCode() {
183: return this.path.hashCode();
184: }
185:
186: }
|