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.io.InputStream;
21  import java.net.MalformedURLException;
22  import java.net.URL;
23  import java.net.URLConnection;
24  
25  import org.apache.struts.flow.core.source.Source;
26  import org.apache.struts.flow.core.source.SourceException;
27  import org.apache.struts.flow.core.source.SourceNotFoundException;
28  import org.apache.struts.flow.core.source.SourceUtil;
29  import org.apache.struts.flow.core.source.SourceValidity;
30  import org.apache.struts.flow.core.source.impl.validity.TimeStampValidity;
31  
32  /***
33   * Description of a source which is described by the resource protocol
34   * which gets a resource from the classloader.
35   *
36   * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
37   * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:24 $
38   */
39  public final class ResourceSource
40      extends AbstractSource
41      implements Source
42  {
43      /*** Location of the resource */
44      private URL m_location;
45      private String m_mimeType;
46  
47      public ResourceSource( final String systemId ) throws MalformedURLException
48      {
49          final int pos = SourceUtil.indexOfSchemeColon(systemId);
50          if (pos == -1 || ! systemId.startsWith("://", pos))
51          {
52              throw new MalformedURLException("Invalid format for ResourceSource : " + systemId);
53          }
54          
55          setSystemId(systemId);
56          m_location = getClassLoader().getResource(systemId.substring( pos + 3 ));
57          setScheme(systemId.substring(0, pos));
58      }
59      
60      public boolean exists()
61      {
62          return m_location != null;
63      }
64      
65      protected void getInfos()
66      {
67          // Reset infos
68          super.getInfos();
69          m_mimeType = null;
70          
71          if (m_location == null) {
72              // Does not exist
73              return;
74          }
75          
76          URLConnection connection;
77          try
78          {
79              connection = m_location.openConnection();
80          }
81          catch(IOException ioe)
82          {
83              // Exists but unable to open it??
84              return;
85          }
86  
87          setLastModified(connection.getLastModified());
88          setContentLength(connection.getContentLength());
89          m_mimeType = connection.getContentType();
90      }
91      
92      public String getMimeType()
93      {
94          return m_mimeType;
95      }
96  
97      /***
98       * Return an <code>InputStream</code> object to read from the source.
99       *
100      * The returned stream must be closed by the calling code.
101      */
102     public InputStream getInputStream()
103         throws IOException, SourceException
104     {
105         if (!exists())
106         {
107             throw new SourceNotFoundException(getURI());
108         }
109         
110         return m_location.openStream();
111     }
112 
113     /***
114      * Returns {@link TimeStampValidity} as resources may change in a directory-based classloader.
115      */
116     public SourceValidity getValidity()
117     {
118         return new TimeStampValidity(getLastModified());
119     }
120     
121     protected ClassLoader getClassLoader() {
122         ClassLoader loader = Thread.currentThread().getContextClassLoader();
123         if( loader == null )
124         {
125             loader = getClass().getClassLoader();
126         }
127         
128         return loader;
129     }
130 }