1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.resource;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.URL;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Map;
27
28 import javax.faces.application.ProjectStage;
29 import javax.faces.application.Resource;
30 import javax.faces.context.FacesContext;
31
32
33
34
35 public class ResourceImpl extends Resource implements ContractResource
36 {
37 protected final static String JAVAX_FACES_LIBRARY_NAME = "javax.faces";
38 protected final static String JSF_JS_RESOURCE_NAME = "jsf.js";
39
40
41 private ResourceMeta _resourceMeta;
42 private ResourceLoader _resourceLoader;
43 private ResourceHandlerSupport _resourceHandlerSupport;
44
45 private URL _url;
46 private String _requestPath;
47
48 public ResourceImpl(ResourceMeta resourceMeta,
49 ResourceLoader resourceLoader, ResourceHandlerSupport support, String contentType)
50 {
51 _resourceMeta = resourceMeta;
52 _resourceLoader = resourceLoader;
53 _resourceHandlerSupport = support;
54 setLibraryName(resourceMeta.getLibraryName());
55 setResourceName(resourceMeta.getResourceName());
56 setContentType(contentType);
57 }
58
59 public ResourceImpl(ResourceMeta resourceMeta,
60 ResourceLoader resourceLoader, ResourceHandlerSupport support, String contentType,
61 URL url, String requestPath)
62 {
63
64 _resourceMeta = resourceMeta;
65 _resourceLoader = resourceLoader;
66 _resourceHandlerSupport = support;
67 _url = url;
68 _requestPath = requestPath;
69 setLibraryName(resourceMeta.getLibraryName());
70 setResourceName(resourceMeta.getResourceName());
71 setContentType(contentType);
72 }
73
74 public ResourceLoader getResourceLoader()
75 {
76 return _resourceLoader;
77 }
78
79 @Override
80 public InputStream getInputStream() throws IOException
81 {
82 if (couldResourceContainValueExpressions())
83 {
84 return new ValueExpressionFilterInputStream(
85 getResourceLoader().getResourceInputStream(_resourceMeta), getLibraryName(), getResourceName());
86 }
87 else
88 {
89 return getResourceLoader().getResourceInputStream(_resourceMeta);
90 }
91 }
92
93 private boolean couldResourceContainValueExpressions()
94 {
95 if (_resourceMeta.couldResourceContainValueExpressions())
96 {
97 return true;
98 }
99 else
100 {
101
102 String contentType = getContentType();
103
104 return ("text/css".equals(contentType));
105 }
106 }
107
108 @Override
109 public String getRequestPath()
110 {
111 if (_requestPath == null)
112 {
113 String path;
114 if (_resourceHandlerSupport.isExtensionMapping())
115 {
116 path = _resourceHandlerSupport.getResourceIdentifier() + '/' +
117 getResourceName() + _resourceHandlerSupport.getMapping();
118 }
119 else
120 {
121 String mapping = _resourceHandlerSupport.getMapping();
122 path = _resourceHandlerSupport.getResourceIdentifier() + '/' + getResourceName();
123 path = (mapping == null) ? path : mapping + path;
124 }
125
126 FacesContext facesContext = FacesContext.getCurrentInstance();
127 String metadata = null;
128 boolean useAmp = false;
129 if (getLibraryName() != null)
130 {
131 metadata = "?ln=" + getLibraryName();
132 path = path + metadata;
133 useAmp = true;
134
135 if (!facesContext.isProjectStage(ProjectStage.Production)
136 && JSF_JS_RESOURCE_NAME.equals(getResourceName())
137 && JAVAX_FACES_LIBRARY_NAME.equals(getLibraryName()))
138 {
139
140 path = path + "&stage=" + facesContext.getApplication().getProjectStage().toString();
141 }
142 }
143 if (_resourceMeta.getLocalePrefix() != null)
144 {
145 path = path + (useAmp ? '&' : '?') + "loc=" + _resourceMeta.getLocalePrefix();
146 useAmp = true;
147 }
148 if (_resourceMeta.getContractName() != null)
149 {
150 path = path + (useAmp ? '&' : '?') + "con=" + _resourceMeta.getContractName();
151 useAmp = true;
152 }
153 _requestPath = facesContext.getApplication().getViewHandler().getResourceURL(facesContext, path);
154 }
155 return _requestPath;
156 }
157
158 @Override
159 public Map<String, String> getResponseHeaders()
160 {
161 FacesContext facesContext = FacesContext.getCurrentInstance();
162
163 if (facesContext.getApplication().getResourceHandler().isResourceRequest(facesContext))
164 {
165 Map<String, String> headers = new HashMap<String, String>();
166
167 long lastModified;
168 try
169 {
170 lastModified = ResourceLoaderUtils.getResourceLastModified(this.getURL());
171 }
172 catch (IOException e)
173 {
174 lastModified = -1;
175 }
176
177
178
179
180 if (this.couldResourceContainValueExpressions() &&
181 lastModified < _resourceHandlerSupport.getStartupTime())
182 {
183 lastModified = _resourceHandlerSupport.getStartupTime();
184 }
185 else if (_resourceMeta instanceof AliasResourceMetaImpl &&
186 lastModified < _resourceHandlerSupport.getStartupTime())
187 {
188
189
190 lastModified = _resourceHandlerSupport.getStartupTime();
191 }
192
193 if (lastModified >= 0)
194 {
195 headers.put("Last-Modified", ResourceLoaderUtils.formatDateHeader(lastModified));
196
197 long expires;
198 if (facesContext.isProjectStage(ProjectStage.Development))
199 {
200
201 expires = System.currentTimeMillis();
202 }
203 else
204 {
205 expires = System.currentTimeMillis() + _resourceHandlerSupport.getMaxTimeExpires();
206 }
207 headers.put("Expires", ResourceLoaderUtils.formatDateHeader(expires));
208 }
209
210 return headers;
211 }
212 else
213 {
214
215 return Collections.emptyMap();
216 }
217 }
218
219 @Override
220 public URL getURL()
221 {
222
223
224 if (_url == null)
225 {
226 _url = getResourceLoader().getResourceURL(_resourceMeta);
227 }
228 return _url;
229 }
230
231 @Override
232 public boolean userAgentNeedsUpdate(FacesContext context)
233 {
234
235
236
237
238
239
240
241
242
243
244
245 String ifModifiedSinceString = context.getExternalContext().getRequestHeaderMap().get("If-Modified-Since");
246
247 if (ifModifiedSinceString == null)
248 {
249 return true;
250 }
251
252 Long ifModifiedSince = ResourceLoaderUtils.parseDateHeader(ifModifiedSinceString);
253
254 if (ifModifiedSince == null)
255 {
256 return true;
257 }
258
259 Long lastModified;
260 try
261 {
262 lastModified = ResourceLoaderUtils.getResourceLastModified(this.getURL());
263 }
264 catch (IOException exception)
265 {
266 lastModified = -1L;
267 }
268
269 if (lastModified >= 0)
270 {
271 if (this.couldResourceContainValueExpressions() &&
272 lastModified < _resourceHandlerSupport.getStartupTime())
273 {
274 lastModified = _resourceHandlerSupport.getStartupTime();
275 }
276
277
278
279
280
281
282
283 if ( (lastModified-(lastModified % 1000)) <= ifModifiedSince)
284 {
285 return false;
286 }
287 }
288
289 return true;
290 }
291
292 protected ResourceHandlerSupport getResourceHandlerSupport()
293 {
294 return _resourceHandlerSupport;
295 }
296
297 protected ResourceMeta getResourceMeta()
298 {
299 return _resourceMeta;
300 }
301
302 public boolean isContractResource()
303 {
304 return _resourceMeta.getContractName() != null;
305 }
306
307 public String getContractName()
308 {
309 return _resourceMeta.getContractName();
310 }
311 }