1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.resource;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.File;
24 import java.io.IOException;
25
26 import java.io.InputStream;
27 import java.net.URL;
28
29 import java.net.UnknownServiceException;
30 import java.net.URLConnection;
31 import java.net.URLStreamHandler;
32 import java.util.Map;
33 import java.util.HashMap;
34
35
36
37
38
39
40
41
42 public class CachingResourceLoader extends ResourceLoader
43 {
44
45
46
47
48
49 public CachingResourceLoader(
50 ResourceLoader parent)
51 {
52 super(parent);
53
54 _cache = new HashMap<String, URL>();
55 }
56
57
58
59
60
61
62
63
64
65
66
67 @Override
68 protected URL findResource(
69 String path
70 ) throws IOException
71 {
72 URL url = _cache.get(path);
73
74 if (url == null)
75 {
76 url = getParent().getResource(path);
77
78 if (url != null)
79 {
80 url = new URL("cache", null, -1, path, new URLStreamHandlerImpl(url));
81 _cache.put(path, url);
82 }
83 }
84
85 return url;
86 }
87
88 private final Map<String, URL> _cache;
89
90
91
92
93 static private class URLStreamHandlerImpl extends URLStreamHandler
94 {
95 public URLStreamHandlerImpl(
96 URL delegate)
97 {
98 _delegate = delegate;
99 }
100
101 @Override
102 protected URLConnection openConnection(
103 URL url
104 ) throws IOException
105 {
106 return new URLConnectionImpl(url, _delegate.openConnection(), this);
107 }
108
109 protected InputStream getInputStream(
110 URLConnection conn) throws IOException
111 {
112 long lastModified = _getLastModified(_delegate);
113
114 if (_contents == null || _contentsModified < lastModified)
115 {
116 InputStream in = conn.getInputStream();
117 ByteArrayOutputStream out = new ByteArrayOutputStream();
118 try
119 {
120 byte[] buffer = new byte[2048];
121 int length;
122 while ((length = (in.read(buffer))) >= 0)
123 {
124 out.write(buffer, 0, length);
125 }
126 }
127 finally
128 {
129 in.close();
130 }
131 _contents = out.toByteArray();
132 _contentsModified = conn.getLastModified();
133 }
134
135 return new ByteArrayInputStream(_contents);
136 }
137
138 private final URL _delegate;
139 private byte[] _contents;
140 private long _contentsModified;
141 }
142
143
144
145
146 static private class URLConnectionImpl extends URLConnection
147 {
148
149
150
151
152
153
154 public URLConnectionImpl(
155 URL url,
156 URLConnection conn,
157 URLStreamHandlerImpl handler)
158 {
159 super(url);
160 _conn = conn;
161 _handler = handler;
162 }
163
164 @Override
165 public void connect() throws IOException
166 {
167
168 }
169
170 @Override
171 public String getContentType()
172 {
173 return _conn.getContentType();
174 }
175
176 @Override
177 public int getContentLength()
178 {
179 return _conn.getContentLength();
180 }
181
182 @Override
183 public long getLastModified()
184 {
185 return _conn.getLastModified();
186 }
187
188 @Override
189 public String getHeaderField(
190 String name)
191 {
192 return _conn.getHeaderField(name);
193 }
194
195 @Override
196 public InputStream getInputStream() throws IOException
197 {
198 return _handler.getInputStream(_conn);
199 }
200
201 private final URLConnection _conn;
202 private final URLStreamHandlerImpl _handler;
203 }
204
205 static private long _getLastModified(URL url) throws IOException
206 {
207 if ("file".equals(url.getProtocol()))
208 {
209 String externalForm = url.toExternalForm();
210
211 File file = new File(externalForm.substring(5));
212
213 return file.lastModified();
214 }
215 else
216 {
217 URLConnection connection = url.openConnection();
218 long modified = connection.getLastModified();
219 try
220 {
221 InputStream is = connection.getInputStream();
222 if (is != null)
223 is.close();
224 }
225 catch (UnknownServiceException use)
226 {
227 }
228
229 return modified;
230 }
231 }
232 }