You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2010/09/01 18:51:38 UTC
svn commit: r991602 -
/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java
Author: ivaynberg
Date: Wed Sep 1 16:51:38 2010
New Revision: 991602
URL: http://svn.apache.org/viewvc?rev=991602&view=rev
Log:
Issue: WICKET-3027
Modified:
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java?rev=991602&r1=991601&r2=991602&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java Wed Sep 1 16:51:38 2010
@@ -16,6 +16,7 @@
*/
package org.apache.wicket.request.resource;
+import java.io.IOException;
import java.util.Locale;
import javax.servlet.http.HttpServletResponse;
@@ -23,17 +24,15 @@ import javax.servlet.http.HttpServletRes
import org.apache.wicket.ThreadContext;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.markup.html.IPackageResourceGuard;
-import org.apache.wicket.request.cycle.RequestCycle;
-import org.apache.wicket.request.handler.AbortRequestHandler;
-import org.apache.wicket.request.http.WebResponse;
-import org.apache.wicket.request.http.handler.ErrorCodeResponseHandler;
+import org.apache.wicket.util.io.IOUtils;
import org.apache.wicket.util.lang.Packages;
import org.apache.wicket.util.lang.WicketObjects;
import org.apache.wicket.util.resource.IResourceStream;
+import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class PackageResource implements IResource
+public class PackageResource extends AbstractResource
{
private static final Logger log = LoggerFactory.getLogger(PackageResource.class);
@@ -48,7 +47,7 @@ public class PackageResource implements
/**
* Construct.
- *
+ *
* @param message
*/
public PackageResourceBlockedException(String message)
@@ -57,41 +56,54 @@ public class PackageResource implements
}
}
- /** The path to the resource */
+ /**
+ * The path to the resource
+ */
private final String absolutePath;
- /** The resource's locale */
+ /**
+ * The resource's locale
+ */
private final Locale locale;
- /** The path this resource was created with. */
+ /**
+ * The path this resource was created with.
+ */
private final String path;
- /** The scoping class, used for class loading and to determine the package. */
+ /**
+ * The scoping class, used for class loading and to determine the package.
+ */
private final String scopeName;
- /** The resource's style */
+ /**
+ * The resource's style
+ */
private final String style;
- /** The component's variation (of the style) */
+ /**
+ * The component's variation (of the style)
+ */
private final String variation;
+
+ /**
+ * should response be cacheable in browser?
+ */
+ private boolean cacheable = true;
+
/**
* Hidden constructor.
- *
- * @param scope
- * This argument will be used to get the class loader for loading the package
- * resource, and to determine what package it is in
- * @param name
- * The relative path to the resource
- * @param locale
- * The locale of the resource
- * @param style
- * The style of the resource
- * @param variation
- * The component's variation (of the style)
+ *
+ * @param scope This argument will be used to get the class loader for loading the package
+ * resource, and to determine what package it is in
+ * @param name The relative path to the resource
+ * @param locale The locale of the resource
+ * @param style The style of the resource
+ * @param variation The component's variation (of the style)
*/
protected PackageResource(final Class<?> scope, final String name, final Locale locale,
- final String style, final String variation)
+ final String style, final String variation)
{
// Convert resource path to absolute path relative to base package
absolutePath = Packages.absolutePath(scope, name);
@@ -99,8 +111,8 @@ public class PackageResource implements
if (!accept(scope, name))
{
throw new PackageResourceBlockedException(
- "Access denied to (static) package resource " + absolutePath +
- ". See IPackageResourceGuard");
+ "Access denied to (static) package resource " + absolutePath +
+ ". See IPackageResourceGuard");
}
// TODO NG: Check path for ../
@@ -114,7 +126,7 @@ public class PackageResource implements
/**
* Gets the scoping class, used for class loading and to determine the package.
- *
+ *
* @return the scoping class
*/
public final Class<?> getScope()
@@ -124,7 +136,7 @@ public class PackageResource implements
/**
* Gets the style.
- *
+ *
* @return the style
*/
public final String getStyle()
@@ -133,39 +145,115 @@ public class PackageResource implements
}
/**
- * @see org.apache.wicket.request.resource.IResource#respond(org.apache.wicket.request.resource.IResource.Attributes)
+ * returns is resource is cacheable
+ *
+ * @return <code>true</code> if cacheable
*/
- public void respond(Attributes attributes)
+ public boolean isCacheable()
{
- // Locate resource
- IResourceStream resourceStream = ThreadContext.getApplication()
- .getResourceSettings()
- .getResourceStreamLocator()
- .locate(getScope(), absolutePath, style, variation, locale, null);
+ return cacheable;
+ }
+
+ /**
+ * sets is resource is cacheable
+ *
+ * @param cacheable <code>true</code> if cacheable
+ */
+ public void setCacheable(boolean cacheable)
+ {
+ this.cacheable = cacheable;
+ }
- if (resourceStream == null)
+ /**
+ * creates a new resource response based on the request attributes
+ *
+ * @param attributes current request attributes from client
+ * @return resource response for answering request
+ */
+ @Override
+ protected ResourceResponse newResourceResponse(Attributes attributes)
+ {
+ ResourceResponse resourceResponse = new ResourceResponse();
+
+ if (resourceResponse.dataNeedsToBeWritten(attributes))
{
- String msg = "Unable to find package resource [path = " + absolutePath + ", style = " +
- style + ", variation = " + variation + ", locale = " + locale + "]";
- log.warn(msg);
+ IResourceStream resourceStream = getResourceStream();
+ resourceResponse.setContentType(resourceStream.getContentType());
+
+ if (resourceStream == null)
+ return sendResourceError(resourceResponse, HttpServletResponse.SC_NOT_FOUND, "Unable to find resource");
+
+ try
+ {
+ final byte[] bytes;
- if (RequestCycle.get().getResponse() instanceof WebResponse)
+ try
+ {
+ bytes = IOUtils.toByteArray(resourceStream.getInputStream());
+ }
+ finally
+ {
+ resourceStream.close();
+ }
+ resourceResponse.setContentLength(bytes.length);
+ resourceResponse.setWriteCallback(new WriteCallback()
+ {
+ @Override
+ public void writeData(Attributes attributes)
+ {
+ attributes.getResponse().write(bytes);
+ }
+ });
+ }
+ catch (IOException e)
{
- RequestCycle.get().replaceAllRequestHandlers(
- new ErrorCodeResponseHandler(HttpServletResponse.SC_NOT_FOUND, msg));
+ log.debug(e.getMessage(), e);
+ return sendResourceError(resourceResponse, 500, "Unable to read resource stream");
}
- else
+ catch (ResourceStreamNotFoundException e)
{
- RequestCycle.get().replaceAllRequestHandlers(new AbortRequestHandler());
+ log.debug(e.getMessage(), e);
+ return sendResourceError(resourceResponse, 500, "Unable to open resource stream");
}
- return;
}
+ resourceResponse.setCacheable(isCacheable());
+ return resourceResponse;
+ }
+
+ /**
+ * send resource specific error message and write log entry
+ *
+ * @param resourceResponse resource response for method chaining
+ * @param errorCode error code (=http status)
+ * @param errorMessage error message (=http error message)
+ * @return
+ */
+ private ResourceResponse sendResourceError(ResourceResponse resourceResponse, int errorCode, String errorMessage)
+ {
+ String msg = String.format("resource [path = %s, style = %s, variation = %s, locale = %s]: %s (status=%d)",
+ absolutePath, style, variation, locale, errorMessage, errorCode);
+
+ log.warn(msg);
- new ResourceStreamResource(resourceStream).respond(attributes);
+ resourceResponse.setError(errorCode, errorMessage);
+ return resourceResponse;
+ }
+
+ /**
+ * locate resource stream for current resource
+ *
+ * @return resource stream or <code>null</code> if not found
+ */
+ private IResourceStream getResourceStream()
+ {
+ // Locate resource
+ return ThreadContext.getApplication()
+ .getResourceSettings()
+ .getResourceStreamLocator()
+ .locate(getScope(), absolutePath, style, variation, locale, null);
}
/**
- *
* @param scope
* @param path
* @return
@@ -173,36 +261,31 @@ public class PackageResource implements
private boolean accept(Class<?> scope, String path)
{
IPackageResourceGuard guard = ThreadContext.getApplication()
- .getResourceSettings()
- .getPackageResourceGuard();
+ .getResourceSettings()
+ .getPackageResourceGuard();
return guard.accept(scope, path);
}
/**
* Gets whether a resource for a given set of criteria exists.
- *
- * @param scope
- * This argument will be used to get the class loader for loading the package
- * resource, and to determine what package it is in. Typically this is the class in
- * which you call this method
- * @param path
- * The path to the resource
- * @param locale
- * The locale of the resource
- * @param style
- * The style of the resource (see {@link org.apache.wicket.Session})
- * @param variation
- * The component's variation (of the style)
+ *
+ * @param scope This argument will be used to get the class loader for loading the package
+ * resource, and to determine what package it is in. Typically this is the class in
+ * which you call this method
+ * @param path The path to the resource
+ * @param locale The locale of the resource
+ * @param style The style of the resource (see {@link org.apache.wicket.Session})
+ * @param variation The component's variation (of the style)
* @return true if a resource could be loaded, false otherwise
*/
public static boolean exists(final Class<?> scope, final String path, final Locale locale,
- final String style, final String variation)
+ final String style, final String variation)
{
String absolutePath = Packages.absolutePath(scope, path);
return ThreadContext.getApplication()
- .getResourceSettings()
- .getResourceStreamLocator()
- .locate(scope, absolutePath, style, variation, locale, null) != null;
+ .getResourceSettings()
+ .getResourceStreamLocator()
+ .locate(scope, absolutePath, style, variation, locale, null) != null;
}
}