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