1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
68 super.getInfos();
69 m_mimeType = null;
70
71 if (m_location == null) {
72
73 return;
74 }
75
76 URLConnection connection;
77 try
78 {
79 connection = m_location.openConnection();
80 }
81 catch(IOException ioe)
82 {
83
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 }