Clean-up, fxed typos etc.

This commit is contained in:
Harald Kuhr 2010-04-30 14:33:23 +02:00
parent 037c0d078a
commit e468484d68
14 changed files with 254 additions and 539 deletions

View File

@ -25,14 +25,15 @@ abstract class AbstractServletMapAdapter extends AbstractMap<String, List<String
protected abstract Iterator<String> valuesImpl(String pName); protected abstract Iterator<String> valuesImpl(String pName);
@Override @Override
public List<String> get(Object pKey) { public List<String> get(final Object pKey) {
if (pKey instanceof String) { if (pKey instanceof String) {
return getValues((String) pKey); return getValues((String) pKey);
} }
return null; return null;
} }
private List<String> getValues(String pName) { private List<String> getValues(final String pName) {
List<String> values = mCache.get(pName); List<String> values = mCache.get(pName);
if (values == null) { if (values == null) {
@ -61,13 +62,14 @@ abstract class AbstractServletMapAdapter extends AbstractMap<String, List<String
if (mSize == -1) { if (mSize == -1) {
computeSize(); computeSize();
} }
return mSize; return mSize;
} }
private void computeSize() { private void computeSize() {
Iterator<String> names = keysImpl();
mSize = 0; mSize = 0;
for (;names.hasNext(); names.next()) {
for (Iterator<String> names = keysImpl(); names.hasNext(); names.next()) {
mSize++; mSize++;
} }
} }

View File

@ -147,12 +147,12 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
* @see #init() init * @see #init() init
* @see BeanUtil#configure(Object, java.util.Map, boolean) * @see BeanUtil#configure(Object, java.util.Map, boolean)
*/ */
public void init(FilterConfig pConfig) throws ServletException { public void init(final FilterConfig pConfig) throws ServletException {
if (pConfig == null) { if (pConfig == null) {
throw new ServletConfigException("filterconfig == null"); throw new ServletConfigException("filter config == null");
} }
// Store filterconfig // Store filter config
mFilterConfig = pConfig; mFilterConfig = pConfig;
// Configure this // Configure this
@ -197,8 +197,8 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
* @see Filter#doFilter Filter.doFilter * @see Filter#doFilter Filter.doFilter
* @see #doFilterImpl doFilterImpl * @see #doFilterImpl doFilterImpl
*/ */
public final void doFilter(ServletRequest pRequest, ServletResponse pResponse, FilterChain pFilterChain) throws IOException, ServletException { public final void doFilter(final ServletRequest pRequest, final ServletResponse pResponse, final FilterChain pFilterChain) throws IOException, ServletException {
// If request filter and allready run, continue chain and return fast // If request filter and already run, continue chain and return fast
if (mOncePerRequest && isRunOnce(pRequest)) { if (mOncePerRequest && isRunOnce(pRequest)) {
pFilterChain.doFilter(pRequest, pResponse); pFilterChain.doFilter(pRequest, pResponse);
return; return;
@ -225,8 +225,8 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
* @return {@code true} if the request is allready filtered, otherwise * @return {@code true} if the request is allready filtered, otherwise
* {@code false}. * {@code false}.
*/ */
private boolean isRunOnce(ServletRequest pRequest) { private boolean isRunOnce(final ServletRequest pRequest) {
// If request allready filtered, return true (skip) // If request already filtered, return true (skip)
if (pRequest.getAttribute(mAttribRunOnce) == ATTRIB_RUN_ONCE_VALUE) { if (pRequest.getAttribute(mAttribRunOnce) == ATTRIB_RUN_ONCE_VALUE) {
return true; return true;
} }
@ -299,7 +299,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
* @return a {@code String} containing the value of the initialization * @return a {@code String} containing the value of the initialization
* parameter * parameter
*/ */
public String getInitParameter(String pKey) { public String getInitParameter(final String pKey) {
return mFilterConfig.getInitParameter(pKey); return mFilterConfig.getInitParameter(pKey);
} }
@ -322,7 +322,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
* @param pMessage the log message * @param pMessage the log message
* @see ServletContext#log(String) * @see ServletContext#log(String)
*/ */
protected void log(String pMessage) { protected void log(final String pMessage) {
getServletContext().log(getFilterName() + ": " + pMessage); getServletContext().log(getFilterName() + ": " + pMessage);
} }
@ -335,7 +335,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
* @param pThrowable the exception * @param pThrowable the exception
* @see ServletContext#log(String,Throwable) * @see ServletContext#log(String,Throwable)
*/ */
protected void log(String pMessage, Throwable pThrowable) { protected void log(final String pMessage, final Throwable pThrowable) {
getServletContext().log(getFilterName() + ": " + pMessage, pThrowable); getServletContext().log(getFilterName() + ": " + pMessage, pThrowable);
} }
@ -347,12 +347,12 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
* *
* @deprecated For compatibility only, use {@link #init init} instead. * @deprecated For compatibility only, use {@link #init init} instead.
*/ */
public void setFilterConfig(FilterConfig pFilterConfig) { public void setFilterConfig(final FilterConfig pFilterConfig) {
try { try {
init(pFilterConfig); init(pFilterConfig);
} }
catch (ServletException e) { catch (ServletException e) {
log("Error in init(), see stacktrace for details.", e); log("Error in init(), see stack trace for details.", e);
} }
} }
@ -376,8 +376,8 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
* once per request * once per request
* @see #mOncePerRequest * @see #mOncePerRequest
*/ */
@InitParam @InitParam(name = "once-per-request")
public void setOncePerRequest(boolean pOncePerRequest) { public void setOncePerRequest(final boolean pOncePerRequest) {
mOncePerRequest = pOncePerRequest; mOncePerRequest = pOncePerRequest;
} }
} }

View File

@ -31,7 +31,7 @@ package com.twelvemonkeys.servlet;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* Annotation to be used by serlvets/filters, to have their init-method * Annotation to be used by servlets/filters, to have their {@code init}-method
* automatically convert and set values from their respective configuration. * automatically convert and set values from their respective configuration.
* *
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a> * @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
@ -41,10 +41,12 @@ import java.lang.annotation.*;
* @see com.twelvemonkeys.servlet.GenericServlet#init(javax.servlet.ServletConfig) * @see com.twelvemonkeys.servlet.GenericServlet#init(javax.servlet.ServletConfig)
* @see com.twelvemonkeys.servlet.HttpServlet#init(javax.servlet.ServletConfig) * @see com.twelvemonkeys.servlet.HttpServlet#init(javax.servlet.ServletConfig)
*/ */
// TODO: Actually implement for version 3.0!
@Documented @Documented
@Inherited @Inherited
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
public @interface InitParam { public @interface InitParam {
// TODO: Rename to value, to allow skipping name = "..."
String name() default ""; String name() default "";
} }

View File

@ -53,7 +53,7 @@ public class ServletConfigException extends ServletException {
* @param pMessage the exception message * @param pMessage the exception message
* @param pCause the exception cause * @param pCause the exception cause
*/ */
public ServletConfigException(String pMessage, Throwable pCause) { public ServletConfigException(final String pMessage, final Throwable pCause) {
super(pMessage, pCause); super(pMessage, pCause);
if (getCause() == null) { if (getCause() == null) {
initCause(pCause); initCause(pCause);
@ -65,28 +65,10 @@ public class ServletConfigException extends ServletException {
* *
* @param pCause the exception cause * @param pCause the exception cause
*/ */
public ServletConfigException(Throwable pCause) { public ServletConfigException(final Throwable pCause) {
super("Erorr in Servlet configuration: " + pCause.getMessage(), pCause); super("Error in Servlet configuration: " + pCause.getMessage(), pCause);
if (getCause() == null) { if (getCause() == null) {
initCause(pCause); initCause(pCause);
} }
} }
/**
* Gets the cause of this {@code ServletConfigException}.
*
* @return the cause, or {@code null} if unknown.
* @see #getRootCause()
*/
// public final Throwable getCause() {
// Throwable cause = super.getCause();
// return cause != null ? cause : super.getRootCause();
// }
/**
* @deprecated Use {@link #getCause()} instead.
*/
// public final Throwable getRootCause() {
// return getCause();
// }
} }

View File

@ -29,6 +29,7 @@
package com.twelvemonkeys.servlet; package com.twelvemonkeys.servlet;
import com.twelvemonkeys.lang.StringUtil; import com.twelvemonkeys.lang.StringUtil;
import com.twelvemonkeys.lang.Validate;
import javax.servlet.FilterConfig; import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
@ -52,7 +53,6 @@ class ServletConfigMapAdapter extends AbstractMap<String, String> implements Map
ServletConfig, FilterConfig, ServletContext ServletConfig, FilterConfig, ServletContext
} }
// private final boolean mIsServlet;
private final ConfigType mType; private final ConfigType mType;
private final ServletConfig mServletConfig; private final ServletConfig mServletConfig;
@ -62,23 +62,21 @@ class ServletConfigMapAdapter extends AbstractMap<String, String> implements Map
// Cache the entry set // Cache the entry set
private transient Set<Entry<String, String>> mEntrySet; private transient Set<Entry<String, String>> mEntrySet;
public ServletConfigMapAdapter(ServletConfig pConfig) { public ServletConfigMapAdapter(final ServletConfig pConfig) {
this(pConfig, ConfigType.ServletConfig); this(pConfig, ConfigType.ServletConfig);
} }
public ServletConfigMapAdapter(FilterConfig pConfig) { public ServletConfigMapAdapter(final FilterConfig pConfig) {
this(pConfig, ConfigType.FilterConfig); this(pConfig, ConfigType.FilterConfig);
} }
public ServletConfigMapAdapter(ServletContext pContext) { public ServletConfigMapAdapter(final ServletContext pContext) {
this(pContext, ConfigType.ServletContext); this(pContext, ConfigType.ServletContext);
} }
private ServletConfigMapAdapter(Object pConfig, ConfigType pType) { private ServletConfigMapAdapter(final Object pConfig, final ConfigType pType) {
if (pConfig == null) { // Could happen if client code invokes with null reference
// Could happen of client code invokes with null reference Validate.notNull(pConfig, "config");
throw new IllegalArgumentException("Config == null");
}
mType = pType; mType = pType;

View File

@ -7,17 +7,17 @@ import java.util.Enumeration;
import java.util.Iterator; import java.util.Iterator;
/** /**
* HeaderMap * ServletHeadersMapAdapter
* *
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a> * @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haku $ * @author last modified by $Author: haku $
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/SerlvetHeadersMapAdapter.java#1 $ * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/ServletHeadersMapAdapter.java#1 $
*/ */
class SerlvetHeadersMapAdapter extends AbstractServletMapAdapter { class ServletHeadersMapAdapter extends AbstractServletMapAdapter {
protected final HttpServletRequest mRequest; protected final HttpServletRequest mRequest;
public SerlvetHeadersMapAdapter(HttpServletRequest pRequest) { public ServletHeadersMapAdapter(HttpServletRequest pRequest) {
if (pRequest == null) { if (pRequest == null) {
throw new IllegalArgumentException("request == null"); throw new IllegalArgumentException("request == null");
} }

View File

@ -7,17 +7,17 @@ import java.util.Iterator;
import java.util.Enumeration; import java.util.Enumeration;
/** /**
* HeaderMap * ServletParametersMapAdapter
* *
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a> * @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haku $ * @author last modified by $Author: haku $
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/SerlvetParametersMapAdapter.java#1 $ * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/ServletParametersMapAdapter.java#1 $
*/ */
class SerlvetParametersMapAdapter extends AbstractServletMapAdapter { class ServletParametersMapAdapter extends AbstractServletMapAdapter {
protected final HttpServletRequest mRequest; protected final HttpServletRequest mRequest;
public SerlvetParametersMapAdapter(HttpServletRequest pRequest) { public ServletParametersMapAdapter(HttpServletRequest pRequest) {
if (pRequest == null) { if (pRequest == null) {
throw new IllegalArgumentException("request == null"); throw new IllegalArgumentException("request == null");
} }

View File

@ -37,15 +37,12 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import java.io.File; import java.io.File;
import java.io.PrintStream;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Date;
import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -61,52 +58,52 @@ import java.util.Map;
public final class ServletUtil { public final class ServletUtil {
/** /**
* "javax.servlet.include.request_uri" * {@code "javax.servlet.include.request_uri"}
*/ */
private final static String ATTRIB_INC_REQUEST_URI = "javax.servlet.include.request_uri"; private final static String ATTRIB_INC_REQUEST_URI = "javax.servlet.include.request_uri";
/** /**
* "javax.servlet.include.context_path" * {@code "javax.servlet.include.context_path"}
*/ */
private final static String ATTRIB_INC_CONTEXT_PATH = "javax.servlet.include.context_path"; private final static String ATTRIB_INC_CONTEXT_PATH = "javax.servlet.include.context_path";
/** /**
* "javax.servlet.include.servlet_path" * {@code "javax.servlet.include.servlet_path"}
*/ */
private final static String ATTRIB_INC_SERVLET_PATH = "javax.servlet.include.servlet_path"; private final static String ATTRIB_INC_SERVLET_PATH = "javax.servlet.include.servlet_path";
/** /**
* "javax.servlet.include.path_info" * {@code "javax.servlet.include.path_info"}
*/ */
private final static String ATTRIB_INC_PATH_INFO = "javax.servlet.include.path_info"; private final static String ATTRIB_INC_PATH_INFO = "javax.servlet.include.path_info";
/** /**
* "javax.servlet.include.query_string" * {@code "javax.servlet.include.query_string"}
*/ */
private final static String ATTRIB_INC_QUERY_STRING = "javax.servlet.include.query_string"; private final static String ATTRIB_INC_QUERY_STRING = "javax.servlet.include.query_string";
/** /**
* "javax.servlet.forward.request_uri" * {@code "javax.servlet.forward.request_uri"}
*/ */
private final static String ATTRIB_FWD_REQUEST_URI = "javax.servlet.forward.request_uri"; private final static String ATTRIB_FWD_REQUEST_URI = "javax.servlet.forward.request_uri";
/** /**
* "javax.servlet.forward.context_path" * {@code "javax.servlet.forward.context_path"}
*/ */
private final static String ATTRIB_FWD_CONTEXT_PATH = "javax.servlet.forward.context_path"; private final static String ATTRIB_FWD_CONTEXT_PATH = "javax.servlet.forward.context_path";
/** /**
* "javax.servlet.forward.servlet_path" * {@code "javax.servlet.forward.servlet_path"}
*/ */
private final static String ATTRIB_FWD_SERVLET_PATH = "javax.servlet.forward.servlet_path"; private final static String ATTRIB_FWD_SERVLET_PATH = "javax.servlet.forward.servlet_path";
/** /**
* "javax.servlet.forward.path_info" * {@code "javax.servlet.forward.path_info"}
*/ */
private final static String ATTRIB_FWD_PATH_INFO = "javax.servlet.forward.path_info"; private final static String ATTRIB_FWD_PATH_INFO = "javax.servlet.forward.path_info";
/** /**
* "javax.servlet.forward.query_string" * {@code "javax.servlet.forward.query_string"}
*/ */
private final static String ATTRIB_FWD_QUERY_STRING = "javax.servlet.forward.query_string"; private final static String ATTRIB_FWD_QUERY_STRING = "javax.servlet.forward.query_string";
@ -126,10 +123,10 @@ public final class ServletUtil {
* @return the value of the parameter, or the default value, if the * @return the value of the parameter, or the default value, if the
* parameter is not set. * parameter is not set.
*/ */
public static String getParameter(ServletRequest pReq, String pName, String pDefault) { public static String getParameter(final ServletRequest pReq, final String pName, final String pDefault) {
String str = pReq.getParameter(pName); String str = pReq.getParameter(pName);
return ((str != null) ? str : pDefault); return str != null ? str : pDefault;
} }
/** /**
@ -148,13 +145,10 @@ public final class ServletUtil {
* non-{@code null} and not an instance of {@code pType} * non-{@code null} and not an instance of {@code pType}
* @throws NullPointerException if {@code pReq}, {@code pName} or * @throws NullPointerException if {@code pReq}, {@code pName} or
* {@code pType} is {@code null}. * {@code pType} is {@code null}.
* @todo Well, it's done. Need some thinking... * @todo Well, it's done. Need some thinking... We probably don't want default if conversion fails...
* @see Converter#toObject * @see Converter#toObject
*/ */
static <T> T getParameter(final ServletRequest pReq, final String pName, final Class<T> pType, final String pFormat, final T pDefault) {
// public static T getParameter<T>(ServletRequest pReq, String pName,
// String pFormat, T pDefault) {
static <T> T getParameter(ServletRequest pReq, String pName, Class<T> pType, String pFormat, T pDefault) {
// Test if pDefault is either null or instance of pType // Test if pDefault is either null or instance of pType
if (pDefault != null && !pType.isInstance(pDefault)) { if (pDefault != null && !pType.isInstance(pDefault)) {
throw new IllegalArgumentException("default value not instance of " + pType + ": " + pDefault.getClass()); throw new IllegalArgumentException("default value not instance of " + pType + ": " + pDefault.getClass());
@ -165,6 +159,7 @@ public final class ServletUtil {
if (str == null) { if (str == null) {
return pDefault; return pDefault;
} }
try { try {
return pType.cast(Converter.getInstance().toObject(str, pType, pFormat)); return pType.cast(Converter.getInstance().toObject(str, pType, pFormat));
} }
@ -175,20 +170,20 @@ public final class ServletUtil {
/** /**
* Gets the value of the given parameter from the request converted to * Gets the value of the given parameter from the request converted to
* a boolean. If the parameter is not set or not parseable, the default * a {@code boolean}.&nbsp;If the parameter is not set or not parseable, the default
* value is returned. * value is returned.
* *
* @param pReq the servlet request * @param pReq the servlet request
* @param pName the parameter name * @param pName the parameter name
* @param pDefault the default value * @param pDefault the default value
* @return the value of the parameter converted to a boolean, or the * @return the value of the parameter converted to a {@code boolean}, or the
* default value, if the parameter is not set. * default value, if the parameter is not set.
*/ */
public static boolean getBooleanParameter(ServletRequest pReq, String pName, boolean pDefault) { public static boolean getBooleanParameter(final ServletRequest pReq, final String pName, final boolean pDefault) {
String str = pReq.getParameter(pName); String str = pReq.getParameter(pName);
try { try {
return ((str != null) ? Boolean.valueOf(str) : pDefault); return str != null ? Boolean.valueOf(str) : pDefault;
} }
catch (NumberFormatException nfe) { catch (NumberFormatException nfe) {
return pDefault; return pDefault;
@ -197,20 +192,20 @@ public final class ServletUtil {
/** /**
* Gets the value of the given parameter from the request converted to * Gets the value of the given parameter from the request converted to
* an int.&nbsp;If the parameter is not set or not parseable, the default * an {@code int}.&nbsp;If the parameter is not set or not parseable, the default
* value is returned. * value is returned.
* *
* @param pReq the servlet request * @param pReq the servlet request
* @param pName the parameter name * @param pName the parameter name
* @param pDefault the default value * @param pDefault the default value
* @return the value of the parameter converted to an int, or the default * @return the value of the parameter converted to an {@code int}, or the default
* value, if the parameter is not set. * value, if the parameter is not set.
*/ */
public static int getIntParameter(ServletRequest pReq, String pName, int pDefault) { public static int getIntParameter(final ServletRequest pReq, final String pName, final int pDefault) {
String str = pReq.getParameter(pName); String str = pReq.getParameter(pName);
try { try {
return ((str != null) ? Integer.parseInt(str) : pDefault); return str != null ? Integer.parseInt(str) : pDefault;
} }
catch (NumberFormatException nfe) { catch (NumberFormatException nfe) {
return pDefault; return pDefault;
@ -219,20 +214,20 @@ public final class ServletUtil {
/** /**
* Gets the value of the given parameter from the request converted to * Gets the value of the given parameter from the request converted to
* an long.&nbsp;If the parameter is not set or not parseable, the default * an {@code long}.&nbsp;If the parameter is not set or not parseable, the default
* value is returned. * value is returned.
* *
* @param pReq the servlet request * @param pReq the servlet request
* @param pName the parameter name * @param pName the parameter name
* @param pDefault the default value * @param pDefault the default value
* @return the value of the parameter converted to an long, or the default * @return the value of the parameter converted to an {@code long}, or the default
* value, if the parameter is not set. * value, if the parameter is not set.
*/ */
public static long getLongParameter(ServletRequest pReq, String pName, long pDefault) { public static long getLongParameter(final ServletRequest pReq, final String pName, final long pDefault) {
String str = pReq.getParameter(pName); String str = pReq.getParameter(pName);
try { try {
return ((str != null) ? Long.parseLong(str) : pDefault); return str != null ? Long.parseLong(str) : pDefault;
} }
catch (NumberFormatException nfe) { catch (NumberFormatException nfe) {
return pDefault; return pDefault;
@ -241,20 +236,20 @@ public final class ServletUtil {
/** /**
* Gets the value of the given parameter from the request converted to * Gets the value of the given parameter from the request converted to
* a float.&nbsp;If the parameter is not set or not parseable, the default * a {@code float}.&nbsp;If the parameter is not set or not parseable, the default
* value is returned. * value is returned.
* *
* @param pReq the servlet request * @param pReq the servlet request
* @param pName the parameter name * @param pName the parameter name
* @param pDefault the default value * @param pDefault the default value
* @return the value of the parameter converted to a float, or the default * @return the value of the parameter converted to a {@code float}, or the default
* value, if the parameter is not set. * value, if the parameter is not set.
*/ */
public static float getFloatParameter(ServletRequest pReq, String pName, float pDefault) { public static float getFloatParameter(final ServletRequest pReq, final String pName, final float pDefault) {
String str = pReq.getParameter(pName); String str = pReq.getParameter(pName);
try { try {
return ((str != null) ? Float.parseFloat(str) : pDefault); return str != null ? Float.parseFloat(str) : pDefault;
} }
catch (NumberFormatException nfe) { catch (NumberFormatException nfe) {
return pDefault; return pDefault;
@ -263,20 +258,20 @@ public final class ServletUtil {
/** /**
* Gets the value of the given parameter from the request converted to * Gets the value of the given parameter from the request converted to
* a double.&nbsp;If the parameter is not set or not parseable, the default * a {@code double}.&nbsp;If the parameter is not set or not parseable, the default
* value is returned. * value is returned.
* *
* @param pReq the servlet request * @param pReq the servlet request
* @param pName the parameter name * @param pName the parameter name
* @param pDefault the default value * @param pDefault the default value
* @return the value of the parameter converted to n double, or the default * @return the value of the parameter converted to n {@code double}, or the default
* value, if the parameter is not set. * value, if the parameter is not set.
*/ */
public static double getDoubleParameter(ServletRequest pReq, String pName, double pDefault) { public static double getDoubleParameter(final ServletRequest pReq, final String pName, final double pDefault) {
String str = pReq.getParameter(pName); String str = pReq.getParameter(pName);
try { try {
return ((str != null) ? Double.parseDouble(str) : pDefault); return str != null ? Double.parseDouble(str) : pDefault;
} }
catch (NumberFormatException nfe) { catch (NumberFormatException nfe) {
return pDefault; return pDefault;
@ -285,20 +280,20 @@ public final class ServletUtil {
/** /**
* Gets the value of the given parameter from the request converted to * Gets the value of the given parameter from the request converted to
* a Date.&nbsp;If the parameter is not set or not parseable, the * a {@code Date}.&nbsp;If the parameter is not set or not parseable, the
* default value is returned. * default value is returned.
* *
* @param pReq the servlet request * @param pReq the servlet request
* @param pName the parameter name * @param pName the parameter name
* @param pDefault the default value * @param pDefault the default value
* @return the value of the parameter converted to a Date, or the * @return the value of the parameter converted to a {@code Date}, or the
* default value, if the parameter is not set. * default value, if the parameter is not set.
* @see com.twelvemonkeys.lang.StringUtil#toDate(String) * @see com.twelvemonkeys.lang.StringUtil#toDate(String)
*/ */
public static long getDateParameter(ServletRequest pReq, String pName, long pDefault) { public static long getDateParameter(final ServletRequest pReq, final String pName, final long pDefault) {
String str = pReq.getParameter(pName); String str = pReq.getParameter(pName);
try { try {
return ((str != null) ? StringUtil.toDate(str).getTime() : pDefault); return str != null ? StringUtil.toDate(str).getTime() : pDefault;
} }
catch (IllegalArgumentException iae) { catch (IllegalArgumentException iae) {
return pDefault; return pDefault;
@ -341,7 +336,7 @@ public final class ServletUtil {
* @deprecated Use {@link javax.servlet.http.HttpServletRequest#getRequestURL()} * @deprecated Use {@link javax.servlet.http.HttpServletRequest#getRequestURL()}
* instead. * instead.
*/ */
static StringBuffer buildHTTPURL(HttpServletRequest pRequest) { static StringBuffer buildHTTPURL(final HttpServletRequest pRequest) {
StringBuffer resultURL = new StringBuffer(); StringBuffer resultURL = new StringBuffer();
// Scheme, as in http, https, ftp etc // Scheme, as in http, https, ftp etc
@ -381,7 +376,7 @@ public final class ServletUtil {
* @see HttpServletRequest#getRequestURI * @see HttpServletRequest#getRequestURI
* @since Servlet 2.2 * @since Servlet 2.2
*/ */
public static String getIncludeRequestURI(ServletRequest pRequest) { public static String getIncludeRequestURI(final ServletRequest pRequest) {
return (String) pRequest.getAttribute(ATTRIB_INC_REQUEST_URI); return (String) pRequest.getAttribute(ATTRIB_INC_REQUEST_URI);
} }
@ -395,7 +390,7 @@ public final class ServletUtil {
* @see HttpServletRequest#getContextPath * @see HttpServletRequest#getContextPath
* @since Servlet 2.2 * @since Servlet 2.2
*/ */
public static String getIncludeContextPath(ServletRequest pRequest) { public static String getIncludeContextPath(final ServletRequest pRequest) {
return (String) pRequest.getAttribute(ATTRIB_INC_CONTEXT_PATH); return (String) pRequest.getAttribute(ATTRIB_INC_CONTEXT_PATH);
} }
@ -409,7 +404,7 @@ public final class ServletUtil {
* @see HttpServletRequest#getServletPath * @see HttpServletRequest#getServletPath
* @since Servlet 2.2 * @since Servlet 2.2
*/ */
public static String getIncludeServletPath(ServletRequest pRequest) { public static String getIncludeServletPath(final ServletRequest pRequest) {
return (String) pRequest.getAttribute(ATTRIB_INC_SERVLET_PATH); return (String) pRequest.getAttribute(ATTRIB_INC_SERVLET_PATH);
} }
@ -423,7 +418,7 @@ public final class ServletUtil {
* @see HttpServletRequest#getPathInfo * @see HttpServletRequest#getPathInfo
* @since Servlet 2.2 * @since Servlet 2.2
*/ */
public static String getIncludePathInfo(ServletRequest pRequest) { public static String getIncludePathInfo(final ServletRequest pRequest) {
return (String) pRequest.getAttribute(ATTRIB_INC_PATH_INFO); return (String) pRequest.getAttribute(ATTRIB_INC_PATH_INFO);
} }
@ -437,7 +432,7 @@ public final class ServletUtil {
* @see HttpServletRequest#getQueryString * @see HttpServletRequest#getQueryString
* @since Servlet 2.2 * @since Servlet 2.2
*/ */
public static String getIncludeQueryString(ServletRequest pRequest) { public static String getIncludeQueryString(final ServletRequest pRequest) {
return (String) pRequest.getAttribute(ATTRIB_INC_QUERY_STRING); return (String) pRequest.getAttribute(ATTRIB_INC_QUERY_STRING);
} }
@ -451,7 +446,7 @@ public final class ServletUtil {
* @see HttpServletRequest#getRequestURI * @see HttpServletRequest#getRequestURI
* @since Servlet 2.4 * @since Servlet 2.4
*/ */
public static String getForwardRequestURI(ServletRequest pRequest) { public static String getForwardRequestURI(final ServletRequest pRequest) {
return (String) pRequest.getAttribute(ATTRIB_FWD_REQUEST_URI); return (String) pRequest.getAttribute(ATTRIB_FWD_REQUEST_URI);
} }
@ -465,7 +460,7 @@ public final class ServletUtil {
* @see HttpServletRequest#getContextPath * @see HttpServletRequest#getContextPath
* @since Servlet 2.4 * @since Servlet 2.4
*/ */
public static String getForwardContextPath(ServletRequest pRequest) { public static String getForwardContextPath(final ServletRequest pRequest) {
return (String) pRequest.getAttribute(ATTRIB_FWD_CONTEXT_PATH); return (String) pRequest.getAttribute(ATTRIB_FWD_CONTEXT_PATH);
} }
@ -479,7 +474,7 @@ public final class ServletUtil {
* @see HttpServletRequest#getServletPath * @see HttpServletRequest#getServletPath
* @since Servlet 2.4 * @since Servlet 2.4
*/ */
public static String getForwardServletPath(ServletRequest pRequest) { public static String getForwardServletPath(final ServletRequest pRequest) {
return (String) pRequest.getAttribute(ATTRIB_FWD_SERVLET_PATH); return (String) pRequest.getAttribute(ATTRIB_FWD_SERVLET_PATH);
} }
@ -493,7 +488,7 @@ public final class ServletUtil {
* @see HttpServletRequest#getPathInfo * @see HttpServletRequest#getPathInfo
* @since Servlet 2.4 * @since Servlet 2.4
*/ */
public static String getForwardPathInfo(ServletRequest pRequest) { public static String getForwardPathInfo(final ServletRequest pRequest) {
return (String) pRequest.getAttribute(ATTRIB_FWD_PATH_INFO); return (String) pRequest.getAttribute(ATTRIB_FWD_PATH_INFO);
} }
@ -507,7 +502,7 @@ public final class ServletUtil {
* @see HttpServletRequest#getQueryString * @see HttpServletRequest#getQueryString
* @since Servlet 2.4 * @since Servlet 2.4
*/ */
public static String getForwardQueryString(ServletRequest pRequest) { public static String getForwardQueryString(final ServletRequest pRequest) {
return (String) pRequest.getAttribute(ATTRIB_FWD_QUERY_STRING); return (String) pRequest.getAttribute(ATTRIB_FWD_QUERY_STRING);
} }
@ -519,7 +514,7 @@ public final class ServletUtil {
* @todo Read the spec, seems to be a mismatch with the Servlet API... * @todo Read the spec, seems to be a mismatch with the Servlet API...
* @see javax.servlet.http.HttpServletRequest#getServletPath() * @see javax.servlet.http.HttpServletRequest#getServletPath()
*/ */
static String getScriptName(HttpServletRequest pRequest) { static String getScriptName(final HttpServletRequest pRequest) {
String requestURI = pRequest.getRequestURI(); String requestURI = pRequest.getRequestURI();
return StringUtil.getLastElement(requestURI, "/"); return StringUtil.getLastElement(requestURI, "/");
} }
@ -536,11 +531,13 @@ public final class ServletUtil {
* @param pRequest the current HTTP request * @param pRequest the current HTTP request
* @return the request URI relative to the current context path. * @return the request URI relative to the current context path.
*/ */
public static String getContextRelativeURI(HttpServletRequest pRequest) { public static String getContextRelativeURI(final HttpServletRequest pRequest) {
String context = pRequest.getContextPath(); String context = pRequest.getContextPath();
if (!StringUtil.isEmpty(context)) { // "" for root context if (!StringUtil.isEmpty(context)) { // "" for root context
return pRequest.getRequestURI().substring(context.length()); return pRequest.getRequestURI().substring(context.length());
} }
return pRequest.getRequestURI(); return pRequest.getRequestURI();
} }
@ -557,12 +554,14 @@ public final class ServletUtil {
* @see ServletContext#getRealPath(java.lang.String) * @see ServletContext#getRealPath(java.lang.String)
* @see ServletContext#getResource(java.lang.String) * @see ServletContext#getResource(java.lang.String)
*/ */
public static URL getRealURL(ServletContext pContext, String pPath) throws MalformedURLException { public static URL getRealURL(final ServletContext pContext, final String pPath) throws MalformedURLException {
String realPath = pContext.getRealPath(pPath); String realPath = pContext.getRealPath(pPath);
if (realPath != null) { if (realPath != null) {
// NOTE: First convert to URI, as of Java 6 File.toURL is deprecated // NOTE: First convert to URI, as of Java 6 File.toURL is deprecated
return new File(realPath).toURI().toURL(); return new File(realPath).toURI().toURL();
} }
return null; return null;
} }
@ -572,20 +571,19 @@ public final class ServletUtil {
* @param pContext the servlet context * @param pContext the servlet context
* @return the temp directory * @return the temp directory
*/ */
public static File getTempDir(ServletContext pContext) { public static File getTempDir(final ServletContext pContext) {
return (File) pContext.getAttribute("javax.servlet.context.tempdir"); return (File) pContext.getAttribute("javax.servlet.context.tempdir");
} }
/** /**
* Gets the identificator string containing the unique identifier assigned * Gets the unique identifier assigned to this session.
* to this session.
* The identifier is assigned by the servlet container and is implementation * The identifier is assigned by the servlet container and is implementation
* dependent. * dependent.
* *
* @param pRequest The HTTP servlet request object. * @param pRequest The HTTP servlet request object.
* @return the session Id * @return the session Id
*/ */
public static String getSessionId(HttpServletRequest pRequest) { public static String getSessionId(final HttpServletRequest pRequest) {
HttpSession session = pRequest.getSession(); HttpSession session = pRequest.getSession();
return (session != null) ? session.getId() : null; return (session != null) ? session.getId() : null;
@ -598,11 +596,11 @@ public final class ServletUtil {
* operations and iterating over it's {@code keySet}. * operations and iterating over it's {@code keySet}.
* For other operations it may not perform well.</small> * For other operations it may not perform well.</small>
* *
* @param pConfig the serlvet configuration * @param pConfig the servlet configuration
* @return a {@code Map} view of the config * @return a {@code Map} view of the config
* @throws IllegalArgumentException if {@code pConfig} is {@code null} * @throws IllegalArgumentException if {@code pConfig} is {@code null}
*/ */
public static Map<String, String> asMap(ServletConfig pConfig) { public static Map<String, String> asMap(final ServletConfig pConfig) {
return new ServletConfigMapAdapter(pConfig); return new ServletConfigMapAdapter(pConfig);
} }
@ -617,7 +615,7 @@ public final class ServletUtil {
* @return a {@code Map} view of the config * @return a {@code Map} view of the config
* @throws IllegalArgumentException if {@code pConfig} is {@code null} * @throws IllegalArgumentException if {@code pConfig} is {@code null}
*/ */
public static Map<String, String> asMap(FilterConfig pConfig) { public static Map<String, String> asMap(final FilterConfig pConfig) {
return new ServletConfigMapAdapter(pConfig); return new ServletConfigMapAdapter(pConfig);
} }
@ -636,6 +634,13 @@ public final class ServletUtil {
return new ServletConfigMapAdapter(pContext); return new ServletConfigMapAdapter(pContext);
} }
// TODO?
// public static Map<String, ?> attributesAsMap(final ServletContext pContext) {
// }
//
// public static Map<String, ?> attributesAsMap(final ServletRequest pRequest) {
// }
//
/** /**
* Creates an unmodifiable {@code Map} view of the given * Creates an unmodifiable {@code Map} view of the given
* {@code HttpServletRequest}s request parameters. * {@code HttpServletRequest}s request parameters.
@ -645,7 +650,7 @@ public final class ServletUtil {
* @throws IllegalArgumentException if {@code pRequest} is {@code null} * @throws IllegalArgumentException if {@code pRequest} is {@code null}
*/ */
public static Map<String, List<String>> parametersAsMap(final HttpServletRequest pRequest) { public static Map<String, List<String>> parametersAsMap(final HttpServletRequest pRequest) {
return new SerlvetParametersMapAdapter(pRequest); return new ServletParametersMapAdapter(pRequest);
} }
/** /**
@ -657,7 +662,7 @@ public final class ServletUtil {
* @throws IllegalArgumentException if {@code pRequest} is {@code null} * @throws IllegalArgumentException if {@code pRequest} is {@code null}
*/ */
public static Map<String, List<String>> headersAsMap(final HttpServletRequest pRequest) { public static Map<String, List<String>> headersAsMap(final HttpServletRequest pRequest) {
return new SerlvetHeadersMapAdapter(pRequest); return new ServletHeadersMapAdapter(pRequest);
} }
/** /**
@ -700,329 +705,22 @@ public final class ServletUtil {
return pImplementation; return pImplementation;
} }
/**
* Prints the init parameters in a {@code javax.servlet.ServletConfig}
* object to a {@code java.io.PrintStream}.
* <p/>
*
* @param pServletConfig The Servlet Config object.
* @param pPrintStream The {@code java.io.PrintStream} for flushing
* the results.
*/
public static void printDebug(final ServletConfig pServletConfig, final PrintStream pPrintStream) {
Enumeration parameterNames = pServletConfig.getInitParameterNames();
while (parameterNames.hasMoreElements()) {
String initParameterName = (String) parameterNames.nextElement();
pPrintStream.println(initParameterName + ": " + pServletConfig.getInitParameter(initParameterName));
}
}
/**
* Prints the init parameters in a {@code javax.servlet.ServletConfig}
* object to {@code System.out}.
*
* @param pServletConfig the Servlet Config object.
*/
public static void printDebug(final ServletConfig pServletConfig) {
printDebug(pServletConfig, System.out);
}
/**
* Prints the init parameters in a {@code javax.servlet.ServletContext}
* object to a {@code java.io.PrintStream}.
*
* @param pServletContext the Servlet Context object.
* @param pPrintStream the {@code java.io.PrintStream} for flushing the
* results.
*/
public static void printDebug(final ServletContext pServletContext, final PrintStream pPrintStream) {
Enumeration parameterNames = pServletContext.getInitParameterNames();
while (parameterNames.hasMoreElements()) {
String initParameterName = (String) parameterNames.nextElement();
pPrintStream.println(initParameterName + ": " + pServletContext.getInitParameter(initParameterName));
}
}
/**
* Prints the init parameters in a {@code javax.servlet.ServletContext}
* object to {@code System.out}.
*
* @param pServletContext The Servlet Context object.
*/
public static void printDebug(final ServletContext pServletContext) {
printDebug(pServletContext, System.out);
}
/**
* Prints an excerpt of the residing information in a
* {@code javax.servlet.http.HttpServletRequest} object to a
* {@code java.io.PrintStream}.
*
* @param pRequest The HTTP servlet request object.
* @param pPrintStream The {@code java.io.PrintStream} for flushing
* the results.
*/
public static void printDebug(final HttpServletRequest pRequest, final PrintStream pPrintStream) {
String indentation = " ";
StringBuilder buffer = new StringBuilder();
// Returns the name of the authentication scheme used to protect the
// servlet, for example, "BASIC" or "SSL," or null if the servlet was
// not protected.
buffer.append(indentation);
buffer.append("Authentication scheme: ");
buffer.append(pRequest.getAuthType());
buffer.append("\n");
// Returns the portion of the request URI that indicates the context
// of the request.
buffer.append(indentation);
buffer.append("Context path: ");
buffer.append(pRequest.getContextPath());
buffer.append("\n");
// Returns an enumeration of all the header mNames this request contains.
buffer.append(indentation);
buffer.append("Header:");
buffer.append("\n");
Enumeration headerNames = pRequest.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerElement = (String) headerNames.nextElement();
buffer.append(indentation);
buffer.append(indentation);
buffer.append(headerElement);
buffer.append(": ");
buffer.append(pRequest.getHeader(headerElement));
buffer.append("\n");
}
// Returns the name of the HTTP method with which this request was made,
// for example, GET, POST, or PUT.
buffer.append(indentation);
buffer.append("HTTP method: ");
buffer.append(pRequest.getMethod());
buffer.append("\n");
// Returns any extra path information associated with the URL the client
// sent when it made this request.
buffer.append(indentation);
buffer.append("Extra path information from client: ");
buffer.append(pRequest.getPathInfo());
buffer.append("\n");
// Returns any extra path information after the servlet name but before
// the query string, and translates it to a real path.
buffer.append(indentation);
buffer.append("Extra translated path information from client: ");
buffer.append(pRequest.getPathTranslated());
buffer.append("\n");
// Returns the login of the user making this request, if the user has
// been authenticated, or null if the user has not been authenticated.
buffer.append(indentation);
String userInfo = pRequest.getRemoteUser();
if (StringUtil.isEmpty(userInfo)) {
buffer.append("User is not authenticated");
}
else {
buffer.append("User logint: ");
buffer.append(userInfo);
}
buffer.append("\n");
// Returns the session ID specified by the client.
buffer.append(indentation);
buffer.append("Session ID from client: ");
buffer.append(pRequest.getRequestedSessionId());
buffer.append("\n");
// Returns the server name.
buffer.append(indentation);
buffer.append("Server name: ");
buffer.append(pRequest.getServerName());
buffer.append("\n");
// Returns the part of this request's URL from the protocol name up
// to the query string in the first line of the HTTP request.
buffer.append(indentation);
buffer.append("Request URI: ").append(pRequest.getRequestURI());
buffer.append("\n");
// Returns the path info.
buffer.append(indentation);
buffer.append("Path information: ").append(pRequest.getPathInfo());
buffer.append("\n");
// Returns the part of this request's URL that calls the servlet.
buffer.append(indentation);
buffer.append("Servlet path: ").append(pRequest.getServletPath());
buffer.append("\n");
// Returns the query string that is contained in the request URL after
// the path.
buffer.append(indentation);
buffer.append("Query string: ").append(pRequest.getQueryString());
buffer.append("\n");
// Returns an enumeration of all the parameters bound to this request.
buffer.append(indentation);
buffer.append("Parameters:");
buffer.append("\n");
Enumeration parameterNames = pRequest.getParameterNames();
while (parameterNames.hasMoreElements()) {
String parameterName = (String) parameterNames.nextElement();
buffer.append(indentation);
buffer.append(indentation);
buffer.append(parameterName);
buffer.append(": ");
buffer.append(pRequest.getParameter(parameterName));
buffer.append("\n");
}
// Returns an enumeration of all the attribute objects bound to this
// request.
buffer.append(indentation);
buffer.append("Attributes:");
buffer.append("\n");
Enumeration attributeNames = pRequest.getAttributeNames();
while (attributeNames.hasMoreElements()) {
String attributeName = (String) attributeNames.nextElement();
buffer.append(indentation);
buffer.append(indentation);
buffer.append(attributeName);
buffer.append(": ");
buffer.append(pRequest.getAttribute(attributeName).toString());
buffer.append("\n");
}
pPrintStream.println(buffer.toString());
}
/**
* Prints an excerpt of the residing information in a
* {@code javax.servlet.http.HttpServletRequest} object to
* {@code System.out}.
*
* @param pRequest The HTTP servlet request object.
*/
public static void printDebug(final HttpServletRequest pRequest) {
printDebug(pRequest, System.out);
}
/**
* Prints an excerpt of a {@code javax.servlet.http.HttpSession} object
* to a {@code java.io.PrintStream}.
*
* @param pHttpSession The HTTP Session object.
* @param pPrintStream The {@code java.io.PrintStream} for flushing
* the results.
*/
public static void printDebug(final HttpSession pHttpSession, final PrintStream pPrintStream) {
String indentation = " ";
StringBuilder buffer = new StringBuilder();
if (pHttpSession == null) {
buffer.append(indentation);
buffer.append("No session object available");
buffer.append("\n");
}
else {
// Returns a string containing the unique identifier assigned to
//this session
buffer.append(indentation);
buffer.append("Session ID: ").append(pHttpSession.getId());
buffer.append("\n");
// Returns the last time the client sent a request associated with
// this session, as the number of milliseconds since midnight
// January 1, 1970 GMT, and marked by the time the container
// recieved the request
buffer.append(indentation);
buffer.append("Last accessed time: ");
buffer.append(new Date(pHttpSession.getLastAccessedTime()));
buffer.append("\n");
// Returns the time when this session was created, measured in
// milliseconds since midnight January 1, 1970 GMT
buffer.append(indentation);
buffer.append("Creation time: ");
buffer.append(new Date(pHttpSession.getCreationTime()));
buffer.append("\n");
// Returns true if the client does not yet know about the session
// or if the client chooses not to join the session
buffer.append(indentation);
buffer.append("New session?: ");
buffer.append(pHttpSession.isNew());
buffer.append("\n");
// Returns the maximum time interval, in seconds, that the servlet
// container will keep this session open between client accesses
buffer.append(indentation);
buffer.append("Max inactive interval: ");
buffer.append(pHttpSession.getMaxInactiveInterval());
buffer.append("\n");
// Returns an enumeration of all the attribute objects bound to
// this session
buffer.append(indentation);
buffer.append("Attributes:");
buffer.append("\n");
Enumeration attributeNames = pHttpSession.getAttributeNames();
while (attributeNames.hasMoreElements()) {
String attributeName = (String) attributeNames.nextElement();
buffer.append(indentation);
buffer.append(indentation);
buffer.append(attributeName);
buffer.append(": ");
buffer.append(pHttpSession.getAttribute(attributeName).toString());
buffer.append("\n");
}
}
pPrintStream.println(buffer.toString());
}
/**
* Prints an excerpt of a {@code javax.servlet.http.HttpSession}
* object to {@code System.out}.
* <p/>
*
* @param pHttpSession The HTTP Session object.
*/
public static void printDebug(final HttpSession pHttpSession) {
printDebug(pHttpSession, System.out);
}
private static class HttpServletResponseHandler implements InvocationHandler { private static class HttpServletResponseHandler implements InvocationHandler {
private ServletResponse mResponse; private final ServletResponseWrapper mResponse;
private HttpServletResponse mHttpResponse;
HttpServletResponseHandler(ServletResponseWrapper pResponse) { HttpServletResponseHandler(final ServletResponseWrapper pResponse) {
mResponse = pResponse; mResponse = pResponse;
mHttpResponse = (HttpServletResponse) pResponse.getResponse();
} }
public Object invoke(Object pProxy, Method pMethod, Object[] pArgs) throws Throwable { public Object invoke(final Object pProxy, final Method pMethod, final Object[] pArgs) throws Throwable {
try { try {
// TODO: Allow partial implementing?
if (pMethod.getDeclaringClass().isInstance(mResponse)) { if (pMethod.getDeclaringClass().isInstance(mResponse)) {
//System.out.println("Invoking " + pMethod + " on wrapper");
return pMethod.invoke(mResponse, pArgs); return pMethod.invoke(mResponse, pArgs);
} }
// Method is not implemented in wrapper // Method is not implemented in wrapper
//System.out.println("Invoking " + pMethod + " on wrapped object"); return pMethod.invoke(mResponse.getResponse(), pArgs);
return pMethod.invoke(mHttpResponse, pArgs);
} }
catch (InvocationTargetException e) { catch (InvocationTargetException e) {
// Unwrap, to avoid UndeclaredThrowableException... // Unwrap, to avoid UndeclaredThrowableException...
@ -1032,23 +730,21 @@ public final class ServletUtil {
} }
private static class HttpServletRequestHandler implements InvocationHandler { private static class HttpServletRequestHandler implements InvocationHandler {
private ServletRequest mRequest; private final ServletRequestWrapper mRequest;
private HttpServletRequest mHttpRequest;
HttpServletRequestHandler(ServletRequestWrapper pRequest) { HttpServletRequestHandler(final ServletRequestWrapper pRequest) {
mRequest = pRequest; mRequest = pRequest;
mHttpRequest = (HttpServletRequest) pRequest.getRequest();
} }
public Object invoke(Object pProxy, Method pMethod, Object[] pArgs) throws Throwable { public Object invoke(final Object pProxy, final Method pMethod, final Object[] pArgs) throws Throwable {
try { try {
// TODO: Allow partial implementing?
if (pMethod.getDeclaringClass().isInstance(mRequest)) { if (pMethod.getDeclaringClass().isInstance(mRequest)) {
//System.out.println("Invoking " + pMethod + " on wrapper");
return pMethod.invoke(mRequest, pArgs); return pMethod.invoke(mRequest, pArgs);
} }
// Method is not implemented in wrapper // Method is not implemented in wrapper
//System.out.println("Invoking " + pMethod + " on wrapped object"); return pMethod.invoke(mRequest.getRequest(), pArgs);
return pMethod.invoke(mHttpRequest, pArgs);
} }
catch (InvocationTargetException e) { catch (InvocationTargetException e) {
// Unwrap, to avoid UndeclaredThrowableException... // Unwrap, to avoid UndeclaredThrowableException...

View File

@ -33,6 +33,7 @@ import com.twelvemonkeys.lang.StringUtil;
import com.twelvemonkeys.servlet.GenericFilter; import com.twelvemonkeys.servlet.GenericFilter;
import javax.servlet.*; import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage; import java.awt.image.RenderedImage;
import java.io.IOException; import java.io.IOException;
@ -67,7 +68,7 @@ public abstract class ImageFilter extends GenericFilter {
* @throws IOException * @throws IOException
* @throws ServletException * @throws ServletException
*/ */
protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) protected void doFilterImpl(final ServletRequest pRequest, final ServletResponse pResponse, final FilterChain pChain)
throws IOException, ServletException { throws IOException, ServletException {
//System.out.println("Starting filtering..."); //System.out.println("Starting filtering...");
@ -78,19 +79,12 @@ public abstract class ImageFilter extends GenericFilter {
pChain.doFilter(pRequest, pResponse); pChain.doFilter(pRequest, pResponse);
} }
else { else {
// If already wrapped, the image will be encoded later in the chain
// Or, if this is first filter in chain, we must encode when done
boolean encode = !(pResponse instanceof ImageServletResponse);
// For images, we do post filtering only and need to wrap the response // For images, we do post filtering only and need to wrap the response
ImageServletResponse imageResponse; ImageServletResponse imageResponse = createImageServletResponse(pRequest, pResponse);
boolean encode;
if (pResponse instanceof ImageServletResponse) {
//System.out.println("Allready ImageServletResponse");
imageResponse = (ImageServletResponse) pResponse;
encode = false; // Allready wrapped, will be encoded later in the chain
}
else {
//System.out.println("Wrapping in ImageServletResponse");
imageResponse = new ImageServletResponseImpl(pRequest, pResponse, getServletContext());
encode = true; // This is first filter in chain, must encode when done
}
//System.out.println("Passing request on to next in chain..."); //System.out.println("Passing request on to next in chain...");
// Pass the request on // Pass the request on
@ -120,7 +114,7 @@ public abstract class ImageFilter extends GenericFilter {
if (encode) { if (encode) {
//System.out.println("Encoding image..."); //System.out.println("Encoding image...");
// Encode image to original repsonse // Encode image to original response
if (image != null) { if (image != null) {
// TODO: Be smarter than this... // TODO: Be smarter than this...
// TODO: Make sure ETag is same, if image content is the same... // TODO: Make sure ETag is same, if image content is the same...
@ -128,8 +122,9 @@ public abstract class ImageFilter extends GenericFilter {
// Use last modified of original response? Or keep original resource's, don't set at all? // Use last modified of original response? Or keep original resource's, don't set at all?
// TODO: Why weak ETag? // TODO: Why weak ETag?
String etag = "W/\"" + Integer.toHexString(hashCode()) + "-" + Integer.toHexString(image.hashCode()) + "\""; String etag = "W/\"" + Integer.toHexString(hashCode()) + "-" + Integer.toHexString(image.hashCode()) + "\"";
((ImageServletResponseImpl) imageResponse).setHeader("ETag", etag); // TODO: This breaks for wrapped instances, need to either unwrap or test for HttpSR...
((ImageServletResponseImpl) imageResponse).setDateHeader("Last-Modified", (System.currentTimeMillis() / 1000) * 1000); ((HttpServletResponse) pResponse).setHeader("ETag", etag);
((HttpServletResponse) pResponse).setDateHeader("Last-Modified", (System.currentTimeMillis() / 1000) * 1000);
imageResponse.flush(); imageResponse.flush();
} }
//System.out.println("Done encoding."); //System.out.println("Done encoding.");
@ -139,6 +134,25 @@ public abstract class ImageFilter extends GenericFilter {
//System.out.println("Filtering done."); //System.out.println("Filtering done.");
} }
/**
* Creates the image servlet response for this response.
*
* @param pResponse the original response
* @param pRequest the original request
* @return the new response, or {@code pResponse} if the response is already wrapped
*
* @see com.twelvemonkeys.servlet.image.ImageServletResponseWrapper
*/
private ImageServletResponse createImageServletResponse(final ServletRequest pRequest, final ServletResponse pResponse) {
if (pResponse instanceof ImageServletResponseImpl) {
ImageServletResponseImpl response = (ImageServletResponseImpl) pResponse;
// response.setRequest(pRequest);
return response;
}
return new ImageServletResponseImpl(pRequest, pResponse, getServletContext());
}
/** /**
* Tests if the filter should do image filtering/processing. * Tests if the filter should do image filtering/processing.
* <P/> * <P/>
@ -157,7 +171,7 @@ public abstract class ImageFilter extends GenericFilter {
* @param pRequest the servlet request * @param pRequest the servlet request
* @return {@code true} if the filter should do image filtering * @return {@code true} if the filter should do image filtering
*/ */
protected boolean trigger(ServletRequest pRequest) { protected boolean trigger(final ServletRequest pRequest) {
// If triggerParams not set, assume always trigger // If triggerParams not set, assume always trigger
if (mTriggerParams == null) { if (mTriggerParams == null) {
return true; return true;

View File

@ -70,9 +70,10 @@ import java.util.Iterator;
*/ */
// TODO: Refactor out HTTP specifcs (if possible). // TODO: Refactor out HTTP specifcs (if possible).
// TODO: Is it a good ide to throw IIOException? // TODO: Is it a good ide to throw IIOException?
// TODO: This implementation has a problem if two filters does scaling, as the second will overwrite the SIZE attribute
class ImageServletResponseImpl extends HttpServletResponseWrapper implements ImageServletResponse { class ImageServletResponseImpl extends HttpServletResponseWrapper implements ImageServletResponse {
private final ServletRequest mOriginalRequest; private ServletRequest mOriginalRequest;
private final ServletContext mContext; private final ServletContext mContext;
private final ServletResponseStreamDelegate mStreamDelegate; private final ServletResponseStreamDelegate mStreamDelegate;
@ -125,6 +126,10 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
this((HttpServletRequest) pRequest, (HttpServletResponse) pResponse, pContext); this((HttpServletRequest) pRequest, (HttpServletResponse) pResponse, pContext);
} }
public void setRequest(ServletRequest pRequest) {
mOriginalRequest = pRequest;
}
/** /**
* Called by the container, do not invoke. * Called by the container, do not invoke.
* *
@ -187,13 +192,6 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
getImage(); getImage();
} }
// For known formats that don't support transparency, convert to opaque
if (("image/jpeg".equals(outputType) || "image/jpg".equals(outputType)
|| "image/bmp".equals(outputType) || "image/x-bmp".equals(outputType)) &&
mImage.getColorModel().getTransparency() != Transparency.OPAQUE) {
mImage = ImageUtil.toBuffered(mImage, BufferedImage.TYPE_INT_RGB);
}
if (mImage != null) { if (mImage != null) {
Iterator writers = ImageIO.getImageWritersByMIMEType(outputType); Iterator writers = ImageIO.getImageWritersByMIMEType(outputType);
if (writers.hasNext()) { if (writers.hasNext()) {
@ -203,6 +201,12 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
ImageWriter writer = (ImageWriter) writers.next(); ImageWriter writer = (ImageWriter) writers.next();
try { try {
ImageWriteParam param = writer.getDefaultWriteParam(); ImageWriteParam param = writer.getDefaultWriteParam();
///////////////////
// POST-PROCESS
// For known formats that don't support transparency, convert to opaque
if (isNonAlphaFormat(outputType) && mImage.getColorModel().getTransparency() != Transparency.OPAQUE) {
mImage = ImageUtil.toBuffered(mImage, BufferedImage.TYPE_INT_RGB);
}
Float requestQuality = (Float) mOriginalRequest.getAttribute(ImageServletResponse.ATTRIB_OUTPUT_QUALITY); Float requestQuality = (Float) mOriginalRequest.getAttribute(ImageServletResponse.ATTRIB_OUTPUT_QUALITY);
@ -211,7 +215,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(requestQuality != null ? requestQuality : 0.8f); param.setCompressionQuality(requestQuality != null ? requestQuality : 0.8f);
} }
//////////////////
ImageOutputStream stream = ImageIO.createImageOutputStream(out); ImageOutputStream stream = ImageIO.createImageOutputStream(out);
writer.setOutput(stream); writer.setOutput(stream);
@ -244,6 +248,11 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
} }
} }
private boolean isNonAlphaFormat(String outputType) {
return "image/jpeg".equals(outputType) || "image/jpg".equals(outputType) ||
"image/bmp".equals(outputType) || "image/x-bmp".equals(outputType);
}
private String getFormatNameSafe(final ImageWriter pWriter) { private String getFormatNameSafe(final ImageWriter pWriter) {
try { try {
return pWriter.getOriginatingProvider().getFormatNames()[0]; return pWriter.getOriginatingProvider().getFormatNames()[0];
@ -304,18 +313,21 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
// Get default size // Get default size
int originalWidth = reader.getWidth(0); int originalWidth = reader.getWidth(0);
int originalHeight = reader.getHeight(0); int originalHeight = reader.getHeight(0);
//////////////////
// PRE-PROCESS (prepare): param, size, format?, request, response?
// TODO: AOI strategy?
// Extract AOI from request // Extract AOI from request
Rectangle aoi = extractAOIFromRequest(originalWidth, originalHeight); Rectangle aoi = extractAOIFromRequest(originalWidth, originalHeight, mOriginalRequest);
if (aoi != null) { if (aoi != null) {
param.setSourceRegion(aoi); param.setSourceRegion(aoi);
originalWidth = aoi.width; originalWidth = aoi.width;
originalHeight = aoi.height; originalHeight = aoi.height;
} }
// TODO: Size and subsampling strategy?
// If possible, extract size from request // If possible, extract size from request
Dimension size = extractSizeFromRequest(originalWidth, originalHeight); Dimension size = extractSizeFromRequest(originalWidth, originalHeight, mOriginalRequest);
double readSubSamplingFactor = getReadSubsampleFactorFromRequest(); double readSubSamplingFactor = getReadSubsampleFactorFromRequest(mOriginalRequest);
if (size != null) { if (size != null) {
//System.out.println("Size: " + size); //System.out.println("Size: " + size);
if (param.canSetSourceRenderSize()) { if (param.canSetSourceRenderSize()) {
@ -334,26 +346,16 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
// Need base URI for SVG with links/stylesheets etc // Need base URI for SVG with links/stylesheets etc
maybeSetBaseURIFromRequest(param); maybeSetBaseURIFromRequest(param);
/////////////////////
// Finally, read the image using the supplied parameter // Finally, read the image using the supplied parameter
BufferedImage image = reader.read(0, param); BufferedImage image = reader.read(0, param);
// If reader doesn't support dynamic sizing, scale now // If reader doesn't support dynamic sizing, scale now
if (image != null && size != null image = resampleImage(image, size);
&& (image.getWidth() != size.width || image.getHeight() != size.height)) {
int resampleAlgorithm = getResampleAlgorithmFromRequest();
// NOTE: Only use createScaled if IndexColorModel,
// as it's more expensive due to color conversion
if (image.getColorModel() instanceof IndexColorModel) {
image = ImageUtil.createScaled(image, size.width, size.height, resampleAlgorithm);
}
else {
image = ImageUtil.createResampled(image, size.width, size.height, resampleAlgorithm);
}
}
// Fill bgcolor behind image, if transparent // Fill bgcolor behind image, if transparent
extractAndSetBackgroundColor(image); extractAndSetBackgroundColor(image); // TODO: Move to flush/POST-PROCESS
// Set image // Set image
mImage = image; mImage = image;
@ -383,27 +385,38 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
return mImage != null ? ImageUtil.toBuffered(mImage) : null; return mImage != null ? ImageUtil.toBuffered(mImage) : null;
} }
private int getResampleAlgorithmFromRequest() { private BufferedImage resampleImage(final BufferedImage image, final Dimension size) {
int resampleAlgoithm; if (image != null && size != null && (image.getWidth() != size.width || image.getHeight() != size.height)) {
int resampleAlgorithm = getResampleAlgorithmFromRequest();
// NOTE: Only use createScaled if IndexColorModel, as it's more expensive due to color conversion
if (image.getColorModel() instanceof IndexColorModel) {
return ImageUtil.createScaled(image, size.width, size.height, resampleAlgorithm);
}
else {
return ImageUtil.createResampled(image, size.width, size.height, resampleAlgorithm);
}
}
return image;
}
private int getResampleAlgorithmFromRequest() {
Object algorithm = mOriginalRequest.getAttribute(ATTRIB_IMAGE_RESAMPLE_ALGORITHM); Object algorithm = mOriginalRequest.getAttribute(ATTRIB_IMAGE_RESAMPLE_ALGORITHM);
if (algorithm instanceof Integer && ((Integer) algorithm == Image.SCALE_SMOOTH || (Integer) algorithm == Image.SCALE_FAST || (Integer) algorithm == Image.SCALE_DEFAULT)) { if (algorithm instanceof Integer && ((Integer) algorithm == Image.SCALE_SMOOTH || (Integer) algorithm == Image.SCALE_FAST || (Integer) algorithm == Image.SCALE_DEFAULT)) {
resampleAlgoithm = (Integer) algorithm; return (Integer) algorithm;
} }
else { else {
if (algorithm != null) { if (algorithm != null) {
mContext.log("WARN: Illegal image resampling algorithm: " + algorithm); mContext.log("WARN: Illegal image resampling algorithm: " + algorithm);
} }
resampleAlgoithm = BufferedImage.SCALE_DEFAULT; return BufferedImage.SCALE_DEFAULT;
}
} }
return resampleAlgoithm; private double getReadSubsampleFactorFromRequest(final ServletRequest pOriginalRequest) {
}
private double getReadSubsampleFactorFromRequest() {
double subsampleFactor; double subsampleFactor;
Object factor = mOriginalRequest.getAttribute(ATTRIB_READ_SUBSAMPLING_FACTOR); Object factor = pOriginalRequest.getAttribute(ATTRIB_READ_SUBSAMPLING_FACTOR);
if (factor instanceof Number && ((Number) factor).doubleValue() >= 1.0) { if (factor instanceof Number && ((Number) factor).doubleValue() >= 1.0) {
subsampleFactor = ((Number) factor).doubleValue(); subsampleFactor = ((Number) factor).doubleValue();
} }
@ -411,6 +424,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
if (factor != null) { if (factor != null) {
mContext.log("WARN: Illegal read subsampling factor: " + factor); mContext.log("WARN: Illegal read subsampling factor: " + factor);
} }
subsampleFactor = 2.0; subsampleFactor = 2.0;
} }
@ -483,7 +497,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
} }
} }
private Dimension extractSizeFromRequest(final int pDefaultWidth, final int pDefaultHeight) { private Dimension extractSizeFromRequest(final int pDefaultWidth, final int pDefaultHeight, final ServletRequest pOriginalRequest) {
// TODO: Allow extraction from request parameters // TODO: Allow extraction from request parameters
/* /*
int sizeW = ServletUtil.getIntParameter(mOriginalRequest, "size.w", -1); int sizeW = ServletUtil.getIntParameter(mOriginalRequest, "size.w", -1);
@ -491,14 +505,14 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
boolean sizePercent = ServletUtil.getBooleanParameter(mOriginalRequest, "size.percent", false); boolean sizePercent = ServletUtil.getBooleanParameter(mOriginalRequest, "size.percent", false);
boolean sizeUniform = ServletUtil.getBooleanParameter(mOriginalRequest, "size.uniform", true); boolean sizeUniform = ServletUtil.getBooleanParameter(mOriginalRequest, "size.uniform", true);
*/ */
Dimension size = (Dimension) mOriginalRequest.getAttribute(ATTRIB_SIZE); Dimension size = (Dimension) pOriginalRequest.getAttribute(ATTRIB_SIZE);
int sizeW = size != null ? size.width : -1; int sizeW = size != null ? size.width : -1;
int sizeH = size != null ? size.height : -1; int sizeH = size != null ? size.height : -1;
Boolean b = (Boolean) mOriginalRequest.getAttribute(ATTRIB_SIZE_PERCENT); Boolean b = (Boolean) pOriginalRequest.getAttribute(ATTRIB_SIZE_PERCENT);
boolean sizePercent = b != null && b; // default: false boolean sizePercent = b != null && b; // default: false
b = (Boolean) mOriginalRequest.getAttribute(ATTRIB_SIZE_UNIFORM); b = (Boolean) pOriginalRequest.getAttribute(ATTRIB_SIZE_UNIFORM);
boolean sizeUniform = b == null || b; // default: true boolean sizeUniform = b == null || b; // default: true
if (sizeW >= 0 || sizeH >= 0) { if (sizeW >= 0 || sizeH >= 0) {
@ -508,7 +522,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
return size; return size;
} }
private Rectangle extractAOIFromRequest(final int pDefaultWidth, final int pDefaultHeight) { private Rectangle extractAOIFromRequest(final int pDefaultWidth, final int pDefaultHeight, final ServletRequest pOriginalRequest) {
// TODO: Allow extraction from request parameters // TODO: Allow extraction from request parameters
/* /*
int aoiX = ServletUtil.getIntParameter(mOriginalRequest, "aoi.x", -1); int aoiX = ServletUtil.getIntParameter(mOriginalRequest, "aoi.x", -1);
@ -518,16 +532,16 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
boolean aoiPercent = ServletUtil.getBooleanParameter(mOriginalRequest, "aoi.percent", false); boolean aoiPercent = ServletUtil.getBooleanParameter(mOriginalRequest, "aoi.percent", false);
boolean aoiUniform = ServletUtil.getBooleanParameter(mOriginalRequest, "aoi.uniform", false); boolean aoiUniform = ServletUtil.getBooleanParameter(mOriginalRequest, "aoi.uniform", false);
*/ */
Rectangle aoi = (Rectangle) mOriginalRequest.getAttribute(ATTRIB_AOI); Rectangle aoi = (Rectangle) pOriginalRequest.getAttribute(ATTRIB_AOI);
int aoiX = aoi != null ? aoi.x : -1; int aoiX = aoi != null ? aoi.x : -1;
int aoiY = aoi != null ? aoi.y : -1; int aoiY = aoi != null ? aoi.y : -1;
int aoiW = aoi != null ? aoi.width : -1; int aoiW = aoi != null ? aoi.width : -1;
int aoiH = aoi != null ? aoi.height : -1; int aoiH = aoi != null ? aoi.height : -1;
Boolean b = (Boolean) mOriginalRequest.getAttribute(ATTRIB_AOI_PERCENT); Boolean b = (Boolean) pOriginalRequest.getAttribute(ATTRIB_AOI_PERCENT);
boolean aoiPercent = b != null && b; // default: false boolean aoiPercent = b != null && b; // default: false
b = (Boolean) mOriginalRequest.getAttribute(ATTRIB_AOI_UNIFORM); b = (Boolean) pOriginalRequest.getAttribute(ATTRIB_AOI_UNIFORM);
boolean aoiUniform = b != null && b; // default: false boolean aoiUniform = b != null && b; // default: false
if (aoiX >= 0 || aoiY >= 0 || aoiW >= 0 || aoiH >= 0) { if (aoiX >= 0 || aoiY >= 0 || aoiW >= 0 || aoiH >= 0) {
@ -552,18 +566,18 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
* @param pHeight the new height of the image, or -1 if unknown * @param pHeight the new height of the image, or -1 if unknown
* @param pPercent the constant specifying units for width and height * @param pPercent the constant specifying units for width and height
* parameter (UNITS_PIXELS or UNITS_PERCENT) * parameter (UNITS_PIXELS or UNITS_PERCENT)
* @param pUniformScale boolean specifying uniform scale or not * @param pUniform boolean specifying uniform scale or not
* @return a Dimension object, with the correct width and heigth * @return a Dimension object, with the correct width and heigth
* in pixels, for the scaled version of the image. * in pixels, for the scaled version of the image.
*/ */
protected static Dimension getSize(int pOriginalWidth, int pOriginalHeight, static Dimension getSize(int pOriginalWidth, int pOriginalHeight,
int pWidth, int pHeight, int pWidth, int pHeight,
boolean pPercent, boolean pUniformScale) { boolean pPercent, boolean pUniform) {
// If uniform, make sure width and height are scaled the same ammount // If uniform, make sure width and height are scaled the same amount
// (use ONLY height or ONLY width). // (use ONLY height or ONLY width).
// //
// Algoritm: // Algorithm:
// if uniform // if uniform
// if newHeight not set // if newHeight not set
// find ratio newWidth / oldWidth // find ratio newWidth / oldWidth
@ -602,7 +616,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
// Else: No scale // Else: No scale
} }
else { else {
if (pUniformScale) { if (pUniform) {
if (pWidth >= 0 && pHeight >= 0) { if (pWidth >= 0 && pHeight >= 0) {
// Compute both ratios // Compute both ratios
ratio = (float) pWidth / (float) pOriginalWidth; ratio = (float) pWidth / (float) pOriginalWidth;
@ -616,7 +630,6 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
else { else {
pHeight = Math.round((float) pOriginalHeight * ratio); pHeight = Math.round((float) pOriginalHeight * ratio);
} }
} }
else if (pWidth >= 0) { else if (pWidth >= 0) {
// Find ratio from pWidth // Find ratio from pWidth
@ -644,10 +657,10 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
return new Dimension(pWidth, pHeight); return new Dimension(pWidth, pHeight);
} }
protected static Rectangle getAOI(int pOriginalWidth, int pOriginalHeight, static Rectangle getAOI(int pOriginalWidth, int pOriginalHeight,
int pX, int pY, int pWidth, int pHeight, int pX, int pY, int pWidth, int pHeight,
boolean pPercent, boolean pUniform) { boolean pPercent, boolean pMaximizeToAspect) {
// Algoritm: // Algorithm:
// Try to get x and y (default 0,0). // Try to get x and y (default 0,0).
// Try to get width and height (default width-x, height-y) // Try to get width and height (default width-x, height-y)
// //
@ -669,7 +682,6 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
ratio = (float) pWidth / 100f; ratio = (float) pWidth / 100f;
pWidth = Math.round((float) pOriginalWidth * ratio); pWidth = Math.round((float) pOriginalWidth * ratio);
pHeight = Math.round((float) pOriginalHeight * ratio); pHeight = Math.round((float) pOriginalHeight * ratio);
} }
else if (pHeight >= 0) { else if (pHeight >= 0) {
// Find ratio from pHeight // Find ratio from pHeight
@ -681,7 +693,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
} }
else { else {
// Uniform // Uniform
if (pUniform) { if (pMaximizeToAspect) {
if (pWidth >= 0 && pHeight >= 0) { if (pWidth >= 0 && pHeight >= 0) {
// Compute both ratios // Compute both ratios
ratio = (float) pWidth / (float) pHeight; ratio = (float) pWidth / (float) pHeight;

View File

@ -2,19 +2,18 @@ package com.twelvemonkeys.servlet.log4j;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.util.Enumeration;
import java.util.Set;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.InputStream;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import javax.servlet.ServletContext;
import javax.servlet.RequestDispatcher; import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet; import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Set;
/** /**
* Log4JContextWrapper * Log4JContextWrapper
@ -24,6 +23,7 @@ import javax.servlet.ServletException;
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/log4j/Log4JContextWrapper.java#1 $ * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/log4j/Log4JContextWrapper.java#1 $
*/ */
final class Log4JContextWrapper implements ServletContext { final class Log4JContextWrapper implements ServletContext {
// TODO: Move to sandbox
// TODO: This solution sucks... // TODO: This solution sucks...
// How about starting to create some kind of pluggable decorator system, // How about starting to create some kind of pluggable decorator system,
@ -32,7 +32,7 @@ final class Log4JContextWrapper implements ServletContext {
// wrapped object based on configuration. // wrapped object based on configuration.
// This way we could simply call ServletUtil.decorate(ServletContext):ServletContext // This way we could simply call ServletUtil.decorate(ServletContext):ServletContext
// And the context would be decorated with all configured mixins at once, // And the context would be decorated with all configured mixins at once,
// requiring less bolierplate delegation code, and less layers of wrapping // requiring less boilerplate delegation code, and less layers of wrapping
// (alternatively we could decorate the Servlet/FilterConfig objects). // (alternatively we could decorate the Servlet/FilterConfig objects).
// See the ServletUtil.createWrapper methods for some hints.. // See the ServletUtil.createWrapper methods for some hints..

View File

@ -47,7 +47,7 @@ public class ServletHeadersMapAdapterTestCase extends MapAbstractTestCase {
mockRequest.stubs().method("getHeaderNames").will(returnValue(Collections.enumeration(Collections.emptyList()))); mockRequest.stubs().method("getHeaderNames").will(returnValue(Collections.enumeration(Collections.emptyList())));
mockRequest.stubs().method("getHeaders").will(returnValue(null)); mockRequest.stubs().method("getHeaders").will(returnValue(null));
return new SerlvetHeadersMapAdapter((HttpServletRequest) mockRequest.proxy()); return new ServletHeadersMapAdapter((HttpServletRequest) mockRequest.proxy());
} }
@Override @Override
@ -60,7 +60,7 @@ public class ServletHeadersMapAdapterTestCase extends MapAbstractTestCase {
mockRequest.stubs().method("getHeaders").with(eq("X-Foo")).will(returnEnumeration(HEADER_VALUE_FOO)); mockRequest.stubs().method("getHeaders").with(eq("X-Foo")).will(returnEnumeration(HEADER_VALUE_FOO));
mockRequest.stubs().method("getHeaders").with(not(or(eq("Date"), or(eq("ETag"), eq("X-Foo"))))).will(returnValue(null)); mockRequest.stubs().method("getHeaders").with(not(or(eq("Date"), or(eq("ETag"), eq("X-Foo"))))).will(returnValue(null));
return new SerlvetHeadersMapAdapter((HttpServletRequest) mockRequest.proxy()); return new ServletHeadersMapAdapter((HttpServletRequest) mockRequest.proxy());
} }
@Override @Override

View File

@ -47,7 +47,7 @@ public class ServletParametersMapAdapterTestCase extends MapAbstractTestCase {
mockRequest.stubs().method("getParameterNames").will(returnValue(Collections.enumeration(Collections.emptyList()))); mockRequest.stubs().method("getParameterNames").will(returnValue(Collections.enumeration(Collections.emptyList())));
mockRequest.stubs().method("getParameterValues").will(returnValue(null)); mockRequest.stubs().method("getParameterValues").will(returnValue(null));
return new SerlvetParametersMapAdapter((HttpServletRequest) mockRequest.proxy()); return new ServletParametersMapAdapter((HttpServletRequest) mockRequest.proxy());
} }
@Override @Override
@ -60,7 +60,7 @@ public class ServletParametersMapAdapterTestCase extends MapAbstractTestCase {
mockRequest.stubs().method("getParameterValues").with(eq("foo")).will(returnValue(PARAM_VALUE_FOO.toArray(new String[PARAM_VALUE_FOO.size()]))); mockRequest.stubs().method("getParameterValues").with(eq("foo")).will(returnValue(PARAM_VALUE_FOO.toArray(new String[PARAM_VALUE_FOO.size()])));
mockRequest.stubs().method("getParameterValues").with(not(or(eq("date"), or(eq("tag"), eq("foo"))))).will(returnValue(null)); mockRequest.stubs().method("getParameterValues").with(not(or(eq("date"), or(eq("tag"), eq("foo"))))).will(returnValue(null));
return new SerlvetParametersMapAdapter((HttpServletRequest) mockRequest.proxy()); return new ServletParametersMapAdapter((HttpServletRequest) mockRequest.proxy());
} }
@Override @Override

View File

@ -126,6 +126,7 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase {
// Test that wrapper works as a no-op, in case the image does not need to be decoded // Test that wrapper works as a no-op, in case the image does not need to be decoded
// This is not a very common use case, as filters should avoid wrapping the response // This is not a very common use case, as filters should avoid wrapping the response
// for performance reasons, but we still want that to work // for performance reasons, but we still want that to work
public void testNoOpResponse() throws IOException { public void testNoOpResponse() throws IOException {
Mock mockResponse = mock(HttpServletResponse.class); Mock mockResponse = mock(HttpServletResponse.class);
mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG));
@ -147,6 +148,7 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase {
} }
// Transcode original PNG to JPEG with no other changes // Transcode original PNG to JPEG with no other changes
public void testTranscodeResponse() throws IOException { public void testTranscodeResponse() throws IOException {
Mock mockResponse = mock(HttpServletResponse.class); Mock mockResponse = mock(HttpServletResponse.class);
mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_JPEG)); mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_JPEG));
@ -325,6 +327,7 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase {
// More? // More?
// Make sure we don't change semantics here... // Make sure we don't change semantics here...
public void testNotFoundInput() throws IOException { public void testNotFoundInput() throws IOException {
// Need speical setup // Need speical setup
Mock mockRequest = mock(HttpServletRequest.class); Mock mockRequest = mock(HttpServletRequest.class);
@ -343,6 +346,7 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase {
} }
// NOTE: This means it's up to some Filter to decide wether we should filter the given request // NOTE: This means it's up to some Filter to decide wether we should filter the given request
public void testUnsupportedInput() throws IOException { public void testUnsupportedInput() throws IOException {
assertFalse("Test is invalid, rewrite test", ImageIO.getImageReadersByFormatName("txt").hasNext()); assertFalse("Test is invalid, rewrite test", ImageIO.getImageReadersByFormatName("txt").hasNext());
@ -409,7 +413,6 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase {
// For example: Read a PNG with transparency and store as B/W WBMP // For example: Read a PNG with transparency and store as B/W WBMP
// TODO: Create ImageFilter test case, that tests normal use, as well as chaining // TODO: Create ImageFilter test case, that tests normal use, as well as chaining
@Test @Test
@ -997,6 +1000,7 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase {
// ----------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------
// Absolute AOI // Absolute AOI
// ----------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------
public void testGetAOIAbsolute() { public void testGetAOIAbsolute() {
assertEquals(new Rectangle(10, 10, 100, 100), ImageServletResponseImpl.getAOI(200, 200, 10, 10, 100, 100, false, false)); assertEquals(new Rectangle(10, 10, 100, 100), ImageServletResponseImpl.getAOI(200, 200, 10, 10, 100, 100, false, false));
} }
@ -1020,6 +1024,7 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase {
// ----------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------
// Uniform AOI centered // Uniform AOI centered
// ----------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------
@Test @Test
public void testGetAOIUniformCenteredS2SUp() { public void testGetAOIUniformCenteredS2SUp() {
assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 333, 333, false, true)); assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 333, 333, false, true));
@ -1148,6 +1153,7 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase {
// ----------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------
// Absolute AOI centered // Absolute AOI centered
// ----------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------
@Test @Test
public void testGetAOICenteredS2SUp() { public void testGetAOICenteredS2SUp() {
assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 333, 333, false, false)); assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 333, 333, false, false));
@ -1303,4 +1309,7 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase {
assertEquals(new Rectangle(0, 0, 100, 200), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 200, false, false)); assertEquals(new Rectangle(0, 0, 100, 200), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 200, false, false));
} }
// TODO: Test percent
// TODO: Test getSize()...
} }