View Javadoc

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 }