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