1 /*
2 * Copyright 2002-2004 The Apache Software Foundation
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 * implied.
13 *
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.struts.flow.core.source.impl;
18
19 import java.io.IOException;
20 import java.net.MalformedURLException;
21 import java.util.Map;
22
23 import org.apache.commons.chain.web.servlet.ServletWebContext;
24 import javax.servlet.ServletContext;
25 import org.apache.commons.chain.web.portlet.PortletWebContext;
26 import javax.portlet.PortletContext;
27 import org.apache.commons.chain.Context;
28
29 import java.net.URL;
30
31 import org.apache.struts.flow.core.source.*;
32
33
34 /***
35 * Base interface for resolving a source by system identifiers.
36 * Instead of using the java.net.URL classes which prevent you
37 * from adding your own custom protocols in a server environment,
38 * you should use this resolver for all URLs.
39 *
40 * The resolver creates for each source a <code>Source</code>
41 * object, which could then be asked for an <code>InputStream</code>
42 * etc.
43 *
44 * When the <code>Source</code> object is no longer needed
45 * it must be released using the resolver. This is very similar like
46 * looking up components from a <code>ComponentLocator</code>.
47 * In fact a source object can implement most lifecycle interfaces
48 * like Composable, Initializable, Disposable etc.
49 *
50 * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
51 * @version CVS $Revision: 1.7 $ $Date: 2004/02/28 11:47:26 $
52 */
53
54 public class ChainSourceResolver extends AbstractSourceResolver implements SourceResolver {
55
56 private Context ctx;
57
58 public ChainSourceResolver(Context ctx) {
59 this.ctx = ctx;
60 }
61
62 /***
63 * Determines an absolute path to the path name. If the chain context is an
64 * instance of <code>ServletWebContext</code>, the path is first resolved
65 * against the <code>ServletContext</code>. If not, the path is also tested
66 * for being an absolute path already, and if not, tested to see if it is
67 * in the classpath. If either the path is in the <code>ServletContext</code>
68 * or in the classpath, a temp file is created and the path to it is
69 * returned.
70 *
71 *@param ctx The chain context
72 *@param pathname The script path
73 *@return The absolute path to the script file
74 *@exception IOException If anything goes wrong
75 */
76 public Source resolveURI( String location ) throws MalformedURLException, IOException {
77
78 return resolveURI(location, null, null);
79 }
80
81 /*
82 InputStream is = null;
83 File tmpdir = null;
84
85 if (ctx instanceof ServletWebContext) {
86 ServletContext context = ((ServletWebContext) ctx).getContext();
87
88 // Can we access the file in the servlet directory?
89 String path = context.getRealPath(pathname);
90 if (path != null) {
91 File file = new File(path);
92 if (file.exists()) {
93 return (file.toURI());
94 }
95 }
96
97 // Determine the servlet temp directory;
98 tmpdir = (File) context.getAttribute
99 ("javax.servlet.context.tempdir");
100
101 // Try to locate the file in the servlet context
102 is = context.getResourceAsStream(pathname);
103 } else if (ctx instanceof PortletWebContext) {
104 PortletContext context = ((PortletWebContext) ctx).getContext();
105
106 // Can we access the file in the portlet directory?
107 String path = context.getRealPath(pathname);
108 if (path != null) {
109 File file = new File(path);
110 if (file.exists()) {
111 return (file.toURI());
112 }
113 }
114
115 // Try to locate the file in the servlet context
116 is = context.getResourceAsStream(pathname);
117 }
118
119 if (tmpdir == null) {
120 // Set the temp directory
121 tmpdir = new File(System.getProperty("java.io.tmpdir"));
122 }
123
124 // Check to see if the tmp file exists
125 File tmpfile = new File(tmpdir, pathname);
126 if (tmpfile.exists()) {
127 return (tmpfile.toURI());
128 }
129
130 // Check to see if the path name is absolute
131 File file = new File(pathname);
132 if (is != null && file.exists()) {
133 return (file.toURI());
134 }
135
136 // Try to locate the file on the classpath
137 if (is == null) {
138 is = getClass().getResourceAsStream(pathname);
139 }
140
141 // If no source stream is able to be located
142 if (is == null) {
143 throw new IOException("Unable to load resource:" + pathname);
144 }
145
146 // Read from the source stream and create a tmp file
147 BufferedInputStream bis = new BufferedInputStream(is, 1024);
148 FileOutputStream os =
149 new FileOutputStream(tmpfile);
150 BufferedOutputStream bos = new BufferedOutputStream(os, 1024);
151 byte buffer[] = new byte[1024];
152 while (true) {
153 int n = bis.read(buffer);
154 if (n <= 0) {
155 break;
156 }
157 bos.write(buffer, 0, n);
158 }
159 bos.close();
160 bis.close();
161 return (tmpfile.toURI());
162 */
163
164 /***
165 * Get a {@link Source} object.
166 * @param location - the URI to resolve. If this is relative it is either
167 * resolved relative to the base parameter (if not null)
168 * or relative to a base setting of the source resolver
169 * itself.
170 * @param base - a base URI for resolving relative locations. This
171 * is optional and can be <code>null</code>.
172 * @param parameters - Additional parameters for the URI. The parameters
173 * are specific to the used scheme.
174 * @return the resolved source object.
175 * @throws MalformedURLException if <code>location</code> is malformed.
176 * @throws IOException if the source couldn't be created for some other reason.
177 */
178 public Source resolveURI( String location,
179 String base,
180 Map parameters )
181 throws MalformedURLException, IOException {
182
183 URL url = null;
184 if (ctx instanceof ServletWebContext) {
185 ServletContext context = ((ServletWebContext) ctx).getContext();
186
187 // Can we access the file in the servlet directory?
188 url = context.getResource(location);
189 } else if (ctx instanceof PortletWebContext) {
190 PortletContext context = ((PortletWebContext) ctx).getContext();
191
192 // Can we access the file in the servlet directory?
193 url = context.getResource(location);
194 }
195 if (url != null) {
196 URLSource source = new URLSource();
197 source.init(url, null);
198 return source;
199 } else {
200 return new ResourceSource("resource:/"+location);
201 }
202 }
203
204 /***
205 * Releases a resolved resource.
206 *
207 * @param source the source to release.
208 */
209 public void release( Source source ) {}
210 }