Author: nbelaevski
Date: 2009-07-16 11:28:04 -0400 (Thu, 16 Jul 2009)
New Revision: 14942
Added:
root/framework/trunk/impl/src/test/java/org/richfaces/resource/EmptyStreamResource.java
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/resource/AbstractBaseResource.java
root/framework/trunk/impl/src/main/java/org/richfaces/resource/CachedResourceImpl.java
root/framework/trunk/impl/src/main/java/org/richfaces/resource/ResourceHandlerImpl.java
root/framework/trunk/impl/src/main/java/org/richfaces/resource/TestResource2.java
root/framework/trunk/impl/src/test/java/org/richfaces/resource/AbstractBaseResourceTest.java
root/framework/trunk/impl/src/test/java/org/richfaces/resource/AbstractCacheableResourceTest.java
root/framework/trunk/impl/src/test/java/org/richfaces/resource/CachedResourceImplTest.java
root/framework/trunk/impl/src/test/java/org/richfaces/resource/MarkerFileResourceImpl.java
root/framework/trunk/impl/src/test/java/org/richfaces/resource/NoMarkerFileResourceImpl.java
root/framework/trunk/impl/src/test/java/org/richfaces/resource/VersionedResourceImpl.java
Log:
Resources:
- timeToLive added
- couple of bugs fixed
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/resource/AbstractBaseResource.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/resource/AbstractBaseResource.java 2009-07-16
15:21:09 UTC (rev 14941)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/resource/AbstractBaseResource.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -21,7 +21,6 @@
package org.richfaces.resource;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -52,8 +51,6 @@
private String version;
- protected InputStream EMPTY_STREAM = new ByteArrayInputStream(new byte[0]);
-
public AbstractBaseResource() {
super();
@@ -77,6 +74,10 @@
return null;
}
+ protected int getTimeToLive(FacesContext context) {
+ return 0;
+ }
+
/**
* @param resourceContext current {@link ResourceContext}
* @return Returns the lastModified.
@@ -201,18 +202,34 @@
if (cacheable) {
long currentTime = getCurrentTime();
- Date expires = getExpired(facesContext);
- if (expires == null) {
- expires = new Date(currentTime + InternetResource.DEFAULT_EXPIRE);
+
+ String formattedExpireDate = null;
+ long maxAge = getTimeToLive(facesContext);
+
+ if (maxAge > 0) {
+ formattedExpireDate = Util.formatHttpDate(currentTime + maxAge * 1000L);
+ } else {
+ Date expired = getExpired(facesContext);
+ if (expired != null) {
+ formattedExpireDate = Util.formatHttpDate(expired);
+ maxAge = (expired.getTime() - currentTime) / 1000L;
+ } else {
+ maxAge = InternetResource.DEFAULT_TTL;
+ formattedExpireDate = Util.formatHttpDate(currentTime + maxAge * 1000L);
+ }
}
+ if (formattedExpireDate != null) {
+ headers.put("Expires", formattedExpireDate);
+ }
+ if (maxAge > 0) {
+ headers.put("Cache-Control", "max-age=" + maxAge);
+ }
+
String entityTag = getEntityTag(facesContext);
if (entityTag != null) {
headers.put("ETag", entityTag);
}
-
- headers.put("Expires", Util.formatHttpDate(expires));
- headers.put("Cache-Control", "max-age=" + (expires.getTime() -
currentTime) / 1000L);
} else {
headers.put("Expires", "0");
headers.put("Cache-Control", "max-age=0, no-store, no-cache");
@@ -254,12 +271,17 @@
@Override
public long getExpiration() {
FacesContext facesContext = FacesContext.getCurrentInstance();
+ long ttl = AbstractBaseResource.this.getTimeToLive(facesContext);
+ if (ttl > 0) {
+ return System.currentTimeMillis() + ttl * 1000;
+ }
+
Date date = AbstractBaseResource.this.getExpired(facesContext);
if (date != null) {
return date.getTime();
}
- return 0;
+ return System.currentTimeMillis() + InternetResource.DEFAULT_TTL * 1000;
}
@Override
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/resource/CachedResourceImpl.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/resource/CachedResourceImpl.java 2009-07-16
15:21:09 UTC (rev 14941)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/resource/CachedResourceImpl.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -45,9 +45,6 @@
*/
class CachedResourceImpl extends AbstractCacheableResource {
- //TODO use configuration parameter
- private static final long DEFAULT_EXPIRE = 24 * 60 * 60 * 1000;
-
//[0..1]
private static final float CACHE_EXPIRATION_COEFFICIENT = 0.9f;
@@ -73,7 +70,9 @@
private void initializeFromHeaders() {
this.entityTag = null;
this.lastModified = null;
- this.setContentType(null);
+
+ //this.setContentType(null);
+
this.expired = null;
Date expiredFromHeader = null;
@@ -106,9 +105,9 @@
}
}
}
- } else if ("content-type".equals(headerKey)) {
+ }/* else if ("content-type".equals(headerKey)) {
this.setContentType(headerEntry.getValue());
- }
+ }*/
}
long currentTime = getCurrentTime();
@@ -152,6 +151,7 @@
public void initialize(Resource resource) {
setResourceName(resource.getResourceName());
+ setContentType(resource.getContentType());
this.headers = resource.getResponseHeaders();
initializeFromHeaders();
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/resource/ResourceHandlerImpl.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/resource/ResourceHandlerImpl.java 2009-07-16
15:21:09 UTC (rev 14941)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/resource/ResourceHandlerImpl.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -216,13 +216,16 @@
} catch (NumberFormatException e) {
// TODO: handle exception
}
- } else if ("content-type".equals(headerName.toLowerCase(Locale.US))) {
+ }/* else if ("content-type".equals(headerName.toLowerCase(Locale.US))) {
externalContext.setResponseContentType(headerValue);
- } else {
+ }*/ else {
externalContext.setResponseHeader(headerName, headerValue);
}
}
+ //TODO null content type?
+ externalContext.setResponseContentType(resource.getContentType());
+
//TODO setup output buffer size according to configuration parameter
InputStream is = resource.getInputStream();
OutputStream os = externalContext.getResponseOutputStream();
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/resource/TestResource2.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/resource/TestResource2.java 2009-07-16
15:21:09 UTC (rev 14941)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/resource/TestResource2.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -108,12 +108,12 @@
@Override
public String getEntityTag(FacesContext context) {
- return Integer.toHexString(color.getRGB() & 0xFFFFFF);
+ return ResourceUtils.formatWeakTag(Integer.toHexString(color.getRGB() &
0xFFFFFF));
}
@Override
protected Date getExpired(FacesContext context) {
- return new Date(System.currentTimeMillis() + 10000);
+ return null;//new Date(System.currentTimeMillis() + 10000);
}
@Override
Modified:
root/framework/trunk/impl/src/test/java/org/richfaces/resource/AbstractBaseResourceTest.java
===================================================================
---
root/framework/trunk/impl/src/test/java/org/richfaces/resource/AbstractBaseResourceTest.java 2009-07-16
15:21:09 UTC (rev 14941)
+++
root/framework/trunk/impl/src/test/java/org/richfaces/resource/AbstractBaseResourceTest.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -60,7 +60,7 @@
@Override
public InputStream getInputStream() {
- return null;
+ throw new UnsupportedOperationException();
}
public ResourceImpl() {
@@ -69,9 +69,39 @@
setResourceName("org.richfaces.resource.ResourceImpl");
}
}
+
+ private class MockStateAwareResourceImpl extends MockResourceImpl implements StateHolder
{
- private class MockResourceImpl extends AbstractBaseResource implements StateHolder {
+ private Object resourceState;
+
+ private boolean _transient = false;
+
+ public MockStateAwareResourceImpl() {
+ super();
+
+ setResourceName("org.richfaces.resource.MockStateAwareResource");
+ }
+
+ public boolean isTransient() {
+ return _transient;
+ }
+ public void setTransient(boolean newTransientValue) {
+ this._transient = newTransientValue;
+ }
+
+ public Object saveState(FacesContext context) {
+ return resourceState;
+ }
+
+ public void restoreState(FacesContext context, Object state) {
+ this.resourceState = state;
+ }
+
+ }
+
+ private class MockResourceImpl extends AbstractBaseResource {
+
private String version;
private int contentLength = -1;
@@ -86,7 +116,7 @@
private String entityTag;
- private Object resourceState;
+ private int ttl;
public MockResourceImpl() {
super();
@@ -168,22 +198,13 @@
this.currentTime = currentTime;
}
- public boolean isTransient() {
- return false;
+ @Override
+ protected int getTimeToLive(FacesContext context) {
+ return ttl;
}
-
- public void setTransient(boolean newTransientValue) {
- }
-
- /* (non-Javadoc)
- * @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
- */
- public Object saveState(FacesContext context) {
- return resourceState;
- }
- public void restoreState(FacesContext context, Object state) {
- this.resourceState = state;
+ public void setTimeToLive(int ttl) {
+ this.ttl = ttl;
}
}
@@ -217,8 +238,15 @@
assertEquals("image/png", headers.get("Content-Type"));
assertEquals(7, headers.size());
+
+ mockResource.setTimeToLive(14 * 24 * 60 * 60 /* 14 days */);
+ headers = mockResource.getResponseHeaders();
+ assertEquals("Tue, 28 Jul 2009 12:45:09 GMT",
headers.get("Expires"));
+ assertEquals("Mon, 13 Jul 2009 12:45:09 GMT",
headers.get("Last-Modified"));
+ assertEquals("Tue, 14 Jul 2009 12:45:09 GMT",
headers.get("Date"));
+ assertEquals("max-age=1209600", headers.get("Cache-Control"));
}
-
+
public void testGetHeadersNonCacheable() throws Exception {
MockResourceImpl mockResource = new MockResourceImpl();
mockResource.setCacheable(false);
@@ -253,18 +281,35 @@
Object resourceState = new Object();
ResourceCodec resourceCodec = EasyMock.createMock(ResourceCodec.class);
- EasyMock.expect(resourceCodec.encodeResource(EasyMock.eq("org.richfaces.resource.MockResource"),
+ EasyMock.expect(resourceCodec.encodeResource(EasyMock.eq("org.richfaces.resource.MockStateAwareResource"),
EasyMock.same(resourceState),
EasyMock.eq("4_0_alpha"))).andReturn("Resource0/4_0_alpha/data");
+
+ EasyMock.expect(resourceCodec.encodeResource(EasyMock.eq("org.richfaces.resource.MockStateAwareResource"),
+ EasyMock.eq(null),
EasyMock.eq("4_0_alpha"))).andReturn("Resource1/4_0_alpha");
+ EasyMock.expect(resourceCodec.encodeResource(EasyMock.eq("org.richfaces.resource.MockResource"),
+ EasyMock.eq(null),
EasyMock.eq("4_0_alpha"))).andReturn("Resource2/4_0_alpha");
+
+ EasyMock.replay(resourceCodec);
ResourceHandlerImpl.setResourceCodec(resourceCodec);
+
+ MockStateAwareResourceImpl stateAwareResourceImpl = new MockStateAwareResourceImpl();
+ stateAwareResourceImpl.setVersion("4_0_alpha");
+ stateAwareResourceImpl.restoreState(facesContext, resourceState);
+
+ assertEquals("org.richfaces.resource.MockStateAwareResource",
stateAwareResourceImpl.getResourceName());
+ assertEquals("/rfRes/Resource0/4_0_alpha/data.jsf",
stateAwareResourceImpl.getRequestPath());
+
+ stateAwareResourceImpl.setTransient(true);
+
+ assertEquals("/rfRes/Resource1/4_0_alpha.jsf",
stateAwareResourceImpl.getRequestPath());
+
MockResourceImpl resourceImpl = new MockResourceImpl();
resourceImpl.setVersion("4_0_alpha");
- resourceImpl.restoreState(facesContext, resourceState);
assertEquals("org.richfaces.resource.MockResource",
resourceImpl.getResourceName());
- EasyMock.replay(resourceCodec);
- assertEquals("/rfRes/Resource0/4_0_alpha/data.jsf",
resourceImpl.getRequestPath());
+ assertEquals("/rfRes/Resource2/4_0_alpha.jsf",
resourceImpl.getRequestPath());
EasyMock.verify(resourceCodec);
}
@@ -307,7 +352,7 @@
assertEquals(-1, urlConnection2.getContentLength());
assertNull(urlConnection2.getContentType());
assertEquals(0, urlConnection2.getLastModified());
- assertEquals(0, urlConnection2.getExpiration());
+ assertTrue(urlConnection2.getExpiration() > 0);
}
public void testDefaults() throws Exception {
Modified:
root/framework/trunk/impl/src/test/java/org/richfaces/resource/AbstractCacheableResourceTest.java
===================================================================
---
root/framework/trunk/impl/src/test/java/org/richfaces/resource/AbstractCacheableResourceTest.java 2009-07-16
15:21:09 UTC (rev 14941)
+++
root/framework/trunk/impl/src/test/java/org/richfaces/resource/AbstractCacheableResourceTest.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -261,66 +261,39 @@
this.lastModified = lastModified;
}
- public void setCacheable(boolean cacheable) {
- this.cacheable = cacheable;
- }
-
- private boolean cacheable = true;
-
- /* (non-Javadoc)
- * @see
org.richfaces.resource.AbstractResource#getEntityTag(javax.faces.context.FacesContext)
- */
@Override
protected String getEntityTag(FacesContext context) {
return entityTag;
}
- /* (non-Javadoc)
- * @see
org.richfaces.resource.AbstractResource#getLastModified(javax.faces.context.FacesContext)
- */
@Override
protected Date getLastModified(FacesContext context) {
return lastModified;
}
- /* (non-Javadoc)
- * @see
org.richfaces.resource.AbstractResource#isCacheable(javax.faces.context.FacesContext)
- */
@Override
- public boolean isCacheable(FacesContext context) {
- return cacheable;
- }
-
- /* (non-Javadoc)
- * @see javax.faces.application.Resource#getInputStream()
- */
- @Override
public InputStream getInputStream() throws IOException {
throw new UnsupportedOperationException();
}
- /* (non-Javadoc)
- * @see javax.faces.application.Resource#getRequestPath()
- */
@Override
public String getRequestPath() {
throw new UnsupportedOperationException();
}
- /* (non-Javadoc)
- * @see javax.faces.application.Resource#getResponseHeaders()
- */
@Override
public Map<String, String> getResponseHeaders() {
throw new UnsupportedOperationException();
}
- /* (non-Javadoc)
- * @see javax.faces.application.Resource#getURL()
- */
@Override
public URL getURL() {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public boolean isCacheable(FacesContext context) {
+ throw new UnsupportedOperationException();
+ }
}
Modified:
root/framework/trunk/impl/src/test/java/org/richfaces/resource/CachedResourceImplTest.java
===================================================================
---
root/framework/trunk/impl/src/test/java/org/richfaces/resource/CachedResourceImplTest.java 2009-07-16
15:21:09 UTC (rev 14941)
+++
root/framework/trunk/impl/src/test/java/org/richfaces/resource/CachedResourceImplTest.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -77,20 +77,21 @@
private InputStream stream;
- @Override
- public Map<String, String> getResponseHeaders() {
- return headers;
- }
-
public MockHeadersResourceImpl(Map<String, String> headers,
InputStream stream) {
super();
setResourceName(getClass().getName());
+ setContentType("image/png");
this.headers = headers;
this.stream = stream != null ? stream : new ByteArrayInputStream(new byte[0]);
}
@Override
+ public Map<String, String> getResponseHeaders() {
+ return headers;
+ }
+
+ @Override
public InputStream getInputStream() throws IOException {
return stream;
}
@@ -148,7 +149,6 @@
headers.put("ETag", "W/\"123\"");
headers.put(LAST_MODIFIED, "Tue, 21 Jul 2009 12:45:09 GMT");
headers.put(EXPIRES, "Tue, 28 Jul 2009 12:45:09 GMT");
- headers.put("Content-Type", "image/png");
headers.put(CACHE_CONTROL, "public, max-age=86400");
return headers;
}
Copied:
root/framework/trunk/impl/src/test/java/org/richfaces/resource/EmptyStreamResource.java
(from rev 14933,
root/framework/trunk/impl/src/test/java/org/richfaces/resource/MarkerFileResourceImpl.java)
===================================================================
---
root/framework/trunk/impl/src/test/java/org/richfaces/resource/EmptyStreamResource.java
(rev 0)
+++
root/framework/trunk/impl/src/test/java/org/richfaces/resource/EmptyStreamResource.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -0,0 +1,40 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.resource;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+/**
+ * @author Nick Belaevski
+ * @since 4.0
+ */
+public class EmptyStreamResource extends AbstractBaseResource {
+
+ protected InputStream EMPTY_STREAM = new ByteArrayInputStream(new byte[0]);
+
+ @Override
+ public InputStream getInputStream() {
+ return EMPTY_STREAM;
+ }
+
+}
Modified:
root/framework/trunk/impl/src/test/java/org/richfaces/resource/MarkerFileResourceImpl.java
===================================================================
---
root/framework/trunk/impl/src/test/java/org/richfaces/resource/MarkerFileResourceImpl.java 2009-07-16
15:21:09 UTC (rev 14941)
+++
root/framework/trunk/impl/src/test/java/org/richfaces/resource/MarkerFileResourceImpl.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -21,17 +21,11 @@
package org.richfaces.resource;
-import java.io.InputStream;
/**
* @author Nick Belaevski
* @since 4.0
*/
-public class MarkerFileResourceImpl extends AbstractBaseResource {
+public class MarkerFileResourceImpl extends EmptyStreamResource {
- @Override
- public InputStream getInputStream() {
- return EMPTY_STREAM;
- }
-
}
Modified:
root/framework/trunk/impl/src/test/java/org/richfaces/resource/NoMarkerFileResourceImpl.java
===================================================================
---
root/framework/trunk/impl/src/test/java/org/richfaces/resource/NoMarkerFileResourceImpl.java 2009-07-16
15:21:09 UTC (rev 14941)
+++
root/framework/trunk/impl/src/test/java/org/richfaces/resource/NoMarkerFileResourceImpl.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -21,17 +21,11 @@
package org.richfaces.resource;
-import java.io.InputStream;
/**
* @author Nick Belaevski
* @since 4.0
*/
-public class NoMarkerFileResourceImpl extends AbstractBaseResource {
+public class NoMarkerFileResourceImpl extends EmptyStreamResource {
- @Override
- public InputStream getInputStream() {
- return EMPTY_STREAM;
- }
-
}
Modified:
root/framework/trunk/impl/src/test/java/org/richfaces/resource/VersionedResourceImpl.java
===================================================================
---
root/framework/trunk/impl/src/test/java/org/richfaces/resource/VersionedResourceImpl.java 2009-07-16
15:21:09 UTC (rev 14941)
+++
root/framework/trunk/impl/src/test/java/org/richfaces/resource/VersionedResourceImpl.java 2009-07-16
15:28:04 UTC (rev 14942)
@@ -21,23 +21,14 @@
package org.richfaces.resource;
-import java.io.InputStream;
/**
* @author Nick Belaevski
* @since 4.0
*/
-public class VersionedResourceImpl extends AbstractBaseResource {
+public class VersionedResourceImpl extends EmptyStreamResource {
- /* (non-Javadoc)
- * @see org.richfaces.resource.AbstractBaseResource#getInputStream()
- */
@Override
- public InputStream getInputStream() {
- return EMPTY_STREAM;
- }
-
- @Override
public String getVersion() {
return "1_0_2";
}