- * This default implementation uses {@link #triggerParams} to test if:
- *
- * as parameter?
- public void setTriggerParams(final String pTriggerParams) {
- triggerParams = StringUtil.toStringArray(pTriggerParams);
- }
-
- /**
- * Filters the image for this request.
- *
- * @param pImage the image to filter
- * @param pRequest the servlet request
- * @param pResponse the servlet response
- *
- * @return the filtered image
- * @throws java.io.IOException if an I/O error occurs during filtering
- */
- protected abstract RenderedImage doFilter(BufferedImage pImage, ServletRequest pRequest, ImageServletResponse pResponse) throws IOException;
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletException.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletException.java
deleted file mode 100755
index e952449b..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletException.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image;
-
-import javax.servlet.ServletException;
-
-/**
- * This exception is a subclass of ServletException, and acts just as a marker
- * for exceptions thrown by the ImageServlet API.
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- *
- * @version $Id: ImageServletException.java#2 $
- */
-@Deprecated
-public class ImageServletException extends ServletException {
-
- public ImageServletException(String pMessage) {
- super(pMessage);
- }
-
- public ImageServletException(Throwable pThrowable) {
- super(pThrowable);
- }
-
- public ImageServletException(String pMessage, Throwable pThrowable) {
- super(pMessage, pThrowable);
- }
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletResponse.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletResponse.java
deleted file mode 100755
index 2ef7e17f..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletResponse.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-import java.io.IOException;
-
-import javax.servlet.ServletResponse;
-
-/**
- * ImageServletResponse.
- *
- * The request attributes regarding image size and source region (AOI) are used
- * in the decoding process, and must be set before the first invocation of
- * {@link #getImage()} to have any effect.
- *
- *
- * @author Harald Kuhr
- * @version $Id: ImageServletResponse.java#4 $
- */
-@Deprecated
-public interface ImageServletResponse extends ServletResponse {
- /**
- * Request attribute of type {@link java.awt.Dimension} controlling image
- * size.
- * If either {@code width} or {@code height} is negative, the size is
- * computed, using uniform scaling.
- * Else, if {@code SIZE_UNIFORM} is {@code true}, the size will be
- * computed to the largest possible area (with correct aspect ratio)
- * fitting inside the target area.
- * Otherwise, the image is scaled to the given size, with no regard to
- * aspect ratio.
- *
- * Defaults to {@code null} (original image size).
- *
- */
- String ATTRIB_SIZE = "com.twelvemonkeys.servlet.image.ImageServletResponse.SIZE";
-
- /**
- * Request attribute of type {@link Boolean} controlling image sizing.
- *
- * Defaults to {@code Boolean.TRUE}.
- *
- */
- String ATTRIB_SIZE_UNIFORM = "com.twelvemonkeys.servlet.image.ImageServletResponse.SIZE_UNIFORM";
-
- /**
- * Request attribute of type {@link Boolean} controlling image sizing.
- *
- * Defaults to {@code Boolean.FALSE}.
- *
- */
- String ATTRIB_SIZE_PERCENT = "com.twelvemonkeys.servlet.image.ImageServletResponse.SIZE_PERCENT";
-
- /**
- * Request attribute of type {@link java.awt.Rectangle} controlling image
- * source region (area of interest).
- *
- * Defaults to {@code null} (the entire image).
- *
- */
- String ATTRIB_AOI = "com.twelvemonkeys.servlet.image.ImageServletResponse.AOI";
-
- /**
- * Request attribute of type {@link Boolean} controlling image AOI.
- *
- * Defaults to {@code Boolean.FALSE}.
- *
- */
- String ATTRIB_AOI_UNIFORM = "com.twelvemonkeys.servlet.image.ImageServletResponse.AOI_UNIFORM";
-
- /**
- * Request attribute of type {@link Boolean} controlling image AOI.
- *
- * Defaults to {@code Boolean.FALSE}.
- *
- */
- String ATTRIB_AOI_PERCENT = "com.twelvemonkeys.servlet.image.ImageServletResponse.AOI_PERCENT";
-
- /**
- * Request attribute of type {@link java.awt.Color} controlling background
- * color for any transparent/translucent areas of the image.
- *
- * Defaults to {@code null} (keeps the transparent areas transparent).
- *
- */
- String ATTRIB_BG_COLOR = "com.twelvemonkeys.servlet.image.ImageServletResponse.BG_COLOR";
-
- /**
- * Request attribute of type {@link Float} controlling image output compression/quality.
- * Used for formats that accepts compression or quality settings,
- * like JPEG (quality), PNG (compression only) etc.
- *
- * Defaults to {@code 0.8f} for JPEG.
- *
- */
- String ATTRIB_OUTPUT_QUALITY = "com.twelvemonkeys.servlet.image.ImageServletResponse.OUTPUT_QUALITY";
-
- /**
- * Request attribute of type {@link Double} controlling image read
- * subsampling factor. Controls the maximum sample pixels in each direction,
- * that is read per pixel in the output image, if the result will be
- * downscaled.
- * Larger values will result in better quality, at the expense of higher
- * memory consumption and CPU usage.
- * However, using values above {@code 3.0} will usually not improve image
- * quality.
- * Legal values are in the range {@code [1.0 .. positive infinity>}.
- *
- * Defaults to {@code 2.0}.
- *
- */
- String ATTRIB_READ_SUBSAMPLING_FACTOR = "com.twelvemonkeys.servlet.image.ImageServletResponse.READ_SUBSAMPLING_FACTOR";
-
- /**
- * Request attribute of type {@link Integer} controlling image resample
- * algorithm.
- * Legal values are {@link java.awt.Image#SCALE_DEFAULT SCALE_DEFAULT},
- * {@link java.awt.Image#SCALE_FAST SCALE_FAST} or
- * {@link java.awt.Image#SCALE_SMOOTH SCALE_SMOOTH}.
- *
- * Note: When using a value of {@code SCALE_FAST}, you should also use a
- * subsampling factor of {@code 1.0}, for fast read/scale.
- * Otherwise, use a subsampling factor of {@code 2.0} for better quality.
- *
- *
- * Defaults to {@code SCALE_DEFAULT}.
- *
- */
- String ATTRIB_IMAGE_RESAMPLE_ALGORITHM = "com.twelvemonkeys.servlet.image.ImageServletResponse.IMAGE_RESAMPLE_ALGORITHM";
-
- /**
- * Gets the image format for this response, such as "image/gif" or "image/jpeg".
- * If not set, the default format is that of the original image.
- *
- * @return the image format for this response.
- * @see #setOutputContentType(String)
- */
- String getOutputContentType();
-
- /**
- * Sets the image format for this response, such as "image/gif" or "image/jpeg".
- *
- * As an example, a custom filter could do content negotiation based on the
- * request header fields and write the image back in an appropriate format.
- *
- *
- * If not set, the default format is that of the original image.
- *
- *
- * @param pImageFormat the image format for this response.
- */
- void setOutputContentType(String pImageFormat);
-
- //TODO: ?? void setCompressionQuality(float pQualityFactor);
- //TODO: ?? float getCompressionQuality();
-
- /**
- * Writes the image to the original {@code ServletOutputStream}.
- * If no format is {@linkplain #setOutputContentType(String) set} in this response,
- * the image is encoded in the same format as the original image.
- *
- * @throws java.io.IOException if an I/O exception occurs during writing
- */
- void flush() throws IOException;
-
- /**
- * Gets the decoded image from the response.
- *
- * @return a {@code BufferedImage} or {@code null} if the image could not be read.
- *
- * @throws java.io.IOException if an I/O exception occurs during reading
- */
- BufferedImage getImage() throws IOException;
-
- /**
- * Sets the image for this response.
- *
- * @param pImage the new response image.
- */
- void setImage(RenderedImage pImage);
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletResponseImpl.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletResponseImpl.java
deleted file mode 100755
index 813058ae..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletResponseImpl.java
+++ /dev/null
@@ -1,815 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image;
-
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.awt.image.IndexColorModel;
-import java.awt.image.RenderedImage;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.Iterator;
-
-import javax.imageio.IIOException;
-import javax.imageio.IIOImage;
-import javax.imageio.ImageIO;
-import javax.imageio.ImageReadParam;
-import javax.imageio.ImageReader;
-import javax.imageio.ImageWriteParam;
-import javax.imageio.ImageWriter;
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.stream.ImageOutputStream;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletResponseWrapper;
-
-import com.twelvemonkeys.image.ImageUtil;
-import com.twelvemonkeys.io.FastByteArrayOutputStream;
-import com.twelvemonkeys.lang.StringUtil;
-import com.twelvemonkeys.servlet.ServletResponseStreamDelegate;
-import com.twelvemonkeys.servlet.ServletUtil;
-import com.twelvemonkeys.servlet.image.aoi.AreaOfInterest;
-import com.twelvemonkeys.servlet.image.aoi.AreaOfInterestFactory;
-
-/**
- * This {@link ImageServletResponse} implementation can be used with image
- * requests, to have the image immediately decoded to a {@code BufferedImage}.
- * The image may be optionally subsampled, scaled and/or cropped.
- * The response also automatically handles writing the image back to the underlying response stream
- * in the preferred format, when the response is flushed.
- *
- * @author Harald Kuhr
- * @version $Id: ImageServletResponseImpl.java#10 $
- */
-// TODO: Refactor out HTTP specifics (if possible).
-// 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
-// TODO: Allow different scaling algorithm based on input image (use case: IndexColorModel does not scale well using default, smooth may be slow for large images)
-// TODO: Support pluggable pre- and post-processing steps
-@Deprecated
-class ImageServletResponseImpl extends HttpServletResponseWrapper implements ImageServletResponse {
- private ServletRequest originalRequest;
- private final ServletContext context;
- private final ServletResponseStreamDelegate streamDelegate;
-
- private FastByteArrayOutputStream bufferedOut;
-
- private RenderedImage image;
- private String outputContentType;
-
- private String originalContentType;
- private int originalContentLength = -1;
-
- /**
- * Creates an {@code ImageServletResponseImpl}.
- *
- * @param pRequest the request
- * @param pResponse the response
- * @param pContext the servlet context
- */
- public ImageServletResponseImpl(final HttpServletRequest pRequest, final HttpServletResponse pResponse, final ServletContext pContext) {
- super(pResponse);
- originalRequest = pRequest;
- streamDelegate = new ServletResponseStreamDelegate(pResponse) {
- @Override
- protected OutputStream createOutputStream() throws IOException {
- if (originalContentLength >= 0) {
- bufferedOut = new FastByteArrayOutputStream(originalContentLength);
- }
- else {
- bufferedOut = new FastByteArrayOutputStream(0);
- }
-
- return bufferedOut;
- }
- };
- context = pContext;
- }
-
- /**
- * Creates an {@code ImageServletResponseImpl}.
- *
- * @param pRequest the request
- * @param pResponse the response
- * @param pContext the servlet context
- *
- * @throws ClassCastException if {@code pRequest} is not an {@link javax.servlet.http.HttpServletRequest} or
- * {@code pResponse} is not an {@link javax.servlet.http.HttpServletResponse}.
- */
- public ImageServletResponseImpl(final ServletRequest pRequest, final ServletResponse pResponse, final ServletContext pContext) {
- // Cheat for now...
- this((HttpServletRequest) pRequest, (HttpServletResponse) pResponse, pContext);
- }
-
- /**
- * Called by the container, do not invoke.
- *
- * @param pMimeType the content (MIME) type
- */
- public void setContentType(final String pMimeType) {
- // Throw exception is already set
- if (originalContentType != null) {
- throw new IllegalStateException("ContentType already set.");
- }
-
- originalContentType = pMimeType;
- }
-
- /**
- * Called by the container. Do not invoke.
- *
- * @return the response's {@code OutputStream}
- * @throws IOException
- */
- public ServletOutputStream getOutputStream() throws IOException {
- return streamDelegate.getOutputStream();
- }
-
- /**
- * Called by the container. Do not invoke.
- *
- * @return the response's {@code PrintWriter}
- * @throws IOException
- */
- public PrintWriter getWriter() throws IOException {
- return streamDelegate.getWriter();
- }
-
- /**
- * Called by the container. Do not invoke.
- *
- * @param pLength the content length
- */
- public void setContentLength(final int pLength) {
- if (originalContentLength != -1) {
- throw new IllegalStateException("ContentLength already set.");
- }
-
- originalContentLength = pLength;
- }
-
- @Override
- public void setHeader(String name, String value) {
- // NOTE: Clients could also specify content type/content length using the setHeader method, special handling
- if (name != null && name.equals("Content-Length")) {
- setContentLength(Integer.valueOf(value)); // Value might be too large, but we don't support that anyway
- }
- else if (name != null && name.equals("Content-Type")) {
- setContentType(value);
- }
- else {
- super.setHeader(name, value);
- }
- }
-
- /**
- * Writes the image to the original {@code ServletOutputStream}.
- * If no format is set in this response, the image is encoded in the same
- * format as the original image.
- *
- * @throws IOException if an I/O exception occurs during writing
- */
- public void flush() throws IOException {
- String outputType = getOutputContentType();
-
- // Force transcoding, if no other filtering is done
- if (outputType != null && !outputType.equals(originalContentType)) {
- getImage();
- }
-
- if (image != null) {
- Iterator writers = ImageIO.getImageWritersByMIMEType(outputType);
- if (writers.hasNext()) {
- super.setContentType(outputType);
- OutputStream out = super.getOutputStream();
- try {
- ImageWriter writer = (ImageWriter) writers.next();
- try {
- ImageWriteParam param = writer.getDefaultWriteParam();
- ///////////////////
- // POST-PROCESS
- // For known formats that don't support transparency, convert to opaque
- if (isNonAlphaFormat(outputType) && image.getColorModel().getTransparency() != Transparency.OPAQUE) {
- image = ImageUtil.toBuffered(image, BufferedImage.TYPE_INT_RGB);
- }
-
- Float requestQuality = (Float) originalRequest.getAttribute(ImageServletResponse.ATTRIB_OUTPUT_QUALITY);
-
- // The default JPEG quality is not good enough, so always adjust compression/quality
- if ((requestQuality != null || "jpeg".equalsIgnoreCase(getFormatNameSafe(writer))) && param.canWriteCompressed()) {
- // TODO: See http://blog.apokalyptik.com/2009/09/16/quality-time-with-your-jpegs/ for better adjusting the (default) JPEG quality
- // OR: Use the metadata of the original image
-
- param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
-
- // WORKAROUND: Known bug in GIFImageWriter in certain JDK versions, compression type is not set by default
- if (param.getCompressionTypes() != null && param.getCompressionType() == null) {
- param.setCompressionType(param.getCompressionTypes()[0]); // Just choose any, to keep param happy
- }
-
- param.setCompressionQuality(requestQuality != null ? requestQuality : 0.8f);
- }
-
- if ("gif".equalsIgnoreCase(getFormatNameSafe(writer)) && !(image.getColorModel() instanceof IndexColorModel)
- /*&& image.getColorModel().getTransparency() != Transparency.OPAQUE*/) {
- // WORKAROUND: Bug in GIFImageWriter may throw NPE if transparent pixels
- // See: http://bugs.sun.com/view_bug.do?bug_id=6287936
- image = ImageUtil.createIndexed(
- ImageUtil.toBuffered(image), 256, null,
- (image.getColorModel().getTransparency() == Transparency.OPAQUE ? ImageUtil.TRANSPARENCY_OPAQUE : ImageUtil.TRANSPARENCY_BITMASK) | ImageUtil.DITHER_DIFFUSION_ALTSCANS
- );
- }
- //////////////////
- ImageOutputStream stream = ImageIO.createImageOutputStream(out);
-
- writer.setOutput(stream);
- try {
- writer.write(null, new IIOImage(image, null, null), param);
- }
- finally {
- stream.close();
- }
- }
- finally {
- writer.dispose();
- }
- }
- finally {
- out.flush();
- }
- }
- else {
- context.log("ERROR: No writer for content-type: " + outputType);
- throw new IIOException("Unable to transcode image: No suitable image writer found (content-type: " + outputType + ").");
- }
- }
- else {
- super.setContentType(originalContentType);
-
- ServletOutputStream out = super.getOutputStream();
-
- try {
- if (bufferedOut != null) {
- bufferedOut.writeTo(out);
- }
- }
- finally {
- out.flush();
- }
- }
- }
-
- 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) {
- try {
- return pWriter.getOriginatingProvider().getFormatNames()[0];
- }
- catch (RuntimeException e) {
- // NPE, AIOOBE, etc..
- return null;
- }
- }
-
- public String getOutputContentType() {
- return outputContentType != null ? outputContentType : originalContentType;
- }
-
- public void setOutputContentType(final String pImageFormat) {
- outputContentType = pImageFormat;
- }
-
- /**
- * Sets the image for this response.
- *
- * @param pImage the {@code RenderedImage} that will be written to the
- * response stream
- */
- public void setImage(final RenderedImage pImage) {
- image = pImage;
- }
-
- /**
- * Gets the decoded image from the response.
- *
- * @return a {@code BufferedImage} or {@code null} if the image could
- * not be read.
- *
- * @throws java.io.IOException if an I/O exception occurs during reading
- */
- public BufferedImage getImage() throws IOException {
- if (image == null) {
- // No content, no image
- if (bufferedOut == null) {
- return null;
- }
-
- // Read from the byte buffer
- InputStream byteStream = bufferedOut.createInputStream();
- ImageInputStream input = null;
- try {
- input = ImageIO.createImageInputStream(byteStream);
- Iterator readers = ImageIO.getImageReaders(input);
- if (readers.hasNext()) {
- // Get the correct reader
- ImageReader reader = (ImageReader) readers.next();
- try {
- reader.setInput(input);
-
- ImageReadParam param = reader.getDefaultReadParam();
-
- // Get default size
- int originalWidth = reader.getWidth(0);
- int originalHeight = reader.getHeight(0);
-//////////////////
-// PRE-PROCESS (prepare): param, size, format?, request, response?
- // TODO: AOI strategy?
- // Extract AOI from request
- Rectangle aoi = extractAOIFromRequest(originalWidth, originalHeight, originalRequest);
-
- if (aoi != null) {
- param.setSourceRegion(aoi);
- originalWidth = aoi.width;
- originalHeight = aoi.height;
- }
-
- // TODO: Size and subsampling strategy?
- // If possible, extract size from request
- Dimension size = extractSizeFromRequest(originalWidth, originalHeight, originalRequest);
- double readSubSamplingFactor = getReadSubsampleFactorFromRequest(originalRequest);
-
- if (size != null) {
- //System.out.println("Size: " + size);
- if (param.canSetSourceRenderSize()) {
- param.setSourceRenderSize(size);
- }
- else {
- int subX = (int) Math.max(originalWidth / (size.width * readSubSamplingFactor), 1.0);
- int subY = (int) Math.max(originalHeight / (size.height * readSubSamplingFactor), 1.0);
-
- if (subX > 1 || subY > 1) {
- param.setSourceSubsampling(subX, subY, subX > 1 ? subX / 2 : 0, subY > 1 ? subY / 2 : 0);
- }
- }
- }
-
- // Need base URI for SVG with links/stylesheets etc
- maybeSetBaseURIFromRequest(param);
-
-/////////////////////
-
- // Finally, read the image using the supplied parameter
- BufferedImage image = reader.read(0, param);
-
- // TODO: If we sub-sampled, it would be a good idea to blur before resampling,
- // to avoid jagged lines artifacts
-
- // If reader doesn't support dynamic sizing, scale now
- image = resampleImage(image, size);
-
- // Fill bgcolor behind image, if transparent
- extractAndSetBackgroundColor(image); // TODO: Move to flush/POST-PROCESS
-
- // Set image
- this.image = image;
- }
- finally {
- reader.dispose();
- }
- }
- else {
- context.log("ERROR: No suitable image reader found (content-type: " + originalContentType + ").");
- context.log("ERROR: Available formats: " + getFormatsString());
-
- throw new IIOException("Unable to transcode image: No suitable image reader found (content-type: " + originalContentType + ").");
- }
-
- // Free resources, as the image is now either read, or unreadable
- bufferedOut = null;
- }
- finally {
- if (input != null) {
- input.close();
- }
- }
- }
-
- // Image is usually a BufferedImage, but may also be a RenderedImage
- return image != null ? ImageUtil.toBuffered(image) : null;
- }
-
- private BufferedImage resampleImage(final BufferedImage image, final Dimension size) {
- if (image != null && size != null && (image.getWidth() != size.width || image.getHeight() != size.height)) {
- int resampleAlgorithm = getResampleAlgorithmFromRequest();
-
- // TODO: One possibility is to NOT handle index color here, and only handle it later, IF NEEDED (read: GIF,
- // possibly also for PNG) when we know the output format (flush method).
- // This will make the filter faster (and better quality, possibly at the expense of more bytes being sent
- // over the wire) in the general case. Who uses GIF nowadays anyway?
- // Also, this means we could either keep the original IndexColorModel in the filter, or go through the
- // expensive operation of re-calculating the optimal palette for the new image (the latter might improve quality).
-
- // 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);
- BufferedImage resampled = ImageUtil.createResampled(image, size.width, size.height, resampleAlgorithm);
- return ImageUtil.createIndexed(resampled, (IndexColorModel) image.getColorModel(), null, ImageUtil.DITHER_NONE | ImageUtil.TRANSPARENCY_BITMASK);
-// return ImageUtil.createIndexed(resampled, 256, null, ImageUtil.COLOR_SELECTION_QUALITY | ImageUtil.DITHER_NONE | ImageUtil.TRANSPARENCY_BITMASK);
- }
- else {
- */
- return ImageUtil.createResampled(image, size.width, size.height, resampleAlgorithm);
-// }
- }
- return image;
- }
-
- int getResampleAlgorithmFromRequest() {
- Object algorithm = originalRequest.getAttribute(ATTRIB_IMAGE_RESAMPLE_ALGORITHM);
- if (algorithm instanceof Integer && ((Integer) algorithm == Image.SCALE_SMOOTH || (Integer) algorithm == Image.SCALE_FAST || (Integer) algorithm == Image.SCALE_DEFAULT)) {
- return (Integer) algorithm;
- }
- else {
- if (algorithm != null) {
- context.log("WARN: Illegal image resampling algorithm: " + algorithm);
- }
-
- return BufferedImage.SCALE_DEFAULT;
- }
- }
-
- private double getReadSubsampleFactorFromRequest(final ServletRequest pOriginalRequest) {
- double subsampleFactor;
-
- Object factor = pOriginalRequest.getAttribute(ATTRIB_READ_SUBSAMPLING_FACTOR);
- if (factor instanceof Number && ((Number) factor).doubleValue() >= 1.0) {
- subsampleFactor = ((Number) factor).doubleValue();
- }
- else {
- if (factor != null) {
- context.log("WARN: Illegal read subsampling factor: " + factor);
- }
-
- subsampleFactor = 2.0;
- }
-
- return subsampleFactor;
- }
-
- private void extractAndSetBackgroundColor(final BufferedImage pImage) {
- // TODO: bgColor request attribute instead of parameter?
- if (pImage.getColorModel().hasAlpha()) {
- String bgColor = originalRequest.getParameter("bg.color");
- if (bgColor != null) {
- Color color = StringUtil.toColor(bgColor);
-
- Graphics2D g = pImage.createGraphics();
- try {
- g.setColor(color);
- g.setComposite(AlphaComposite.DstOver);
- g.fillRect(0, 0, pImage.getWidth(), pImage.getHeight());
- }
- finally {
- g.dispose();
- }
- }
- }
- }
-
- private static String getFormatsString() {
- String[] formats = ImageIO.getReaderFormatNames();
- StringBuilder buf = new StringBuilder();
- for (int i = 0; i < formats.length; i++) {
- String format = formats[i];
- if (i > 0) {
- buf.append(", ");
- }
- buf.append(format);
- }
- return buf.toString();
- }
-
- private void maybeSetBaseURIFromRequest(final ImageReadParam pParam) {
- if (originalRequest instanceof HttpServletRequest) {
- try {
- // If there's a setBaseURI method, we'll try to use that (uses reflection, to avoid dependency on plugins)
- Method setBaseURI;
- try {
- setBaseURI = pParam.getClass().getMethod("setBaseURI", String.class);
- }
- catch (NoSuchMethodException ignore) {
- return;
- }
-
- // Get URL for resource and set as base
- String baseURI = ServletUtil.getContextRelativeURI((HttpServletRequest) originalRequest);
-
- URL resourceURL = context.getResource(baseURI);
-
- if (resourceURL == null) {
- resourceURL = ServletUtil.getRealURL(context, baseURI);
- }
-
- if (resourceURL != null) {
- setBaseURI.invoke(pParam, resourceURL.toExternalForm());
- }
- else {
- context.log("WARN: Resource URL not found for URI: " + baseURI);
- }
- }
- catch (Exception e) {
- context.log("WARN: Could not set base URI: ", e);
- }
- }
- }
-
- private Dimension extractSizeFromRequest(final int pDefaultWidth, final int pDefaultHeight, final ServletRequest pOriginalRequest) {
- // TODO: Allow extraction from request parameters
- /*
- int sizeW = ServletUtil.getIntParameter(originalRequest, "size.w", -1);
- int sizeH = ServletUtil.getIntParameter(originalRequest, "size.h", -1);
- boolean sizePercent = ServletUtil.getBooleanParameter(originalRequest, "size.percent", false);
- boolean sizeUniform = ServletUtil.getBooleanParameter(originalRequest, "size.uniform", true);
- */
- Dimension size = (Dimension) pOriginalRequest.getAttribute(ATTRIB_SIZE);
- int sizeW = size != null ? size.width : -1;
- int sizeH = size != null ? size.height : -1;
-
- Boolean b = (Boolean) pOriginalRequest.getAttribute(ATTRIB_SIZE_PERCENT);
- boolean sizePercent = b != null && b; // default: false
-
- b = (Boolean) pOriginalRequest.getAttribute(ATTRIB_SIZE_UNIFORM);
- boolean sizeUniform = b == null || b; // default: true
-
- if (sizeW >= 0 || sizeH >= 0) {
- size = getSize(pDefaultWidth, pDefaultHeight, sizeW, sizeH, sizePercent, sizeUniform);
- }
-
- return size;
- }
-
- private Rectangle extractAOIFromRequest(final int pDefaultWidth, final int pDefaultHeight, final ServletRequest pOriginalRequest) {
- // TODO: Allow extraction from request parameters
- /*
- int aoiX = ServletUtil.getIntParameter(originalRequest, "aoi.x", -1);
- int aoiY = ServletUtil.getIntParameter(originalRequest, "aoi.y", -1);
- int aoiW = ServletUtil.getIntParameter(originalRequest, "aoi.w", -1);
- int aoiH = ServletUtil.getIntParameter(originalRequest, "aoi.h", -1);
- boolean aoiPercent = ServletUtil.getBooleanParameter(originalRequest, "aoi.percent", false);
- boolean aoiUniform = ServletUtil.getBooleanParameter(originalRequest, "aoi.uniform", false);
- */
- Rectangle aoi = (Rectangle) pOriginalRequest.getAttribute(ATTRIB_AOI);
- int aoiX = aoi != null ? aoi.x : -1;
- int aoiY = aoi != null ? aoi.y : -1;
- int aoiW = aoi != null ? aoi.width : -1;
- int aoiH = aoi != null ? aoi.height : -1;
-
- Boolean b = (Boolean) pOriginalRequest.getAttribute(ATTRIB_AOI_PERCENT);
- boolean aoiPercent = b != null && b; // default: false
-
- b = (Boolean) pOriginalRequest.getAttribute(ATTRIB_AOI_UNIFORM);
- boolean aoiUniform = b != null && b; // default: false
-
- if (aoiX >= 0 || aoiY >= 0 || aoiW >= 0 || aoiH >= 0) {
-
- AreaOfInterest areaOfInterest = AreaOfInterestFactory.getDefault().
- createAreaOfInterest(pDefaultWidth, pDefaultHeight, aoiPercent, aoiUniform);
- aoi = areaOfInterest.getAOI(new Rectangle(aoiX, aoiY, aoiW, aoiH));
- return aoi;
- }
-
- return null;
- }
-
- // TODO: Move these to ImageUtil or similar, as they are often used...
- // TODO: Consider separate methods for percent and pixels
- /**
- * Gets the dimensions (height and width) of the scaled image. The
- * dimensions are computed based on the old image's dimensions, the units
- * used for specifying new dimensions and whether or not uniform scaling
- * should be used (se algorithm below).
- *
- * @param pOriginalWidth the original width of the image
- * @param pOriginalHeight the original height of the image
- * @param pWidth the new width 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
- * parameter (UNITS_PIXELS or UNITS_PERCENT)
- * @param pUniform boolean specifying uniform scale or not
- * @return a Dimension object, with the correct width and heigth
- * in pixels, for the scaled version of the image.
- */
- static Dimension getSize(int pOriginalWidth, int pOriginalHeight,
- int pWidth, int pHeight,
- boolean pPercent, boolean pUniform) {
-
- // If uniform, make sure width and height are scaled the same amount
- // (use ONLY height or ONLY width).
- //
- // Algorithm:
- // if uniform
- // if newHeight not set
- // find ratio newWidth / oldWidth
- // oldHeight *= ratio
- // else if newWidth not set
- // find ratio newWidth / oldWidth
- // oldHeight *= ratio
- // else
- // find both ratios and use the smallest one
- // (this will be the largest version of the image that fits
- // inside the rectangle given)
- // (if PERCENT, just use smallest percentage).
- //
- // If units is percent, we only need old height and width
-
- float ratio;
-
- if (pPercent) {
- if (pWidth >= 0 && pHeight >= 0) {
- // Non-uniform
- pWidth = Math.round((float) pOriginalWidth * (float) pWidth / 100f);
- pHeight = Math.round((float) pOriginalHeight * (float) pHeight / 100f);
- }
- else if (pWidth >= 0) {
- // Find ratio from pWidth
- ratio = (float) pWidth / 100f;
- pWidth = Math.round((float) pOriginalWidth * ratio);
- pHeight = Math.round((float) pOriginalHeight * ratio);
- }
- else if (pHeight >= 0) {
- // Find ratio from pHeight
- ratio = (float) pHeight / 100f;
- pWidth = Math.round((float) pOriginalWidth * ratio);
- pHeight = Math.round((float) pOriginalHeight * ratio);
- }
- // Else: No scale
- }
- else {
- if (pUniform) {
- if (pWidth >= 0 && pHeight >= 0) {
- // Compute both ratios
- ratio = (float) pWidth / (float) pOriginalWidth;
- float heightRatio = (float) pHeight / (float) pOriginalHeight;
-
- // Find the largest ratio, and use that for both
- if (heightRatio < ratio) {
- ratio = heightRatio;
- pWidth = Math.round((float) pOriginalWidth * ratio);
- }
- else {
- pHeight = Math.round((float) pOriginalHeight * ratio);
- }
- }
- else if (pWidth >= 0) {
- // Find ratio from pWidth
- ratio = (float) pWidth / (float) pOriginalWidth;
- pHeight = Math.round((float) pOriginalHeight * ratio);
- }
- else if (pHeight >= 0) {
- // Find ratio from pHeight
- ratio = (float) pHeight / (float) pOriginalHeight;
- pWidth = Math.round((float) pOriginalWidth * ratio);
- }
- // Else: No scale
- }
- }
-
- // Default is no scale, just work as a proxy
- if (pWidth < 0) {
- pWidth = pOriginalWidth;
- }
- if (pHeight < 0) {
- pHeight = pOriginalHeight;
- }
-
- // Create new Dimension object and return
- return new Dimension(pWidth, pHeight);
- }
-
- static Rectangle getAOI(int pOriginalWidth, int pOriginalHeight,
- int pX, int pY, int pWidth, int pHeight,
- boolean pPercent, boolean pMaximizeToAspect) {
- // Algorithm:
- // Try to get x and y (default 0,0).
- // Try to get width and height (default width-x, height-y)
- //
- // If percent, get ratio
- //
- // If uniform
- //
-
- float ratio;
-
- if (pPercent) {
- if (pWidth >= 0 && pHeight >= 0) {
- // Non-uniform
- pWidth = Math.round((float) pOriginalWidth * (float) pWidth / 100f);
- pHeight = Math.round((float) pOriginalHeight * (float) pHeight / 100f);
- }
- else if (pWidth >= 0) {
- // Find ratio from pWidth
- ratio = (float) pWidth / 100f;
- pWidth = Math.round((float) pOriginalWidth * ratio);
- pHeight = Math.round((float) pOriginalHeight * ratio);
- }
- else if (pHeight >= 0) {
- // Find ratio from pHeight
- ratio = (float) pHeight / 100f;
- pWidth = Math.round((float) pOriginalWidth * ratio);
- pHeight = Math.round((float) pOriginalHeight * ratio);
- }
- // Else: No crop
- }
- else {
- // Uniform
- if (pMaximizeToAspect) {
- if (pWidth >= 0 && pHeight >= 0) {
- // Compute both ratios
- ratio = (float) pWidth / (float) pHeight;
- float originalRatio = (float) pOriginalWidth / (float) pOriginalHeight;
- if (ratio > originalRatio) {
- pWidth = pOriginalWidth;
- pHeight = Math.round((float) pOriginalWidth / ratio);
- }
- else {
- pHeight = pOriginalHeight;
- pWidth = Math.round((float) pOriginalHeight * ratio);
- }
- }
- else if (pWidth >= 0) {
- // Find ratio from pWidth
- ratio = (float) pWidth / (float) pOriginalWidth;
- pHeight = Math.round((float) pOriginalHeight * ratio);
- }
- else if (pHeight >= 0) {
- // Find ratio from pHeight
- ratio = (float) pHeight / (float) pOriginalHeight;
- pWidth = Math.round((float) pOriginalWidth * ratio);
- }
- // Else: No crop
- }
- }
-
- // Not specified, or outside bounds: Use original dimensions
- if (pWidth < 0 || (pX < 0 && pWidth > pOriginalWidth)
- || (pX >= 0 && (pX + pWidth) > pOriginalWidth)) {
- pWidth = (pX >= 0 ? pOriginalWidth - pX : pOriginalWidth);
- }
- if (pHeight < 0 || (pY < 0 && pHeight > pOriginalHeight)
- || (pY >= 0 && (pY + pHeight) > pOriginalHeight)) {
- pHeight = (pY >= 0 ? pOriginalHeight - pY : pOriginalHeight);
- }
-
- // Center
- if (pX < 0) {
- pX = (pOriginalWidth - pWidth) / 2;
- }
- if (pY < 0) {
- pY = (pOriginalHeight - pHeight) / 2;
- }
-
-// System.out.println("x: " + pX + " y: " + pY
-// + " w: " + pWidth + " h " + pHeight);
-
- return new Rectangle(pX, pY, pWidth, pHeight);
- }
-}
\ No newline at end of file
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/NullImageFilter.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/NullImageFilter.java
deleted file mode 100755
index 6a2cc0ef..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/NullImageFilter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-
-import javax.servlet.ServletRequest;
-
-/**
- * An {@code ImageFilter} that does nothing. Useful for debugging purposes.
- *
- * @author Harald Kuhr
- * @version $Id: NullImageFilter.java $
- *
- */
-@Deprecated
-public final class NullImageFilter extends ImageFilter {
- protected RenderedImage doFilter(BufferedImage pImage, ServletRequest pRequest, ImageServletResponse pResponse) {
- return pImage;
- }
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/RotateFilter.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/RotateFilter.java
deleted file mode 100755
index 51974464..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/RotateFilter.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image;
-
-import java.awt.*;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-
-import javax.servlet.ServletRequest;
-
-import com.twelvemonkeys.image.ImageUtil;
-import com.twelvemonkeys.lang.StringUtil;
-import com.twelvemonkeys.servlet.ServletUtil;
-
-/**
- * This Servlet is able to render a cropped part of an image.
- *
- *
- *
- * Parameters:
- *
- * - {@code cropX}
- * - integer, the new left edge of the image.
- *
- {@code cropY}
- * - integer, the new top of the image.
- *
- {@code cropWidth}
- * - integer, the new width of the image.
- *
- {@code cropHeight}
- * - integer, the new height of the image.
- *
- *
- *
- *
- * Examples:
- *
- * JPEG:
- * <IMG src="/scale/test.jpg?image=http://www.iconmedialab.com/images/random/home_image_12.jpg&width=500&uniform=true">
- *
- * PNG:
- * <IMG src="/scale/test.png?cache=false&image=http://www.iconmedialab.com/images/random/home_image_12.jpg&width=50&units=PERCENT">
- *
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- * @version $Id: RotateFilter.java#1 $
- */
-// TODO: Correct rounding errors, resulting in black borders when rotating 90
-// degrees, and one of width or height is odd length...
-@Deprecated
-public class RotateFilter extends ImageFilter {
- /** {@code angle}*/
- protected final static String PARAM_ANGLE = "angle";
- /** {@code angleUnits (RADIANS|DEGREES)}*/
- protected final static String PARAM_ANGLE_UNITS = "angleUnits";
- /** {@code crop}*/
- protected final static String PARAM_CROP = "rotateCrop";
- /** {@code bgcolor}*/
- protected final static String PARAM_BGCOLOR = "rotateBgcolor";
-
- /** {@code degrees}*/
- private final static String ANGLE_DEGREES = "degrees";
- /** {@code radians}*/
- //private final static String ANGLE_RADIANS = "radians";
-
- /**
- * Reads the image from the requested URL, rotates it, and returns
- * it in the
- * Servlet stream. See above for details on parameters.
- */
-
- protected RenderedImage doFilter(BufferedImage pImage, ServletRequest pRequest, ImageServletResponse pResponse) {
- // Get angle
- double ang = getAngle(pRequest);
-
- // Get bounds
- Rectangle2D rect = getBounds(pRequest, pImage, ang);
- int width = (int) rect.getWidth();
- int height = (int) rect.getHeight();
-
- // Create result image
- BufferedImage res = ImageUtil.createTransparent(width, height, BufferedImage.TYPE_INT_ARGB);
- Graphics2D g = res.createGraphics();
-
- // Get background color and clear
- String str = pRequest.getParameter(PARAM_BGCOLOR);
- if (!StringUtil.isEmpty(str)) {
- Color bgcolor = StringUtil.toColor(str);
- g.setBackground(bgcolor);
- g.clearRect(0, 0, width, height);
- }
-
- // Set mHints (why do I always get jagged edgdes?)
- RenderingHints hints = new RenderingHints(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
- hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
- hints.add(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
- hints.add(new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC));
-
- g.setRenderingHints(hints);
-
- // Rotate around center
- AffineTransform at = AffineTransform
- .getRotateInstance(ang, width / 2.0, height / 2.0);
-
- // Move to center
- at.translate(width / 2.0 - pImage.getWidth() / 2.0,
- height / 2.0 - pImage.getHeight() / 2.0);
-
- // Draw it, centered
- g.drawImage(pImage, at, null);
-
- return res;
- }
-
- /**
- * Gets the angle of rotation.
- */
-
- private double getAngle(ServletRequest pReq) {
- double angle = 0.0;
- String str = pReq.getParameter(PARAM_ANGLE);
- if (!StringUtil.isEmpty(str)) {
- angle = Double.parseDouble(str);
-
- // Convert to radians, if needed
- str = pReq.getParameter(PARAM_ANGLE_UNITS);
- if (!StringUtil.isEmpty(str)
- && ANGLE_DEGREES.equalsIgnoreCase(str)) {
- angle = Math.toRadians(angle);
- }
- }
-
- return angle;
- }
-
- /**
- * Get the bounding rectangle of the rotated image.
- */
-
- private Rectangle2D getBounds(ServletRequest pReq, BufferedImage pImage,
- double pAng) {
- // Get dimensions of original image
- int width = pImage.getWidth(); // loads the image
- int height = pImage.getHeight();
-
- // Test if we want to crop image (default)
- // if true
- // - find the largest bounding box INSIDE the rotated image,
- // that matches the original proportions (nearest 90deg)
- // (scale up to fit dimensions?)
- // else
- // - find the smallest bounding box OUTSIDE the rotated image.
- // - that matches the original proportions (nearest 90deg) ?
- // (scale down to fit dimensions?)
- AffineTransform at =
- AffineTransform.getRotateInstance(pAng, width / 2.0, height / 2.0);
-
- Rectangle2D orig = new Rectangle(width, height);
- Shape rotated = at.createTransformedShape(orig);
-
- if (ServletUtil.getBooleanParameter(pReq, PARAM_CROP, false)) {
- // TODO: Inside box
- return rotated.getBounds2D();
- }
- else {
- return rotated.getBounds2D();
- }
- }
-}
-
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/ScaleFilter.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/ScaleFilter.java
deleted file mode 100755
index 6434d7a0..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/ScaleFilter.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image;
-
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-import java.lang.reflect.Field;
-
-import javax.servlet.ServletRequest;
-
-import com.twelvemonkeys.image.ImageUtil;
-import com.twelvemonkeys.lang.StringUtil;
-import com.twelvemonkeys.servlet.ServletUtil;
-
-
-/**
- * This filter renders a scaled version of an image read from a
- * given URL. The image can be output as a GIF, JPEG or PNG image
- * or similar.
- *
- *
- *
- *
- * Parameters:
- *
- *
- * - {@code scaleX}
- * - integer, the new width of the image.
- *
- {@code scaleY}
- * - integer, the new height of the image.
- *
- {@code scaleUniform}
- * - boolean, wether or not uniform scalnig should be used. Default is
- * {@code true}.
- *
- {@code scaleUnits}
- * - string, one of {@code PIXELS}, {@code PERCENT}.
- * {@code PIXELS} is default.
- *
- {@code scaleQuality}
- * - string, one of {@code SCALE_SMOOTH}, {@code SCALE_FAST},
- * {@code SCALE_REPLICATE}, {@code SCALE_AREA_AVERAGING}.
- * {@code SCALE_DEFAULT} is default (see
- * {@link java.awt.Image#getScaledInstance(int,int,int)}, {@link java.awt.Image}
- * for more details).
- *
- *
- * Examples:
- *
- *
- * <IMG src="/scale/test.jpg?scaleX=500&scaleUniform=false">
- * <IMG src="/scale/test.png?scaleY=50&scaleUnits=PERCENT">
- *
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- * @version $Id: ScaleFilter.java#1 $
- *
- */
-@Deprecated
-public class ScaleFilter extends ImageFilter {
-
- /**
- * Width and height are absolute pixels. The default.
- */
- public static final int UNITS_PIXELS = 1;
- /**
- * Width and height are percentage of original width and height.
- */
- public static final int UNITS_PERCENT = 5;
- /**
- * Ahh, good choice!
- */
- //private static final int UNITS_METRIC = 42;
- /**
- * The root of all evil...
- */
- //private static final int UNITS_INCHES = 666;
- /**
- * Unknown units.
- */
- public static final int UNITS_UNKNOWN = 0;
-
- /**
- * {@code scaleQuality}
- */
- protected final static String PARAM_SCALE_QUALITY = "scaleQuality";
- /**
- * {@code scaleUnits}
- */
- protected final static String PARAM_SCALE_UNITS = "scaleUnits";
- /**
- * {@code scaleUniform}
- */
- protected final static String PARAM_SCALE_UNIFORM = "scaleUniform";
- /**
- * {@code scaleX}
- */
- protected final static String PARAM_SCALE_X = "scaleX";
- /**
- * {@code scaleY}
- */
- protected final static String PARAM_SCALE_Y = "scaleY";
- /**
- * {@code image}
- */
- protected final static String PARAM_IMAGE = "image";
-
- /** */
- protected int defaultScaleQuality = Image.SCALE_DEFAULT;
-
- /**
- * Reads the image from the requested URL, scales it, and returns it in the
- * Servlet stream. See above for details on parameters.
- */
- protected RenderedImage doFilter(BufferedImage pImage, ServletRequest pRequest, ImageServletResponse pResponse) {
-
- // Get quality setting
- // SMOOTH | FAST | REPLICATE | DEFAULT | AREA_AVERAGING
- // See Image (mHints)
- int quality = getQuality(pRequest.getParameter(PARAM_SCALE_QUALITY));
-
- // Get units, default is pixels
- // PIXELS | PERCENT | METRIC | INCHES
- int units = getUnits(pRequest.getParameter(PARAM_SCALE_UNITS));
- if (units == UNITS_UNKNOWN) {
- log("Unknown units for scale, returning original.");
- return pImage;
- }
-
- // Use uniform scaling? Default is true
- boolean uniformScale = ServletUtil.getBooleanParameter(pRequest, PARAM_SCALE_UNIFORM, true);
-
- // Get dimensions
- int width = ServletUtil.getIntParameter(pRequest, PARAM_SCALE_X, -1);
- int height = ServletUtil.getIntParameter(pRequest, PARAM_SCALE_Y, -1);
-
- // Get dimensions for scaled image
- Dimension dim = getDimensions(pImage, width, height, units, uniformScale);
-
- width = (int) dim.getWidth();
- height = (int) dim.getHeight();
-
- // Return scaled instance directly
- return ImageUtil.createScaled(pImage, width, height, quality);
- }
-
- /**
- * Gets the quality constant for the scaling, from the string argument.
- *
- * @param pQualityStr The string representation of the scale quality
- * constant.
- * @return The matching quality constant, or the default quality if none
- * was found.
- * @see java.awt.Image
- * @see java.awt.Image#getScaledInstance(int,int,int)
- */
- protected int getQuality(String pQualityStr) {
- if (!StringUtil.isEmpty(pQualityStr)) {
- try {
- // Get quality constant from Image using reflection
- Class cl = Image.class;
- Field field = cl.getField(pQualityStr.toUpperCase());
-
- return field.getInt(null);
- }
- catch (IllegalAccessException ia) {
- log("Unable to get quality.", ia);
- }
- catch (NoSuchFieldException nsf) {
- log("Unable to get quality.", nsf);
- }
- }
-
- return defaultScaleQuality;
- }
-
- public void setDefaultScaleQuality(String pDefaultScaleQuality) {
- defaultScaleQuality = getQuality(pDefaultScaleQuality);
- }
-
- /**
- * Gets the units constant for the width and height arguments, from the
- * given string argument.
- *
- * @param pUnitStr The string representation of the units constant,
- * can be one of "PIXELS" or "PERCENT".
- * @return The mathcing units constant, or UNITS_UNKNOWN if none was found.
- */
- protected int getUnits(String pUnitStr) {
- if (StringUtil.isEmpty(pUnitStr)
- || pUnitStr.equalsIgnoreCase("PIXELS")) {
- return UNITS_PIXELS;
- }
- else if (pUnitStr.equalsIgnoreCase("PERCENT")) {
- return UNITS_PERCENT;
- }
- else {
- return UNITS_UNKNOWN;
- }
- }
-
- /**
- * Gets the dimensions (height and width) of the scaled image. The
- * dimensions are computed based on the old image's dimensions, the units
- * used for specifying new dimensions and whether or not uniform scaling
- * should be used (se algorithm below).
- *
- * @param pImage the image to be scaled
- * @param pWidth the new width of the image, or -1 if unknown
- * @param pHeight the new height of the image, or -1 if unknown
- * @param pUnits the constant specifying units for width and height
- * parameter (UNITS_PIXELS or UNITS_PERCENT)
- * @param pUniformScale boolean specifying uniform scale or not
- * @return a Dimension object, with the correct width and heigth
- * in pixels, for the scaled version of the image.
- */
- protected Dimension getDimensions(Image pImage, int pWidth, int pHeight,
- int pUnits, boolean pUniformScale) {
-
- // If uniform, make sure width and height are scaled the same ammount
- // (use ONLY height or ONLY width).
- //
- // Algoritm:
- // if uniform
- // if newHeight not set
- // find ratio newWidth / oldWidth
- // oldHeight *= ratio
- // else if newWidth not set
- // find ratio newWidth / oldWidth
- // oldHeight *= ratio
- // else
- // find both ratios and use the smallest one
- // (this will be the largest version of the image that fits
- // inside the rectangle given)
- // (if PERCENT, just use smallest percentage).
- //
- // If units is percent, we only need old height and width
-
- int oldWidth = ImageUtil.getWidth(pImage);
- int oldHeight = ImageUtil.getHeight(pImage);
- float ratio;
-
- if (pUnits == UNITS_PERCENT) {
- if (pWidth >= 0 && pHeight >= 0) {
- // Non-uniform
- pWidth = (int) ((float) oldWidth * (float) pWidth / 100f);
- pHeight = (int) ((float) oldHeight * (float) pHeight / 100f);
- }
- else if (pWidth >= 0) {
- // Find ratio from pWidth
- ratio = (float) pWidth / 100f;
- pWidth = (int) ((float) oldWidth * ratio);
- pHeight = (int) ((float) oldHeight * ratio);
- }
- else if (pHeight >= 0) {
- // Find ratio from pHeight
- ratio = (float) pHeight / 100f;
- pWidth = (int) ((float) oldWidth * ratio);
- pHeight = (int) ((float) oldHeight * ratio);
- }
- // Else: No scale
- }
- else if (pUnits == UNITS_PIXELS) {
- if (pUniformScale) {
- if (pWidth >= 0 && pHeight >= 0) {
- // Compute both ratios
- ratio = (float) pWidth / (float) oldWidth;
- float heightRatio = (float) pHeight / (float) oldHeight;
-
- // Find the largest ratio, and use that for both
- if (heightRatio < ratio) {
- ratio = heightRatio;
- pWidth = (int) ((float) oldWidth * ratio);
- }
- else {
- pHeight = (int) ((float) oldHeight * ratio);
- }
-
- }
- else if (pWidth >= 0) {
- // Find ratio from pWidth
- ratio = (float) pWidth / (float) oldWidth;
- pHeight = (int) ((float) oldHeight * ratio);
- }
- else if (pHeight >= 0) {
- // Find ratio from pHeight
- ratio = (float) pHeight / (float) oldHeight;
- pWidth = (int) ((float) oldWidth * ratio);
- }
- // Else: No scale
- }
- }
-
- // Default is no scale, just work as a proxy
- if (pWidth < 0) {
- pWidth = oldWidth;
- }
- if (pHeight < 0) {
- pHeight = oldHeight;
- }
-
- // Create new Dimension object and return
- return new Dimension(pWidth, pHeight);
- }
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/SourceRenderFilter.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/SourceRenderFilter.java
deleted file mode 100755
index 727458ba..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/SourceRenderFilter.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (c) 2009, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image;
-
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-import java.io.IOException;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-import com.twelvemonkeys.servlet.ServletUtil;
-
-/**
- * A {@link javax.servlet.Filter} that extracts request parameters, and sets the
- * corresponding request attributes from {@link ImageServletResponse}.
- * Only affects how the image is decoded, and must be applied before any
- * other image filters in the chain.
- *
- * @see ImageServletResponse#ATTRIB_SIZE
- * @see ImageServletResponse#ATTRIB_AOI
- *
- * @author Harald Kuhr
- * @version $Id: SourceRenderFilter.java#1 $
- */
-@Deprecated
-public class SourceRenderFilter extends ImageFilter {
- private String sizeWidthParam = "size.w";
- private String sizeHeightParam = "size.h";
- private String sizePercentParam = "size.percent";
- private String sizeUniformParam = "size.uniform";
-
- private String regionWidthParam = "aoi.w";
- private String regionHeightParam = "aoi.h";
- private String regionLeftParam = "aoi.x";
- private String regionTopParam = "aoi.y";
- private String regionPercentParam = "aoi.percent";
- private String regionUniformParam = "aoi.uniform";
-
- public void setRegionHeightParam(String pRegionHeightParam) {
- regionHeightParam = pRegionHeightParam;
- }
-
- public void setRegionWidthParam(String pRegionWidthParam) {
- regionWidthParam = pRegionWidthParam;
- }
-
- public void setRegionLeftParam(String pRegionLeftParam) {
- regionLeftParam = pRegionLeftParam;
- }
-
- public void setRegionTopParam(String pRegionTopParam) {
- regionTopParam = pRegionTopParam;
- }
-
- public void setSizeHeightParam(String pSizeHeightParam) {
- sizeHeightParam = pSizeHeightParam;
- }
-
- public void setSizeWidthParam(String pSizeWidthParam) {
- sizeWidthParam = pSizeWidthParam;
- }
-
- public void setRegionPercentParam(String pRegionPercentParam) {
- regionPercentParam = pRegionPercentParam;
- }
-
- public void setRegionUniformParam(String pRegionUniformParam) {
- regionUniformParam = pRegionUniformParam;
- }
-
- public void setSizePercentParam(String pSizePercentParam) {
- sizePercentParam = pSizePercentParam;
- }
-
- public void setSizeUniformParam(String pSizeUniformParam) {
- sizeUniformParam = pSizeUniformParam;
- }
-
- public void init() throws ServletException {
- if (triggerParams == null) {
- // Add all params as triggers
- triggerParams = new String[]{sizeWidthParam, sizeHeightParam,
- sizeUniformParam, sizePercentParam,
- regionLeftParam, regionTopParam,
- regionWidthParam, regionHeightParam,
- regionUniformParam, regionPercentParam};
- }
- }
-
- /**
- * Extracts request parameters, and sets the corresponding request
- * attributes if specified.
- *
- * @param pRequest
- * @param pResponse
- * @param pChain
- * @throws IOException
- * @throws ServletException
- */
- protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException, ServletException {
- // TODO: Max size configuration, to avoid DOS attacks? OutOfMemory
-
- // Size parameters
- int width = ServletUtil.getIntParameter(pRequest, sizeWidthParam, -1);
- int height = ServletUtil.getIntParameter(pRequest, sizeHeightParam, -1);
- if (width > 0 || height > 0) {
- pRequest.setAttribute(ImageServletResponse.ATTRIB_SIZE, new Dimension(width, height));
- }
-
- // Size uniform/percent
- boolean uniform = ServletUtil.getBooleanParameter(pRequest, sizeUniformParam, true);
- if (!uniform) {
- pRequest.setAttribute(ImageServletResponse.ATTRIB_SIZE_UNIFORM, Boolean.FALSE);
- }
- boolean percent = ServletUtil.getBooleanParameter(pRequest, sizePercentParam, false);
- if (percent) {
- pRequest.setAttribute(ImageServletResponse.ATTRIB_SIZE_PERCENT, Boolean.TRUE);
- }
-
- // Area of interest parameters
- int x = ServletUtil.getIntParameter(pRequest, regionLeftParam, -1); // Default is center
- int y = ServletUtil.getIntParameter(pRequest, regionTopParam, -1); // Default is center
- width = ServletUtil.getIntParameter(pRequest, regionWidthParam, -1);
- height = ServletUtil.getIntParameter(pRequest, regionHeightParam, -1);
- if (width > 0 || height > 0) {
- pRequest.setAttribute(ImageServletResponse.ATTRIB_AOI, new Rectangle(x, y, width, height));
- }
-
- // AOI uniform/percent
- uniform = ServletUtil.getBooleanParameter(pRequest, regionUniformParam, false);
- if (uniform) {
- pRequest.setAttribute(ImageServletResponse.ATTRIB_SIZE_UNIFORM, Boolean.TRUE);
- }
- percent = ServletUtil.getBooleanParameter(pRequest, regionPercentParam, false);
- if (percent) {
- pRequest.setAttribute(ImageServletResponse.ATTRIB_SIZE_PERCENT, Boolean.TRUE);
- }
-
- super.doFilterImpl(pRequest, pResponse, pChain);
- }
-
- /**
- * This implementation does no filtering, and simply returns the image
- * passed in.
- *
- * @param pImage
- * @param pRequest
- * @param pResponse
- * @return {@code pImage}
- */
- protected RenderedImage doFilter(BufferedImage pImage, ServletRequest pRequest, ImageServletResponse pResponse) {
- return pImage;
- }
-}
\ No newline at end of file
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterest.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterest.java
deleted file mode 100644
index f46d37c7..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2012, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image.aoi;
-
-import java.awt.*;
-
-/**
- * @author Erlend Hamnaberg
- * @version $Revision: $
- */
-@Deprecated
-public interface AreaOfInterest {
-
- Rectangle getAOI(Rectangle pCrop);
-
- Dimension getOriginalDimension();
-
- int calculateX(Dimension pOriginalDimension, Rectangle pCrop);
-
- int calculateY(Dimension pOriginalDimension, Rectangle pCrop);
-
- Dimension getCrop(Dimension pOriginalDimension, Rectangle pCrop);
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterestFactory.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterestFactory.java
deleted file mode 100644
index fc2c500a..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterestFactory.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2012, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image.aoi;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * @author Erlend Hamnaberg
- * @version $Revision: $
- */
-@Deprecated
-public class AreaOfInterestFactory {
- private final static AtomicReference DEFAULT =
- new AtomicReference(new AreaOfInterestFactory());
-
- public static void setDefault(AreaOfInterestFactory factory) {
- DEFAULT.set(factory);
- }
-
- public static AreaOfInterestFactory getDefault() {
- return DEFAULT.get();
- }
-
- public AreaOfInterest createAreaOfInterest(int pDefaultWidth, int pDefaultHeight, boolean aoiPercent, boolean aoiUniform) {
- if (aoiPercent && aoiUniform) {
- throw new IllegalArgumentException("Cannot be both uniform and percent Area of Interest");
- }
- if (aoiPercent) {
- return new PercentAreaOfInterest(pDefaultWidth, pDefaultHeight);
- }
- else if (aoiUniform) {
- return new UniformAreaOfInterest(pDefaultWidth, pDefaultHeight);
- }
- return new DefaultAreaOfInterest(pDefaultWidth, pDefaultHeight);
- }
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterestWrapper.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterestWrapper.java
deleted file mode 100644
index 9f7b0672..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterestWrapper.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2012, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image.aoi;
-
-import java.awt.*;
-
-import com.twelvemonkeys.lang.Validate;
-
-/**
- * @author Erlend Hamnaberg
- * @version $Revision: $
- */
-@Deprecated
-public class AreaOfInterestWrapper implements AreaOfInterest {
- private AreaOfInterest mDelegate;
-
- public AreaOfInterestWrapper(AreaOfInterest mDelegate) {
- this.mDelegate = Validate.notNull(mDelegate);
- }
-
- public Rectangle getAOI(Rectangle pCrop) {
- return mDelegate.getAOI(pCrop);
- }
-
- public Dimension getOriginalDimension() {
- return mDelegate.getOriginalDimension();
- }
-
- public int calculateX(Dimension pOriginalDimension, Rectangle pCrop) {
- return mDelegate.calculateX(pOriginalDimension, pCrop);
- }
-
- public int calculateY(Dimension pOriginalDimension, Rectangle pCrop) {
- return mDelegate.calculateY(pOriginalDimension, pCrop);
- }
-
- public Dimension getCrop(Dimension pOriginalDimension, Rectangle pCrop) {
- return mDelegate.getCrop(pOriginalDimension, pCrop);
- }
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/DefaultAreaOfInterest.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/DefaultAreaOfInterest.java
deleted file mode 100644
index 5cd86a00..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/DefaultAreaOfInterest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2012, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image.aoi;
-
-import java.awt.*;
-
-/**
- * @author Harald Kuhr
- * @author Erlend Hamnaberg
- * @version $Revision: $
- */
-@Deprecated
-public class DefaultAreaOfInterest implements AreaOfInterest {
- private final int mOriginalWidth;
- private final int mOriginalHeight;
-
- public DefaultAreaOfInterest(int pOriginalWidth, int pOriginalHeight) {
- this.mOriginalWidth = pOriginalWidth;
- this.mOriginalHeight = pOriginalHeight;
- }
-
- public DefaultAreaOfInterest(Dimension pOriginalDimension) {
- this(pOriginalDimension.width, pOriginalDimension.height);
- }
-
- Rectangle getAOI(final int pX, final int pY, final int pWidth, final int pHeight) {
- return getAOI(new Rectangle(pX, pY, pWidth, pHeight));
- }
-
- public Rectangle getAOI(final Rectangle pCrop) {
- int y = pCrop.y;
- int x = pCrop.x;
- Dimension dimension = getOriginalDimension();
-
- Dimension crop = getCrop(dimension, pCrop);
-
- // Center
- if (y < 0) {
- y = calculateY(dimension, new Rectangle(x, y, crop.width, crop.height));
- }
-
- if (x < 0) {
- x = calculateX(dimension, new Rectangle(x, y, crop.width, crop.height));
- }
- return new Rectangle(x, y, crop.width, crop.height);
- }
-
- public Dimension getOriginalDimension() {
- return new Dimension(mOriginalWidth, mOriginalHeight);
- }
-
- public int calculateX(Dimension pOriginalDimension, Rectangle pCrop) {
- return (pOriginalDimension.width - pCrop.width) / 2;
- }
-
- public int calculateY(Dimension pOriginalDimension, Rectangle pCrop) {
- return (pOriginalDimension.height - pCrop.height) / 2;
- }
-
- public Dimension getCrop(Dimension pOriginalDimension, final Rectangle pCrop) {
- int mOriginalWidth1 = pOriginalDimension.width;
- int mOriginalHeight1 = pOriginalDimension.height;
- int x = pCrop.x;
- int y = pCrop.y;
- int cropWidth = pCrop.width;
- int cropHeight = pCrop.height;
-
- if (cropWidth < 0 || (x < 0 && cropWidth > mOriginalWidth1)
- || (x >= 0 && (x + cropWidth) > mOriginalWidth1)) {
- cropWidth = (x >= 0 ? mOriginalWidth1 - x : mOriginalWidth1);
- }
- if (cropHeight < 0 || (y < 0 && cropHeight > mOriginalHeight1)
- || (y >= 0 && (y + cropHeight) > mOriginalHeight1)) {
- cropHeight = (y >= 0 ? mOriginalHeight1 - y : mOriginalHeight1);
- }
- return new Dimension(cropWidth, cropHeight);
- }
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/PercentAreaOfInterest.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/PercentAreaOfInterest.java
deleted file mode 100644
index 1605d2df..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/PercentAreaOfInterest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2012, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image.aoi;
-
-import java.awt.*;
-
-/**
- * @author Erlend Hamnaberg
- * @version $Revision: $
- */
-@Deprecated
-public class PercentAreaOfInterest extends DefaultAreaOfInterest {
-
- public PercentAreaOfInterest(Dimension pOriginalDimension) {
- super(pOriginalDimension);
- }
-
- public PercentAreaOfInterest(int pOriginalWidth, int pOriginalHeight) {
- super(pOriginalWidth, pOriginalHeight);
- }
-
- public Dimension getCrop(Dimension pOriginalDimension, final Rectangle pCrop) {
- int cropWidth = pCrop.width;
- int cropHeight = pCrop.height;
- float ratio;
-
- if (cropWidth >= 0 && cropHeight >= 0) {
- // Non-uniform
- cropWidth = Math.round((float) pOriginalDimension.width * (float) pCrop.width / 100f);
- cropHeight = Math.round((float) pOriginalDimension.height * (float) pCrop.height / 100f);
- }
- else if (cropWidth >= 0) {
- // Find ratio from pWidth
- ratio = (float) cropWidth / 100f;
- cropWidth = Math.round((float) pOriginalDimension.width * ratio);
- cropHeight = Math.round((float) pOriginalDimension.height * ratio);
-
- }
- else if (cropHeight >= 0) {
- // Find ratio from pHeight
- ratio = (float) cropHeight / 100f;
- cropWidth = Math.round((float) pOriginalDimension.width * ratio);
- cropHeight = Math.round((float) pOriginalDimension.height * ratio);
- }
- // Else: No crop
-
- return new Dimension(cropWidth, cropHeight);
- }
-
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/UniformAreaOfInterest.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/UniformAreaOfInterest.java
deleted file mode 100644
index aa04e779..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/aoi/UniformAreaOfInterest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2012, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image.aoi;
-
-import java.awt.*;
-
-/**
- * @author Erlend Hamnaberg
- * @version $Revision: $
- */
-@Deprecated
-public class UniformAreaOfInterest extends DefaultAreaOfInterest {
-
- public UniformAreaOfInterest(Dimension pOriginalDimension) {
- super(pOriginalDimension);
- }
-
- public UniformAreaOfInterest(int pOriginalWidth, int pOriginalHeight) {
- super(pOriginalWidth, pOriginalHeight);
- }
-
- public Dimension getCrop(Dimension pOriginalDimension, final Rectangle pCrop) {
- float ratio;
- if (pCrop.width >= 0 && pCrop.height >= 0) {
- // Compute both ratios
- ratio = (float) pCrop.width / (float) pCrop.height;
- float originalRatio = (float) pOriginalDimension.width / (float) pOriginalDimension.height;
- if (ratio > originalRatio) {
- pCrop.width = pOriginalDimension.width;
- pCrop.height = Math.round((float) pOriginalDimension.width / ratio);
- }
- else {
- pCrop.height = pOriginalDimension.height;
- pCrop.width = Math.round((float) pOriginalDimension.height * ratio);
- }
- }
- else if (pCrop.width >= 0) {
- // Find ratio from pWidth
- ratio = (float) pCrop.width / (float) pOriginalDimension.width;
- pCrop.height = Math.round((float) pOriginalDimension.height * ratio);
- }
- else if (pCrop.height >= 0) {
- // Find ratio from pHeight
- ratio = (float) pCrop.height / (float) pOriginalDimension.height;
- pCrop.width = Math.round((float) pOriginalDimension.width * ratio);
- }
- // Else: No crop
- return new Dimension(pCrop.width, pCrop.height);
- }
-}
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/image/package_info.java b/servlet/src/main/java/com/twelvemonkeys/servlet/image/package_info.java
index 4ab97f32..d6ec9af3 100755
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/image/package_info.java
+++ b/servlet/src/main/java/com/twelvemonkeys/servlet/image/package_info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2021, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,35 +29,7 @@
*/
/**
- * Contains various image-outputting filters, that should run under any
- * servlet engine.
- *
- * Some of these methods may require use of the native graphics libraries
- * supported by the JVM, like the X libraries on Unix systems, and should be
- * run with JRE 1.4 or later, and with the option:
- *
- * - {@code -Djawa.awt.headless=true}
- *
- * See the document
- * AWT Enhancements and bugtraq report
- * 4281163 for more information on this issue.
- *
- * If you cannot use JRE 1.4 or later, or do not want to use the X
- * libraries, one possibility is to use the
- * PJA package (com.eteks.pja),
- * and start the JVM with the following options:
- *
- * - {@code -Xbootclasspath/a:<path to pja.jar>}
- * - {@code -Dawt.toolkit=com.eteks.awt.PJAToolkit}
- * - {@code -Djava.awt.graphicsenv=com.eteks.java2d.PJAGraphicsEnvironment}
- * - {@code -Djava.awt.fonts=<path where True Type fonts files will be loaded from>}
- *
- *
- * Please note that creation of PNG images (from bytes or URL's) are only
- * supported in JRE 1.3 and later, trying to load them from an earlier version,
- * will result in errors.
- *
- * @see com.twelvemonkeys.servlet.image.ImageServlet
- * @see com.twelvemonkeys.servlet.image.ImagePainterServlet
+ * Contains the context listener required for bundling ImageIO plugins
+ * inside a web application.
*/
package com.twelvemonkeys.servlet.image;
\ No newline at end of file
diff --git a/servlet/src/main/java/com/twelvemonkeys/servlet/package_info.java b/servlet/src/main/java/com/twelvemonkeys/servlet/package_info.java
deleted file mode 100755
index 84545a85..00000000
--- a/servlet/src/main/java/com/twelvemonkeys/servlet/package_info.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * Contains servlet support classes.
- */
-package com.twelvemonkeys.servlet;
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/FilterAbstractTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/FilterAbstractTest.java
deleted file mode 100755
index f5dd73b6..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/FilterAbstractTest.java
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet;
-
-import com.twelvemonkeys.lang.ObjectAbstractTest;
-import org.junit.Test;
-
-import javax.servlet.*;
-import java.io.*;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.*;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-/**
- * FilterAbstractTestCase
- *
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/FilterAbstractTestCase.java#1 $
- */
-public abstract class FilterAbstractTest extends ObjectAbstractTest {
- protected Object makeObject() {
- return makeFilter();
- }
-
- protected abstract Filter makeFilter();
-
- // TODO: Is it a good thing to have an API like this?
- protected FilterConfig makeFilterConfig() {
- return makeFilterConfig(new HashMap());
- }
-
- protected FilterConfig makeFilterConfig(Map pParams) {
- return new MockFilterConfig(pParams);
- }
-
- protected ServletRequest makeRequest() {
- return new MockServletRequest();
- }
-
- protected ServletResponse makeResponse() {
- return new MockServletResponse();
- }
-
- protected FilterChain makeFilterChain() {
- return new MockFilterChain();
- }
-
- @Test
- public void testInitNull() {
- Filter filter = makeFilter();
-
- // The spec seems to be a little unclear on this issue, but anyway,
- // the container should never invoke init(null)...
- try {
- filter.init(null);
- fail("Should throw Exception on init(null)");
- }
- catch (IllegalArgumentException e) {
- // Good
- }
- catch (NullPointerException e) {
- // Bad (but not unreasonable)
- }
- catch (ServletException e) {
- // Hmmm.. The jury is still out.
- }
- }
-
- @Test
- public void testInit() {
- Filter filter = makeFilter();
-
- try {
- filter.init(makeFilterConfig());
- }
- catch (ServletException e) {
- assertNotNull(e.getMessage());
- }
- finally {
- filter.destroy();
- }
- }
-
- @Test
- public void testLifeCycle() throws ServletException {
- Filter filter = makeFilter();
-
- try {
- filter.init(makeFilterConfig());
- }
- finally {
- filter.destroy();
- }
- }
-
- @Test
- public void testFilterBasic() throws ServletException, IOException {
- Filter filter = makeFilter();
-
- try {
- filter.init(makeFilterConfig());
-
- filter.doFilter(makeRequest(), makeResponse(), makeFilterChain());
- }
- finally {
- filter.destroy();
- }
- }
-
- @Test
- public void testDestroy() {
- // TODO: Implement
- }
-
- static class MockFilterConfig implements FilterConfig {
- private final Map params;
-
- MockFilterConfig(Map pParams) {
- if (pParams == null) {
- throw new IllegalArgumentException("params == null");
- }
- params = pParams;
- }
-
- public String getFilterName() {
- return "mock-filter";
- }
-
- public String getInitParameter(String pName) {
- return params.get(pName);
- }
-
- public Enumeration getInitParameterNames() {
- return Collections.enumeration(params.keySet());
- }
-
- public ServletContext getServletContext() {
- return new MockServletContext();
- }
-
- private static class MockServletContext implements ServletContext {
- private final Map attributes;
- private final Map params;
-
- MockServletContext() {
- attributes = new HashMap<>();
- params = new HashMap<>();
- }
-
- public Object getAttribute(String s) {
- return attributes.get(s);
- }
-
- public Enumeration getAttributeNames() {
- return Collections.enumeration(attributes.keySet());
- }
-
- public ServletContext getContext(String s) {
- return null; // TODO: Implement
- }
-
- public String getInitParameter(String s) {
- return params.get(s);
- }
-
- public Enumeration getInitParameterNames() {
- return Collections.enumeration(params.keySet());
- }
-
- public int getMajorVersion() {
- return 0; // TODO: Implement
- }
-
- public String getMimeType(String s) {
- return null; // TODO: Implement
- }
-
- public int getMinorVersion() {
- return 0; // TODO: Implement
- }
-
- public RequestDispatcher getNamedDispatcher(String s) {
- return null; // TODO: Implement
- }
-
- public String getRealPath(String s) {
- return null; // TODO: Implement
- }
-
- public RequestDispatcher getRequestDispatcher(String s) {
- return null; // TODO: Implement
- }
-
- public URL getResource(String s) throws MalformedURLException {
- return null; // TODO: Implement
- }
-
- public InputStream getResourceAsStream(String s) {
- return null; // TODO: Implement
- }
-
- public Set getResourcePaths(String s) {
- return null; // TODO: Implement
- }
-
- public String getServerInfo() {
- return null; // TODO: Implement
- }
-
- public Servlet getServlet(String s) throws ServletException {
- return null; // TODO: Implement
- }
-
- public String getServletContextName() {
- return "mock";
- }
-
- public Enumeration getServletNames() {
- return null; // TODO: Implement
- }
-
- public Enumeration getServlets() {
- return null; // TODO: Implement
- }
-
- public void log(Exception exception, String s) {
- }
-
- public void log(String s) {
- }
-
- public void log(String s, Throwable throwable) {
- }
-
- public void removeAttribute(String s) {
- attributes.remove(s);
- }
-
- public void setAttribute(String s, Object obj) {
- attributes.put(s, obj);
- }
- }
- }
-
- static class MockServletRequest implements ServletRequest {
- final private Map attributes;
-
- public MockServletRequest() {
- attributes = new HashMap();
- }
-
- public Object getAttribute(String pKey) {
- return attributes.get(pKey);
- }
-
- public Enumeration getAttributeNames() {
- return Collections.enumeration(attributes.keySet());
- }
-
- public String getCharacterEncoding() {
- return null; // TODO: Implement
- }
-
- public void setCharacterEncoding(String pMessage) throws UnsupportedEncodingException {
- // TODO: Implement
- }
-
- public int getContentLength() {
- return 0; // TODO: Implement
- }
-
- public String getContentType() {
- return null; // TODO: Implement
- }
-
- public ServletInputStream getInputStream() throws IOException {
- return null; // TODO: Implement
- }
-
- public String getParameter(String pMessage) {
- return null; // TODO: Implement
- }
-
- public Enumeration getParameterNames() {
- return null; // TODO: Implement
- }
-
- public String[] getParameterValues(String pMessage) {
- return new String[0]; // TODO: Implement
- }
-
- public Map getParameterMap() {
- return null; // TODO: Implement
- }
-
- public String getProtocol() {
- return null; // TODO: Implement
- }
-
- public String getScheme() {
- return null; // TODO: Implement
- }
-
- public String getServerName() {
- return null; // TODO: Implement
- }
-
- public int getServerPort() {
- return 0; // TODO: Implement
- }
-
- public BufferedReader getReader() throws IOException {
- return null; // TODO: Implement
- }
-
- public String getRemoteAddr() {
- return null; // TODO: Implement
- }
-
- public String getRemoteHost() {
- return null; // TODO: Implement
- }
-
- public void setAttribute(String pKey, Object pValue) {
- attributes.put(pKey, pValue);
- }
-
- public void removeAttribute(String pKey) {
- attributes.remove(pKey);
- }
-
- public Locale getLocale() {
- return null; // TODO: Implement
- }
-
- public Enumeration getLocales() {
- return null; // TODO: Implement
- }
-
- public boolean isSecure() {
- return false; // TODO: Implement
- }
-
- public RequestDispatcher getRequestDispatcher(String pMessage) {
- return null; // TODO: Implement
- }
-
- public String getRealPath(String pMessage) {
- return null; // TODO: Implement
- }
-
- public int getRemotePort() {
- throw new UnsupportedOperationException("Method getRemotePort not implemented");// TODO: Implement
- }
-
- public String getLocalName() {
- throw new UnsupportedOperationException("Method getLocalName not implemented");// TODO: Implement
- }
-
- public String getLocalAddr() {
- throw new UnsupportedOperationException("Method getLocalAddr not implemented");// TODO: Implement
- }
-
- public int getLocalPort() {
- throw new UnsupportedOperationException("Method getLocalPort not implemented");// TODO: Implement
- }
- }
-
- static class MockServletResponse implements ServletResponse {
- public void flushBuffer() throws IOException {
- // TODO: Implement
- }
-
- public int getBufferSize() {
- return 0; // TODO: Implement
- }
-
- public String getCharacterEncoding() {
- return null; // TODO: Implement
- }
-
- public String getContentType() {
- throw new UnsupportedOperationException("Method getContentType not implemented");// TODO: Implement
- }
-
- public Locale getLocale() {
- return null; // TODO: Implement
- }
-
- public ServletOutputStream getOutputStream() throws IOException {
- return null; // TODO: Implement
- }
-
- public PrintWriter getWriter() throws IOException {
- return null; // TODO: Implement
- }
-
- public void setCharacterEncoding(String charset) {
- throw new UnsupportedOperationException("Method setCharacterEncoding not implemented");// TODO: Implement
- }
-
- public boolean isCommitted() {
- return false; // TODO: Implement
- }
-
- public void reset() {
- // TODO: Implement
- }
-
- public void resetBuffer() {
- // TODO: Implement
- }
-
- public void setBufferSize(int pLength) {
- // TODO: Implement
- }
-
- public void setContentLength(int pLength) {
- // TODO: Implement
- }
-
- public void setContentType(String pMessage) {
- // TODO: Implement
- }
-
- public void setLocale(Locale pLocale) {
- // TODO: Implement
- }
- }
-
- static class MockFilterChain implements FilterChain {
- public void doFilter(ServletRequest pRequest, ServletResponse pResponse) throws IOException, ServletException {
- // TODO: Implement
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/GenericFilterTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/GenericFilterTest.java
deleted file mode 100755
index 1340a3d9..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/GenericFilterTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet;
-
-import org.junit.Test;
-
-import javax.servlet.*;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.junit.Assert.*;
-
-/**
- * GenericFilterTestCase
- *
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/GenericFilterTestCase.java#1 $
- */
-public final class GenericFilterTest extends FilterAbstractTest {
- protected Filter makeFilter() {
- return new GenericFilterImpl();
- }
-
- @Test
- public void testInitOncePerRequest() {
- // Default FALSE
- GenericFilter filter = new GenericFilterImpl();
-
- try {
- filter.init(makeFilterConfig());
- }
- catch (ServletException e) {
- fail(e.getMessage());
- }
-
- assertFalse("OncePerRequest should default to false", filter.oncePerRequest);
- filter.destroy();
-
- // TRUE
- filter = new GenericFilterImpl();
- Map params = new HashMap<>();
- params.put("once-per-request", "true");
-
- try {
- filter.init(makeFilterConfig(params));
- }
- catch (ServletException e) {
- fail(e.getMessage());
- }
-
- assertTrue("oncePerRequest should be true", filter.oncePerRequest);
- filter.destroy();
-
- // TRUE
- filter = new GenericFilterImpl();
- params = new HashMap<>();
- params.put("oncePerRequest", "true");
-
- try {
- filter.init(makeFilterConfig(params));
- }
- catch (ServletException e) {
- fail(e.getMessage());
- }
-
- assertTrue("oncePerRequest should be true", filter.oncePerRequest);
- filter.destroy();
- }
-
- @Test
- public void testFilterOnlyOnce() {
- final GenericFilterImpl filter = new GenericFilterImpl();
- filter.setOncePerRequest(true);
-
- try {
- filter.init(makeFilterConfig());
- }
- catch (ServletException e) {
- fail(e.getMessage());
- }
-
- FilterChain chain = new MyFilterChain(new Filter[] {filter, filter, filter});
-
- try {
- chain.doFilter(makeRequest(), makeResponse());
- }
- catch (IOException | ServletException e) {
- fail(e.getMessage());
- }
-
- assertEquals("Filter was invoked more than once!", 1, filter.invocationCount);
-
- filter.destroy();
- }
-
- @Test
- public void testFilterMultiple() {
- final GenericFilterImpl filter = new GenericFilterImpl();
-
- try {
- filter.init(makeFilterConfig());
- }
- catch (ServletException e) {
- fail(e.getMessage());
- }
-
- FilterChain chain = new MyFilterChain(new Filter[] {
- filter, filter, filter, filter, filter
- });
-
- try {
- chain.doFilter(makeRequest(), makeResponse());
- }
- catch (IOException | ServletException e) {
- fail(e.getMessage());
- }
-
- assertEquals("Filter was invoked not invoked five times!", 5, filter.invocationCount);
-
- filter.destroy();
- }
-
- private static class GenericFilterImpl extends GenericFilter {
- int invocationCount;
- protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException, ServletException {
- invocationCount++;
- pChain.doFilter(pRequest, pResponse);
- }
- }
-
- private static class MyFilterChain implements FilterChain {
-
- Filter[] mFilters;
- int mCurrentFilter;
-
- public MyFilterChain(Filter[] pFilters) {
- if (pFilters == null) {
- throw new IllegalArgumentException("filters == null");
- }
- mFilters = pFilters;
- mCurrentFilter = 0;
- }
-
- public void doFilter(ServletRequest pRequest, ServletResponse pResponse) throws IOException, ServletException {
- if (mCurrentFilter < mFilters.length) {
- mFilters[mCurrentFilter++].doFilter(pRequest, pResponse, this);
- }
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletAttributesMapAdapterContextTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletAttributesMapAdapterContextTest.java
deleted file mode 100755
index 6f88a2b4..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletAttributesMapAdapterContextTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2013, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet;
-
-import com.twelvemonkeys.util.MapAbstractTest;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import javax.servlet.ServletContext;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.Mockito.mock;
-
-/**
- * ServletConfigMapAdapterTestCase
- *
- *
- * @author Harald Kuhr
- * @version $Id: ServletAttributesMapAdapterTestCase.java#1 $
- */
-public class ServletAttributesMapAdapterContextTest extends MapAbstractTest {
- private static final String ATTRIB_VALUE_ETAG = "\"1234567890abcdef\"";
- private static final Date ATTRIB_VALUE_DATE = new Date();
- private static final List ATTRIB_VALUE_FOO = Arrays.asList(1, 2);
-
- @Override
- public boolean isTestSerialization() {
- return false;
- }
-
- @Override
- public boolean isAllowNullKey() {
- return false; // Makes no sense...
- }
-
- @Override
- public boolean isAllowNullValue() {
- return false; // Should be allowed, but the tests don't handle the put(foo, null) == remove(foo) semantics
- }
-
- public Map makeEmptyMap() {
- MockServletContextImpl context = mock(MockServletContextImpl.class, Mockito.CALLS_REAL_METHODS);
- context.attributes = createAttributes(false);
-
- return new ServletAttributesMapAdapter(context);
- }
-
- @Override
- public Map makeFullMap() {
- MockServletContextImpl context = mock(MockServletContextImpl.class, Mockito.CALLS_REAL_METHODS);
- context.attributes = createAttributes(true);
-
- return new ServletAttributesMapAdapter(context);
- }
-
- private Map createAttributes(boolean initialValues) {
- Map map = new ConcurrentHashMap<>();
-
- if (initialValues) {
- String[] sampleKeys = (String[]) getSampleKeys();
- for (int i = 0; i < sampleKeys.length; i++) {
- map.put(sampleKeys[i], getSampleValues()[i]);
- }
- }
-
- return map;
- }
-
- @Override
- public Object[] getSampleKeys() {
- return new String[] {"Date", "ETag", "X-Foo"};
- }
-
- @Override
- public Object[] getSampleValues() {
- return new Object[] {ATTRIB_VALUE_DATE, ATTRIB_VALUE_ETAG, ATTRIB_VALUE_FOO};
- }
-
- @Override
- public Object[] getNewSampleValues() {
- // Needs to be same length but different values
- return new Object[] {new Date(-1L), "foo/bar", Arrays.asList(2, 3, 4)};
- }
-
- @Test
- @SuppressWarnings("unchecked")
- @Override
- public void testMapPutNullValue() {
- // Special null semantics
- resetFull();
-
- int size = map.size();
- String key = getClass().getName() + ".someNewKey";
- map.put(key, null);
- assertEquals(size, map.size());
- assertFalse(map.containsKey(key));
-
- map.put(getSampleKeys()[0], null);
- assertEquals(size - 1, map.size());
- assertFalse(map.containsKey(getSampleKeys()[0]));
-
- map.remove(getSampleKeys()[1]);
- assertEquals(size - 2, map.size());
- assertFalse(map.containsKey(getSampleKeys()[1]));
- }
-
- private static abstract class MockServletContextImpl implements ServletContext {
- Map attributes;
-
- public Object getAttribute(String name) {
- return attributes.get(name);
- }
-
- public Enumeration getAttributeNames() {
- return Collections.enumeration(attributes.keySet());
- }
-
- public void setAttribute(String name, Object o) {
- if (o == null) {
- attributes.remove(name);
- }
- else {
- attributes.put(name, o);
- }
- }
-
- public void removeAttribute(String name) {
- attributes.remove(name);
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletAttributesMapAdapterRequestTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletAttributesMapAdapterRequestTest.java
deleted file mode 100755
index 765564a7..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletAttributesMapAdapterRequestTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2013, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet;
-
-import com.twelvemonkeys.util.MapAbstractTest;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import javax.servlet.ServletRequest;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.Mockito.mock;
-
-/**
- * ServletConfigMapAdapterTestCase
- *
- *
- * @author Harald Kuhr
- * @version $Id: ServletAttributesMapAdapterTestCase.java#1 $
- */
-public class ServletAttributesMapAdapterRequestTest extends MapAbstractTest {
- private static final String ATTRIB_VALUE_ETAG = "\"1234567890abcdef\"";
- private static final Date ATTRIB_VALUE_DATE = new Date();
- private static final List ATTRIB_VALUE_FOO = Arrays.asList(1, 2);
-
- @Override
- public boolean isTestSerialization() {
- return false;
- }
-
- @Override
- public boolean isAllowNullKey() {
- return false; // Makes no sense...
- }
-
- @Override
- public boolean isAllowNullValue() {
- return false; // Should be allowed, but the tests don't handle the put(foo, null) == remove(foo) semantics
- }
-
- public Map makeEmptyMap() {
- MockServletRequestImpl request = mock(MockServletRequestImpl.class, Mockito.CALLS_REAL_METHODS);
- request.attributes = createAttributes(false);
-
- return new ServletAttributesMapAdapter(request);
- }
-
- @Override
- public Map makeFullMap() {
- MockServletRequestImpl request = mock(MockServletRequestImpl.class, Mockito.CALLS_REAL_METHODS);
- request.attributes = createAttributes(true);
-
- return new ServletAttributesMapAdapter(request);
- }
-
- private Map createAttributes(boolean initialValues) {
- Map map = new ConcurrentHashMap<>();
-
- if (initialValues) {
- String[] sampleKeys = (String[]) getSampleKeys();
- for (int i = 0; i < sampleKeys.length; i++) {
- map.put(sampleKeys[i], getSampleValues()[i]);
- }
- }
-
- return map;
- }
-
- @Override
- public Object[] getSampleKeys() {
- return new String[] {"Date", "ETag", "X-Foo"};
- }
-
- @Override
- public Object[] getSampleValues() {
- return new Object[] {ATTRIB_VALUE_DATE, ATTRIB_VALUE_ETAG, ATTRIB_VALUE_FOO};
- }
-
- @Override
- public Object[] getNewSampleValues() {
- // Needs to be same length but different values
- return new Object[] {new Date(-1L), "foo/bar", Arrays.asList(2, 3, 4)};
- }
-
- @Test
- @SuppressWarnings("unchecked")
- @Override
- public void testMapPutNullValue() {
- // Special null semantics
- resetFull();
-
- int size = map.size();
- String key = getClass().getName() + ".someNewKey";
- map.put(key, null);
- assertEquals(size, map.size());
- assertFalse(map.containsKey(key));
-
- map.put(getSampleKeys()[0], null);
- assertEquals(size - 1, map.size());
- assertFalse(map.containsKey(getSampleKeys()[0]));
-
- map.remove(getSampleKeys()[1]);
- assertEquals(size - 2, map.size());
- assertFalse(map.containsKey(getSampleKeys()[1]));
- }
-
- private static abstract class MockServletRequestImpl implements ServletRequest {
- Map attributes;
-
- public Object getAttribute(String name) {
- return attributes.get(name);
- }
-
- public Enumeration getAttributeNames() {
- return Collections.enumeration(attributes.keySet());
- }
-
- public void setAttribute(String name, Object o) {
- if (o == null) {
- attributes.remove(name);
- }
- else {
- attributes.put(name, o);
- }
- }
-
- public void removeAttribute(String name) {
- attributes.remove(name);
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfigExceptionTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfigExceptionTest.java
deleted file mode 100755
index f49efb72..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfigExceptionTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet;
-
-import com.twelvemonkeys.io.NullOutputStream;
-import org.junit.Test;
-
-import java.io.PrintWriter;
-
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-
-/**
- * ServletConfigExceptionTestCase
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfigExceptionTestCase.java#2 $
- */
-public class ServletConfigExceptionTest {
- @Test
- public void testThrowCatchPrintStacktrace() {
- try {
- throw new ServletConfigException("FooBar!");
- }
- catch (ServletConfigException e) {
- e.printStackTrace(new PrintWriter(new NullOutputStream()));
- }
- }
-
- @Test
- public void testThrowCatchGetNoCause() {
- try {
- throw new ServletConfigException("FooBar!");
- }
- catch (ServletConfigException e) {
- assertNull(e.getRootCause()); // Old API
- assertNull(e.getCause());
-
- e.printStackTrace(new PrintWriter(new NullOutputStream()));
- }
- }
-
- @Test
- public void testThrowCatchInitCauseNull() {
- try {
- ServletConfigException e = new ServletConfigException("FooBar!");
- e.initCause(null);
- throw e;
- }
- catch (ServletConfigException e) {
- assertNull(e.getRootCause()); // Old API
- assertNull(e.getCause());
-
- e.printStackTrace(new PrintWriter(new NullOutputStream()));
- }
- }
-
- @Test
- public void testThrowCatchInitCause() {
- //noinspection ThrowableInstanceNeverThrown
- Exception cause = new Exception();
- try {
- ServletConfigException exception = new ServletConfigException("FooBar!");
- exception.initCause(cause);
- throw exception;
- }
- catch (ServletConfigException e) {
- // NOTE: We don't know how the superclass is implemented, so we assume nothing here
- //assertEquals(null, e.getRootCause()); // Old API
- assertSame(cause, e.getCause());
-
- e.printStackTrace(new PrintWriter(new NullOutputStream()));
- }
- }
-
- @Test
- public void testThrowCatchGetNullCause() {
- try {
- throw new ServletConfigException("FooBar!", null);
- }
- catch (ServletConfigException e) {
- assertNull(e.getRootCause()); // Old API
- assertNull(e.getCause());
-
- e.printStackTrace(new PrintWriter(new NullOutputStream()));
- }
- }
-
- @Test
- public void testThrowCatchGetCause() {
- IllegalStateException cause = new IllegalStateException();
- try {
- throw new ServletConfigException("FooBar caused by stupid API!", cause);
- }
- catch (ServletConfigException e) {
- assertSame(cause, e.getRootCause()); // Old API
- assertSame(cause, e.getCause());
-
- e.printStackTrace(new PrintWriter(new NullOutputStream()));
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfigMapAdapterTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfigMapAdapterTest.java
deleted file mode 100755
index 4f972f81..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfigMapAdapterTest.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet;
-
-import com.twelvemonkeys.util.MapAbstractTest;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-import javax.servlet.*;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.*;
-
-/**
- * ServletConfigMapAdapterTestCase
- *
- *
- * @author Harald Kuhr
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfigMapAdapterTestCase.java#3 $
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({AbstractServletConfigMapAdapterTest.ServletConfigMapTest.class, AbstractServletConfigMapAdapterTest.FilterConfigMapTest.class, AbstractServletConfigMapAdapterTest.ServletContextMapTest.class})
-public final class ServletConfigMapAdapterTest {
-}
-
-abstract class AbstractServletConfigMapAdapterTest extends MapAbstractTest {
-
- public boolean isPutAddSupported() {
- return false;
- }
-
- public boolean isPutChangeSupported() {
- return false;
- }
-
- public boolean isRemoveSupported() {
- return false;
- }
-
- public boolean isSetValueSupported() {
- return false;
- }
-
- private static class TestConfig implements ServletConfig, FilterConfig, ServletContext, Serializable, Cloneable {
- Map map = new HashMap();
-
- public String getServletName() {
- return "dummy"; // Not needed for this test
- }
-
- public String getFilterName() {
- return getServletName();
- }
-
- public String getServletContextName() {
- return getServletName();
- }
-
-
- public ServletContext getServletContext() {
- throw new UnsupportedOperationException("Method getSerlvetContext not implemented");
- }
-
- public String getInitParameter(String s) {
- return (String) map.get(s);
- }
-
- public Enumeration getInitParameterNames() {
- //noinspection unchecked
- return Collections.enumeration(map.keySet());
- }
-
- public ServletContext getContext(String uripath) {
- throw new UnsupportedOperationException("Method getContext not implemented");
- }
-
- public int getMajorVersion() {
- throw new UnsupportedOperationException("Method getMajorVersion not implemented");
- }
-
- public int getMinorVersion() {
- throw new UnsupportedOperationException("Method getMinorVersion not implemented");
- }
-
- public String getMimeType(String file) {
- throw new UnsupportedOperationException("Method getMimeType not implemented");
- }
-
- public Set getResourcePaths(String path) {
- throw new UnsupportedOperationException("Method getResourcePaths not implemented");
- }
-
- public URL getResource(String path) throws MalformedURLException {
- throw new UnsupportedOperationException("Method getResource not implemented");
- }
-
- public InputStream getResourceAsStream(String path) {
- throw new UnsupportedOperationException("Method getResourceAsStream not implemented");
- }
-
- public RequestDispatcher getRequestDispatcher(String path) {
- throw new UnsupportedOperationException("Method getRequestDispatcher not implemented");
- }
-
- public RequestDispatcher getNamedDispatcher(String name) {
- throw new UnsupportedOperationException("Method getNamedDispatcher not implemented");
- }
-
- public Servlet getServlet(String name) throws ServletException {
- throw new UnsupportedOperationException("Method getServlet not implemented");
- }
-
- public Enumeration getServlets() {
- throw new UnsupportedOperationException("Method getServlets not implemented");
- }
-
- public Enumeration getServletNames() {
- throw new UnsupportedOperationException("Method getServletNames not implemented");
- }
-
- public void log(String msg) {
- throw new UnsupportedOperationException("Method log not implemented");
- }
-
- public void log(Exception exception, String msg) {
- throw new UnsupportedOperationException("Method log not implemented");
- }
-
- public void log(String message, Throwable throwable) {
- throw new UnsupportedOperationException("Method log not implemented");
- }
-
- public String getRealPath(String path) {
- throw new UnsupportedOperationException("Method getRealPath not implemented");
- }
-
- public String getServerInfo() {
- throw new UnsupportedOperationException("Method getServerInfo not implemented");
- }
-
- public Object getAttribute(String name) {
- throw new UnsupportedOperationException("Method getAttribute not implemented");
- }
-
- public Enumeration getAttributeNames() {
- throw new UnsupportedOperationException("Method getAttributeNames not implemented");
- }
-
- public void setAttribute(String name, Object object) {
- throw new UnsupportedOperationException("Method setAttribute not implemented");
- }
-
- public void removeAttribute(String name) {
- throw new UnsupportedOperationException("Method removeAttribute not implemented");
- }
- }
-
- public static final class ServletConfigMapTest extends AbstractServletConfigMapAdapterTest {
-
- public Map makeEmptyMap() {
- ServletConfig config = new TestConfig();
- return new ServletConfigMapAdapter(config);
- }
-
- public Map makeFullMap() {
- ServletConfig config = new TestConfig();
- addSampleMappings(((TestConfig) config).map);
- return new ServletConfigMapAdapter(config);
- }
- }
-
- public static final class FilterConfigMapTest extends AbstractServletConfigMapAdapterTest {
-
- public Map makeEmptyMap() {
- FilterConfig config = new TestConfig();
- return new ServletConfigMapAdapter(config);
- }
-
- public Map makeFullMap() {
- FilterConfig config = new TestConfig();
- addSampleMappings(((TestConfig) config).map);
- return new ServletConfigMapAdapter(config);
- }
- }
-
- public static final class ServletContextMapTest extends AbstractServletConfigMapAdapterTest {
-
- public Map makeEmptyMap() {
- ServletContext config = new TestConfig();
- return new ServletConfigMapAdapter(config);
- }
-
- public Map makeFullMap() {
- FilterConfig config = new TestConfig();
- addSampleMappings(((TestConfig) config).map);
- return new ServletConfigMapAdapter(config);
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfiguratorTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfiguratorTest.java
deleted file mode 100644
index 2b9820ec..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfiguratorTest.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet;
-
-import org.junit.Test;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterConfig;
-import javax.servlet.Servlet;
-import javax.servlet.ServletConfig;
-import java.util.Arrays;
-import java.util.Collections;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
-
-/**
- * ServletConfiguratorTestCase
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haraldk$
- * @version $Id: ServletConfiguratorTestCase.java,v 1.0 May 2, 2010 3:08:33 PM haraldk Exp$
- */
-public class ServletConfiguratorTest {
-
- // TODO: Test error conditions:
- // - Missing name = ... or non-bean conforming method
- // - Non-accessible? How..?
- // - Missing required value
-
- // TODO: Clean up tests to test only one thing at a time
- // - Public method
- // - Public method with override
- // - Public method overridden without annotation
- // - Protected method
- // - Protected method with override
- // - Protected method overridden without annotation
- // - Package protected method
- // - Package protected method with override
- // - Package protected method overridden without annotation
- // - Private method
- // - Multiple private methods with same signature (should invoke all, as private methods can't be overridden)
-
- @Test
- public void testConfigureAnnotatedServlet() throws ServletConfigException {
- AnnotatedServlet servlet = mock(AnnotatedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("x", "foo", "bar")));
- when(config.getInitParameter("x")).thenReturn("99");
- when(config.getInitParameter("foo")).thenReturn("Foo");
- when(config.getInitParameter("bar")).thenReturn("-1, 2, 0, 42");
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- verify(servlet, times(1)).setX(99);
- verify(servlet, times(1)).setFoo("Foo");
- verify(servlet, times(1)).configTheBar(-1, 2, 0, 42);
- }
-
- @Test
- public void testConfigureAnnotatedFilter() throws ServletConfigException {
- AnnotatedServlet servlet = mock(AnnotatedServlet.class);
-
- FilterConfig config = mock(FilterConfig.class);
- when(config.getFilterName()).thenReturn("FooFilter");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("x", "foo", "bar")));
- when(config.getInitParameter("x")).thenReturn("99");
- when(config.getInitParameter("foo")).thenReturn("Foo");
- when(config.getInitParameter("bar")).thenReturn("-1, 2, 0, 42");
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- verify(servlet, times(1)).setX(99);
- verify(servlet, times(1)).setFoo("Foo");
- verify(servlet, times(1)).configTheBar(-1, 2, 0, 42);
- }
-
- @Test
- public void testConfigurePrivateMethod() throws ServletConfigException {
- AnnotatedServlet servlet = mock(AnnotatedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.singletonList("private")));
- when(config.getInitParameter("private")).thenReturn("99");
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- assertEquals(servlet.priv, "99");
- }
-
- @Test
- public void testConfigurePrivateShadowedMethod() throws ServletConfigException {
- abstract class SubclassedServlet extends AnnotatedServlet {
- @InitParam(name = "package-private")
- abstract void setPrivate(String priv);
- }
-
- SubclassedServlet servlet = mock(SubclassedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.singletonList("private")));
- when(config.getInitParameter("private")).thenReturn("private");
- when(config.getInitParameter("package-private")).thenReturn("package");
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- assertEquals(servlet.priv, "private");
- verify(servlet, times(1)).setPrivate("package");
- }
-
- @Test
- public void testConfigureSubclassedServlet() throws ServletConfigException {
- abstract class SubclassedServlet extends AnnotatedServlet {
- @InitParam(name = "flag")
- abstract void configureMeToo(boolean flag);
- }
-
- SubclassedServlet servlet = mock(SubclassedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("x", "foo", "bar", "flag")));
- when(config.getInitParameter("x")).thenReturn("99");
- when(config.getInitParameter("foo")).thenReturn("Foo");
- when(config.getInitParameter("bar")).thenReturn("-1, 2, 0, 42");
- when(config.getInitParameter("flag")).thenReturn("true");
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- verify(servlet, times(1)).setX(99);
- verify(servlet, times(1)).setFoo("Foo");
- verify(servlet, times(1)).configTheBar(-1, 2, 0, 42);
- verify(servlet, times(1)).configureMeToo(true);
- }
-
- @Test
- public void testConfigureAnnotatedServletWithLispStyle() throws ServletConfigException {
- abstract class SubclassedServlet extends AnnotatedServlet {
- @InitParam(name = "the-explicit-x")
- abstract public void setExplicitX(int x);
-
- @InitParam
- abstract public void setTheOtherX(int x);
- }
-
- SubclassedServlet servlet = mock(SubclassedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("the-explicit-x", "the-other-x")));
- when(config.getInitParameter("the-explicit-x")).thenReturn("-1");
- when(config.getInitParameter("the-other-x")).thenReturn("42");
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- verify(servlet, times(1)).setExplicitX(-1);
- verify(servlet, times(1)).setTheOtherX(42);
- }
-
- @Test
- public void testConfigureSubclassedServletWithOverride() throws ServletConfigException {
- abstract class SubclassedServlet extends AnnotatedServlet {
- @Override
- @InitParam(name = "y")
- public void setX(int x) {
- }
- }
-
- SubclassedServlet servlet = mock(SubclassedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("x", "y")));
- when(config.getInitParameter("x")).thenReturn("99");
- when(config.getInitParameter("y")).thenReturn("-66");
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- verify(servlet, times(1)).setX(-66);
- verify(servlet, times(1)).setX(anyInt()); // We don't want multiple invocations, only the overridden method
- }
-
- @Test
- public void testConfigureSubclassedServletWithOverrideNoParam() throws ServletConfigException {
- // NOTE: We must allow overriding the methods without annotation present, in order to allow CGLib/proxies of the class...
- abstract class SubclassedServlet extends AnnotatedServlet {
- @Override
- @InitParam(name = "")
- public void setX(int x) {
- }
-
- @Override
- public void setFoo(String foo) {
- }
- }
-
- SubclassedServlet servlet = mock(SubclassedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("x", "foo")));
- when(config.getInitParameter("x")).thenReturn("99");
- when(config.getInitParameter("foo")).thenReturn("Foo");
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- verify(servlet, never()).setX(anyInt());
- verify(servlet, times(1)).setFoo("Foo");
- verify(servlet, times(1)).setFoo(anyString()); // We don't want multiple invocations
- }
-
- // Test interface
- @Test
- public void testConfigureServletWithInterface() throws ServletConfigException {
- abstract class InterfacedServlet implements Servlet, Annotated {
- }
-
- InterfacedServlet servlet = mock(InterfacedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.singletonList("foo")));
- when(config.getInitParameter("foo")).thenReturn("Foo");
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- verify(servlet, times(1)).annotated("Foo");
- }
-
- // TODO: Test override/shadow of package protected method outside package
-
- @Test
- public void testRequiredParameter() throws ServletConfigException {
- abstract class SubclassedServlet extends AnnotatedServlet {
- @InitParam(required = true)
- abstract void setRequired(String value);
- }
-
- SubclassedServlet servlet = mock(SubclassedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.singletonList("required")));
- when(config.getInitParameter("required")).thenReturn("the required value");
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- verify(servlet, times(1)).setRequired("the required value");
- verify(servlet, times(1)).setRequired(anyString()); // We don't want multiple invocations
- }
-
- @Test
- public void testMissingParameter() throws ServletConfigException {
- abstract class SubclassedServlet extends AnnotatedServlet {
- @InitParam()
- abstract void setNonRequired(String value);
- }
-
- SubclassedServlet servlet = mock(SubclassedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.emptyList()));
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- verify(servlet, never()).setNonRequired(anyString()); // Simply not configured
- }
-
- @Test(expected = ServletConfigException.class)
- public void testMissingRequiredParameter() throws ServletConfigException {
- abstract class SubclassedServlet extends AnnotatedServlet {
- @Override
- @InitParam(required = true)
- protected abstract void setFoo(String value);
- }
-
- SubclassedServlet servlet = mock(SubclassedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.emptyList()));
-
- ServletConfigurator.configure(servlet, config); // Should throw exception
- }
-
- @Test
- public void testMissingParameterDefaultValue() throws ServletConfigException {
- abstract class SubclassedServlet extends AnnotatedServlet {
- @InitParam(defaultValue = "1, 2, 3")
- abstract void setNonRequired(int[] value);
- }
-
- SubclassedServlet servlet = mock(SubclassedServlet.class);
-
- ServletConfig config = mock(ServletConfig.class);
- when(config.getServletName()).thenReturn("FooServlet");
- when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.emptyList()));
-
- ServletConfigurator.configure(servlet, config);
-
- // Verify
- verify(servlet, times(1)).setNonRequired(new int[] {1, 2, 3});
- verify(servlet, times(1)).setNonRequired((int[]) any());
- }
-
-
- public interface Annotated {
- @InitParam(name = "foo")
- void annotated(String an);
- }
-
- public abstract class AnnotatedServlet implements Servlet, Filter {
- String priv;
-
- // Implicit name "x"
- @InitParam
- public abstract void setX(int x);
-
- // Implicit name "foo"
- @InitParam
- protected abstract void setFoo(String foo);
-
- @InitParam(name = "bar")
- abstract void configTheBar(int... bar);
-
- @InitParam(name = "private")
- private void setPrivate(String priv) {
- this.priv = priv;
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletHeadersMapAdapterTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletHeadersMapAdapterTest.java
deleted file mode 100755
index c930aac3..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletHeadersMapAdapterTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet;
-
-import com.twelvemonkeys.util.MapAbstractTest;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.*;
-
-import static org.mockito.Mockito.when;
-
-/**
- * ServletConfigMapAdapterTest
- *
- *
- * @author Harald Kuhr
- * @version $Id: ServletHeadersMapAdapterTest.java#1 $
- */
-public class ServletHeadersMapAdapterTest extends MapAbstractTest {
- private static final List HEADER_VALUE_ETAG = Collections.singletonList("\"1234567890abcdef\"");
- private static final List HEADER_VALUE_DATE = Collections.singletonList(new Date().toString());
- private static final List HEADER_VALUE_FOO = Arrays.asList("one", "two");
-
- public boolean isPutAddSupported() {
- return false;
- }
-
- public boolean isPutChangeSupported() {
- return false;
- }
-
- public boolean isRemoveSupported() {
- return false;
- }
-
- public boolean isSetValueSupported() {
- return false;
- }
-
- @Override
- public boolean isTestSerialization() {
- return false;
- }
-
- public Map makeEmptyMap() {
- HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
- when(request.getHeaderNames()).thenAnswer(returnEnumeration(Collections.emptyList()));
-
- return new ServletHeadersMapAdapter(request);
- }
-
- @Override
- public Map makeFullMap() {
- HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
- when(request.getHeaderNames()).thenAnswer(returnEnumeration(Arrays.asList(getSampleKeys())));
- when(request.getHeaders("Date")).thenAnswer(returnEnumeration(HEADER_VALUE_DATE));
- when(request.getHeaders("ETag")).thenAnswer(returnEnumeration(HEADER_VALUE_ETAG));
- when(request.getHeaders("X-Foo")).thenAnswer(returnEnumeration(HEADER_VALUE_FOO));
-
- return new ServletHeadersMapAdapter(request);
- }
-
- @Override
- public Object[] getSampleKeys() {
- return new String[] {"Date", "ETag", "X-Foo"};
- }
-
- @Override
- public Object[] getSampleValues() {
- return new Object[] {HEADER_VALUE_DATE, HEADER_VALUE_ETAG, HEADER_VALUE_FOO};
- }
-
- @Override
- public Object[] getNewSampleValues() {
- // Needs to be same length but different values
- return new Object[3];
- }
-
- protected static ReturnNewEnumeration returnEnumeration(final Collection collection) {
- return new ReturnNewEnumeration<>(collection);
- }
-
- private static class ReturnNewEnumeration implements Answer> {
- private final Collection collection;
-
- private ReturnNewEnumeration(final Collection collection) {
- this.collection = collection;
- }
-
- public Enumeration answer(InvocationOnMock invocation) throws Throwable {
- return Collections.enumeration(collection);
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletParametersMapAdapterTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletParametersMapAdapterTest.java
deleted file mode 100755
index 5ea4c4f5..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletParametersMapAdapterTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet;
-
-import com.twelvemonkeys.util.MapAbstractTest;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.*;
-
-import static org.mockito.Mockito.when;
-
-/**
- * ServletConfigMapAdapterTest
- *
- *
- * @author Harald Kuhr
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/ServletParametersMapAdapterTest.java#1 $
- */
-public class ServletParametersMapAdapterTest extends MapAbstractTest {
- private static final List PARAM_VALUE_ETAG = Collections.singletonList("\"1234567890abcdef\"");
- private static final List PARAM_VALUE_DATE = Collections.singletonList(new Date().toString());
- private static final List PARAM_VALUE_FOO = Arrays.asList("one", "two");
-
- public boolean isPutAddSupported() {
- return false;
- }
-
- public boolean isPutChangeSupported() {
- return false;
- }
-
- public boolean isRemoveSupported() {
- return false;
- }
-
- public boolean isSetValueSupported() {
- return false;
- }
-
- @Override
- public boolean isTestSerialization() {
- return false;
- }
-
- public Map makeEmptyMap() {
- HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
- when(request.getParameterNames()).thenAnswer(returnEnumeration(Collections.emptyList()));
-
- return new ServletParametersMapAdapter(request);
- }
-
- @Override
- public Map makeFullMap() {
- HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
-
- when(request.getParameterNames()).thenAnswer(returnEnumeration(Arrays.asList("tag", "date", "foo")));
- when(request.getParameterValues("date")).thenReturn(PARAM_VALUE_DATE.toArray(new String[PARAM_VALUE_DATE.size()]));
- when(request.getParameterValues("tag")).thenReturn(PARAM_VALUE_ETAG.toArray(new String[PARAM_VALUE_ETAG.size()]));
- when(request.getParameterValues("foo")).thenReturn(PARAM_VALUE_FOO.toArray(new String[PARAM_VALUE_FOO.size()]));
-
- return new ServletParametersMapAdapter(request);
- }
-
- @Override
- public Object[] getSampleKeys() {
- return new String[] {"date", "tag", "foo"};
- }
-
- @Override
- public Object[] getSampleValues() {
- return new Object[] {PARAM_VALUE_DATE, PARAM_VALUE_ETAG, PARAM_VALUE_FOO};
- }
-
- @Override
- public Object[] getNewSampleValues() {
- // Needs to be same length but different values
- return new Object[3];
- }
-
- protected static ReturnNewEnumeration returnEnumeration(final Collection collection) {
- return new ReturnNewEnumeration<>(collection);
- }
-
- private static class ReturnNewEnumeration implements Answer> {
- private final Collection collection;
-
- private ReturnNewEnumeration(final Collection collection) {
- this.collection = collection;
- }
-
- public Enumeration answer(InvocationOnMock invocation) throws Throwable {
- return Collections.enumeration(collection);
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletResponseAbsrtactTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletResponseAbsrtactTest.java
deleted file mode 100755
index 819871b7..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletResponseAbsrtactTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet;
-
-import com.twelvemonkeys.lang.ObjectAbstractTest;
-
-import javax.servlet.ServletResponse;
-
-/**
- * ServletResponseAbsrtactTestCase
- *
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/ServletResponseAbsrtactTestCase.java#1 $
- */
-public abstract class ServletResponseAbsrtactTest extends ObjectAbstractTest {
- protected Object makeObject() {
- return makeServletResponse();
- }
-
- protected abstract ServletResponse makeServletResponse();
-
- // TODO: Implement
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/TrimWhiteSpaceFilterTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/TrimWhiteSpaceFilterTest.java
deleted file mode 100755
index 498496ac..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/TrimWhiteSpaceFilterTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.twelvemonkeys.servlet;
-
-import com.twelvemonkeys.io.OutputStreamAbstractTest;
-import org.junit.Test;
-
-import javax.servlet.Filter;
-import javax.servlet.ServletResponse;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * TrimWhiteSpaceFilterTestCase
- *
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/TrimWhiteSpaceFilterTestCase.java#1 $
- */
-public class TrimWhiteSpaceFilterTest extends FilterAbstractTest {
- protected Filter makeFilter() {
- return new TrimWhiteSpaceFilter();
- }
-
- public static final class TrimWSFilterOutputStreamTest extends OutputStreamAbstractTest {
- protected OutputStream makeObject() {
- // NOTE: ByteArrayOutputStream does not implement flush or close...
- return makeOutputStream(new ByteArrayOutputStream(16));
- }
-
- protected OutputStream makeOutputStream(OutputStream pWrapped) {
- return new TrimWhiteSpaceFilter.TrimWSFilterOutputStream(pWrapped);
- }
-
- @Test
- public void testTrimWSOnlyWS() throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream(64);
- OutputStream trim = makeOutputStream(out);
-
- String input = " \n\n\t \t" + (char) 0x0a + ' ' + (char) 0x0d + "\r ";
-
- trim.write(input.getBytes());
- trim.flush();
- trim.close();
-
- assertEquals("Should be trimmed", "\"\"", '"' + new String(out.toByteArray()) + '"');
- }
-
- @Test
- public void testTrimWSLeading() throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream(64);
- OutputStream trim = makeOutputStream(out);
-
- byte[] input = " \n\n\t \t".getBytes();
- String trimmed = "\n "; // TODO: This is pr spec (the trailing space). But probably quite stupid...
-
- trim.write(input);
- trim.flush();
- trim.close();
-
- assertEquals("Should be trimmed", '"' + trimmed + '"', '"' + new String(out.toByteArray()) + '"');
- }
-
- @Test
- public void testTrimWSOffsetLength() throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream(64);
- OutputStream trim = makeOutputStream(out);
-
- // Kindly generated by http://lipsum.org/ :-)
- byte[] input = (" \n\tLorem ipsum dolor sit amet, consectetuer adipiscing elit.\n\r\n\r" +
- "Etiam arcu neque, \n\rmalesuada blandit,\t\n\r\n\r\n\n\n\r\n\r\r\n\n\t rutrum quis, molestie at, diam.\n" +
- " Nulla elementum elementum eros.\n \t\t\n\r" +
- "Ut rhoncus, turpis in pellentesque volutpat, sapien sem accumsan augue, a scelerisque nibh erat vel magna.\n" +
- " Phasellus diam orci, dignissim et, gravida vitae, venenatis eu, elit.\n" +
- "\t\t\tSuspendisse dictum enim at nisl. Integer magna erat, viverra sit amet, consectetuer nec, accumsan ut, mi.\n" +
- "\n\r\r\r\n\rNunc ultricies \n\n\n consectetuer mauris. " +
- "Nulla lectus mauris, viverra ac, pulvinar a, commodo quis, nulla.\n " +
- "Ut eget nulla. In est dolor, convallis \t non, tincidunt \tvestibulum, porttitor et, eros.\n " +
- "\t\t \t \n\rDonec vehicula ultrices nisl.").getBytes();
-
- String trimmed = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n" +
- "Etiam arcu neque, malesuada blandit,\trutrum quis, molestie at, diam.\n" +
- "Nulla elementum elementum eros.\n" +
- "Ut rhoncus, turpis in pellentesque volutpat, sapien sem accumsan augue, a scelerisque nibh erat vel magna.\n" +
- "Phasellus diam orci, dignissim et, gravida vitae, venenatis eu, elit.\n" +
- "Suspendisse dictum enim at nisl. Integer magna erat, viverra sit amet, consectetuer nec, accumsan ut, mi.\n" +
- "Nunc ultricies consectetuer mauris. Nulla lectus mauris, viverra ac, pulvinar a, commodo quis, nulla.\n" +
- "Ut eget nulla. In est dolor, convallis non, tincidunt vestibulum, porttitor et, eros.\n" +
- "Donec vehicula ultrices nisl.";
-
- int chunkLenght = 5;
- int bytesLeft = input.length;
- while (bytesLeft > chunkLenght) {
- trim.write(input, input.length - bytesLeft, chunkLenght);
- bytesLeft -= chunkLenght;
- }
- trim.write(input, input.length - bytesLeft, bytesLeft);
-
- trim.flush();
- trim.close();
-
- assertEquals("Should be trimmed", '"' + trimmed + '"', '"' + new String(out.toByteArray()) + '"');
- }
-
- // TODO: Test that we DON'T remove too much...
- }
-
- public static final class TrimWSServletResponseWrapperTest extends ServletResponseAbsrtactTest {
- protected ServletResponse makeServletResponse() {
- return new TrimWhiteSpaceFilter.TrimWSServletResponseWrapper(new MockServletResponse());
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/cache/HTTPCacheTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/cache/HTTPCacheTest.java
deleted file mode 100755
index 6a84e130..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/cache/HTTPCacheTest.java
+++ /dev/null
@@ -1,1176 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.cache;
-
-import com.twelvemonkeys.net.HTTPUtil;
-
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.TestName;
-import org.mockito.InOrder;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletResponse;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
-
-/**
- * HTTPCacheTest
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/cache/HTTPCacheTestCase.java#2 $
- */
-public class HTTPCacheTest {
- @Rule
- public final TestName name = new TestName();
-
- @Rule
- public final TemporaryFolder temporaryFolder = new TemporaryFolder();
-
- private File createTempRoot() throws IOException {
- return temporaryFolder.newFolder("cache-test");
- }
-
- private CacheRequest configureRequest(CacheRequest request, String pRequestURI) {
- return configureRequest(request, "GET", pRequestURI, null, null);
- }
-
- private CacheRequest configureRequest(CacheRequest request, String pMethod, String pRequestURI, Map> pParameters, final Map> pHeaders) {
- reset(request);
-
- when(request.getRequestURI()).thenReturn(URI.create(pRequestURI));
- when(request.getParameters()).thenReturn(pParameters == null ? Collections.>emptyMap() : pParameters);
- when(request.getHeaders()).thenReturn(pHeaders == null ? Collections.>emptyMap() : pHeaders);
- when(request.getMethod()).thenReturn(pMethod);
-
- return request;
- }
-
- @SuppressWarnings("deprecation")
- @Test
- public void testCreateNegativeNoName() {
- try {
- new HTTPCache(null, mock(ServletContext.class), 500, 0, 10, true);
- fail("Expected creation failure, no name");
- }
- catch (IllegalArgumentException expected) {
- String message = expected.getMessage().toLowerCase();
- assertTrue(message.contains("name"));
- assertTrue(message.contains("null"));
- }
-
- try {
- new HTTPCache("", mock(ServletContext.class), 500, 0, 10, true);
- fail("Expected creation failure, empty name");
- }
- catch (IllegalArgumentException expected) {
- String message = expected.getMessage().toLowerCase();
- assertTrue(message.contains("name"));
- assertTrue(message.contains("empty"));
- }
- }
-
- @SuppressWarnings("deprecation")
- @Test
- public void testCreateNegativeNoContext() {
- try {
- new HTTPCache("Dummy", null, 500, 0, 10, true);
- fail("Expected creation failure, no context");
- }
- catch (IllegalArgumentException expected) {
- String message = expected.getMessage().toLowerCase();
- assertTrue(message.contains("context"));
- assertTrue(message.contains("null"));
- }
-
- }
-
- @Test
- public void testCreateNegativeNoTempFolder() {
- try {
- new HTTPCache(null, 500, 0, 10, true);
- fail("Expected creation failure, no temp folder");
- }
- catch (IllegalArgumentException expected) {
- String message = expected.getMessage().toLowerCase();
- assertTrue(message.contains("temp"));
- assertTrue(message.contains("folder"));
- assertTrue(message.contains("null"));
- }
- }
-
- @Test
- public void testCreateNegativeValues() throws IOException {
- File tempRoot = createTempRoot();
-
- try {
- new HTTPCache(tempRoot, -1, 0, 10, true);
- fail("Expected creation failure");
- }
- catch (IllegalArgumentException expected) {
- String message = expected.getMessage().toLowerCase();
- assertTrue(message.contains("negative"));
- assertTrue(message.contains("expiry time"));
- }
-
- try {
- new HTTPCache(tempRoot, 1000, -1, 10, false);
- fail("Expected creation failure");
- }
- catch (IllegalArgumentException expected) {
- String message = expected.getMessage().toLowerCase();
- assertTrue(message.contains("negative"));
- assertTrue(message.contains("cache size"));
- }
-
- try {
- new HTTPCache(tempRoot, 1000, 128, -1, true);
- fail("Expected creation failure");
- }
- catch (IllegalArgumentException expected) {
- String message = expected.getMessage().toLowerCase();
- assertTrue(message.contains("negative"));
- assertTrue(message.contains("number"));
- }
- }
-
- @Test
- public void testCreate() throws IOException {
- new HTTPCache(createTempRoot(), 500, 0, 10, true);
- }
-
- @SuppressWarnings("deprecation")
- @Test
- public void testCreateServletContext() throws IOException {
- ServletContext mockContext = mock(ServletContext.class);
- // Currently context is used for tempdir and logging
- when(mockContext.getAttribute(eq("javax.servlet.context.tempdir"))).thenReturn(createTempRoot());
-
- new HTTPCache("cache", mockContext, 500, 0, 10, true);
- }
-
- @Test
- public void testCacheableRequest() throws IOException, CacheException {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI());
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
-
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- private String createRequestURI() {
- return "http://www.foo.com/" + name.getMethodName() + ".bar";
- }
-
- @Test
- public void testCacheableRequestWithParameters() throws IOException, CacheException {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- Map> parameters = new HashMap<>();
- parameters.put("foo", Collections.singletonList("bar"));
- parameters.put("params", Arrays.asList("une", "due", "tres"));
- CacheRequest request = configureRequest(mock(CacheRequest.class), "GET", createRequestURI(), parameters, null);
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class, "MY-RESOLVER-1");
- doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- @Test
- public void testCacheablePersistentRepeatedRequest() throws IOException, CacheException {
- File tempRoot = createTempRoot();
- HTTPCache cache = new HTTPCache(tempRoot, 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI());
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class, "MY-RESOLVER-2");
- doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
-
- // Reset
- result.reset();
- reset(response);
- when(response.getOutputStream()).thenReturn(result);
-
- // Test request again, make sure resolve is executed exactly once
- HTTPCache cache2 = new HTTPCache(tempRoot, 60000, 1024 * 1024, 10, true);
- cache2.doCached(request, response, resolver);
-
- // Test that second response is equal to first
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- @Test
- public void testCacheableRepeatedRequest() throws IOException, CacheException {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI());
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class, "MY-RESOLVER-3");
- doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that reponse is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
-
- // Reset
- result.reset();
- reset(response);
-
- // Reconfigure
- when(response.getOutputStream()).thenReturn(result);
-
- // Test request again, make sure resolve is executed exactly once
- cache.doCached(request, response, resolver);
-
- // Test that second response is equal to first
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- @Test
- public void testNonCacheableRequestHeader() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), "GET", createRequestURI(), null, Collections.singletonMap("Cache-Control", Collections.singletonList("no-store")));
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // TODO: How do we know that the response was NOT cached?
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- @Test
- public void testNonCacheableRequestHeaderRepeated() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
- String requestURI = createRequestURI();
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), requestURI);
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Reset
- result.reset();
- reset(response, resolver);
-
- // Reconfigure
- request = configureRequest(request, "GET", requestURI, null, Collections.singletonMap("Cache-Control", Collections.singletonList("no-cache")));
- when(response.getOutputStream()).thenReturn(result);
- doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- value[3] = 'B'; // Make sure we have a different value second time
-
- // This request should not be cached
- cache.doCached(request, response, resolver);
-
- // Verify that second response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- @Test
- public void testNonCacheableResponseHeader() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI());
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, Collections.singletonMap("Cache-Control", Collections.singletonList("no-cache"))))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader(eq("Cache-Control"), eq("no-cache"));
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- @Test
- public void testNonCacheableResponseHeaderRepeated() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI());
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, Collections.singletonMap("Cache-Control", Collections.singletonList("no-store"))))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader(eq("Cache-Control"), eq("no-store"));
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Reset
- result.reset();
- reset(response, resolver);
-
- // Reconfigure
- when(response.getOutputStream()).thenReturn(result);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, Collections.singletonMap("Cache-Control", Collections.singletonList("no-store"))))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- value[3] = 'B';
-
- // Repeat invocation
- cache.doCached(request, response, resolver);
-
- // Verify that reponse is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader(eq("Cache-Control"), eq("no-store"));
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- // Test non-cacheable response
- @Test
- public void testNonCacheableResponse() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI());
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, value, null))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- // Test non-cacheable response
- @Test
- public void testNonCacheableResponseRepeated() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI());
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, value, null))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that reponse is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Reset
- result.reset();
- reset(response, resolver);
-
- // Reconfigure
- when(response.getOutputStream()).thenReturn(result);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, value, null))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- value[3] = 'B';
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- // Verify new resolve
- verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- // Test that request headers are forwarded to resolver...
- @Test
- public void testRequestHeadersForwarded() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- final Map> headers = new LinkedHashMap<>();
- headers.put("Cache-Control", Collections.singletonList("no-cache"));
- headers.put("X-Custom", Arrays.asList("FOO", "BAR"));
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), "HEAD", createRequestURI(), null, headers);
- CacheResponse response = mock(CacheResponse.class);
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new Answer() {
- public Void answer(InvocationOnMock invocation) {
- CacheRequest req = (CacheRequest) invocation.getArguments()[0];
-
- Map> reqHeaders = req.getHeaders();
- assertEquals(headers, reqHeaders);
-
- // Make sure that we preserve insertion order
- Set>> expected = headers.entrySet();
- Iterator>> actual = reqHeaders.entrySet().iterator();
-
- for (Map.Entry> entry : expected) {
- assertEquals(entry, actual.next());
- }
-
- return null;
- }
- }).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that custom resolve was invoked
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- // Test that response headers are preserved
- @Test
- public void testCacheablePreserveResponseHeaders() throws IOException, CacheException {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI());
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- final byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new Answer() {
- public Void answer(InvocationOnMock invocation) throws Throwable {
- CacheResponse res = (CacheResponse) invocation.getArguments()[1];
-
- res.setStatus(HttpServletResponse.SC_OK);
- res.setHeader("Date", HTTPUtil.formatHTTPDate(System.currentTimeMillis()));
- res.setHeader("Cache-Control", "public");
- res.addHeader("X-Custom", "FOO");
- res.addHeader("X-Custom", "BAR");
- res.getOutputStream().write(value);
-
- return null;
- }
- }).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response).setHeader(eq("Cache-Control"), eq("public"));
-
- InOrder ordered = inOrder(response);
- // TODO: This test is to fragile, as it relies on internal knowledge of the code tested
- // (it doesn't really matter if first invocation is setHeader or addHeader)
- // See if we can create a custom VerificationMode for "either/or"
- ordered.verify(response).setHeader(eq("X-Custom"), eq("FOO"));
- ordered.verify(response).addHeader(eq("X-Custom"), eq("BAR"));
-
- verify(response, atLeastOnce()).getOutputStream();
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- // Test Vary
- @Test
- public void testVaryMissingRequestHeader() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI());
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- HashMap> headers = new HashMap<>();
- headers.put(HTTPCache.HEADER_CONTENT_TYPE, Collections.singletonList("x-foo/bar"));
- headers.put("Vary", Collections.singletonList("X-Foo"));
- headers.put("X-Foo", Collections.singletonList("foobar"));
- headers.put("X-Other", Collections.singletonList("don't care"));
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).getOutputStream();
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader("Vary", "X-Foo");
-
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Reset
- result.reset();
- reset(response, resolver);
-
- // Reconfigure
- when(response.getOutputStream()).thenReturn(result);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Repeat invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).getOutputStream();
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader("Vary", "X-Foo");
-
- verifyNoMoreInteractions(resolver);
- }
-
- @Test
- public void testVaryMissingRequestHeaderRepeated() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- String requestURI = createRequestURI();
- CacheRequest request = configureRequest(mock(CacheRequest.class), requestURI);
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- HashMap> headers = new HashMap<>();
- headers.put(HTTPCache.HEADER_CONTENT_TYPE, Collections.singletonList("x-foo/bar"));
- headers.put("Vary", Collections.singletonList("X-Foo"));
- headers.put("X-Other", Collections.singletonList("don't care"));
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).getOutputStream();
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader("Vary", "X-Foo");
-
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Reset
- result.reset();
- request = configureRequest(request, "GET", requestURI, null, Collections.singletonMap("X-Foo", Collections.singletonList("foobar")));
- reset(response, resolver);
-
- // Reconfigure
- when(response.getOutputStream()).thenReturn(result);
-
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- value[3] = 'B';
-
- // Repeat invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).getOutputStream();
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader("Vary", "X-Foo");
-
- // Different X-Foo header, must re-validate
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- @Test
- public void testVarySameResourceIsCached() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), "GET", createRequestURI(), null, Collections.singletonMap("X-Foo", Collections.singletonList("foobar value")));
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
-
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- HashMap> headers = new HashMap<>();
- headers.put(HTTPCache.HEADER_CONTENT_TYPE, Collections.singletonList("x-foo/bar"));
- headers.put("Vary", Collections.singletonList("X-Foo"));
- headers.put("X-Other", Collections.singletonList("don't care"));
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that reponse is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).getOutputStream();
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader("Vary", "X-Foo");
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Reset
- reset(response);
- result.reset();
-
- // Reconfigure
- when(response.getOutputStream()).thenReturn(result);
-
- // Repeat invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).getOutputStream();
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader("Vary", "X-Foo");
-
- verifyNoMoreInteractions(resolver);
- }
-
- @Test
- public void testVaryDifferentResources() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- String requestURI = createRequestURI();
- CacheRequest request = configureRequest(mock(CacheRequest.class), requestURI);
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- HashMap> headers = new HashMap<>();
- headers.put(HTTPCache.HEADER_CONTENT_TYPE, Collections.singletonList("x-foo/bar"));
- headers.put("Vary", Collections.singletonList("X-Foo"));
- headers.put("X-Other", Collections.singletonList("don't care"));
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).getOutputStream();
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader("Vary", "X-Foo");
-
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Reset
- result.reset();
- request = configureRequest(request, "GET", requestURI, null, Collections.singletonMap("X-Foo", Collections.singletonList("bar")));
- reset(response, resolver);
-
- // Reconfigure
- when(response.getOutputStream()).thenReturn(result);
- headers.put("Cache-Control", Collections.singletonList("no-store"));
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- value[0] = 'b';
- value[1] = 'a';
- value[2] = 'r';
-
- // Repeat invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).getOutputStream();
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader("Vary", "X-Foo");
- verify(response, atLeastOnce()).setHeader("Cache-Control", "no-store");
-
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- @Test
- public void testVaryStarNonCached() throws Exception {
- HTTPCache cache = new HTTPCache(createTempRoot(), 60000, 1024 * 1024, 10, true);
-
- // Custom setup
- CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI());
-
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- CacheResponse response = mock(CacheResponse.class);
- when(response.getOutputStream()).thenReturn(result);
-
- byte[] value = "foobar".getBytes(StandardCharsets.UTF_8);
-
- HashMap> headers = new HashMap<>();
- headers.put(HTTPCache.HEADER_CONTENT_TYPE, Collections.singletonList("x-foo/bar"));
- headers.put("Vary", Collections.singletonList("*"));
-
- ResponseResolver resolver = mock(ResponseResolver.class);
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Do the invocation
- cache.doCached(request, response, resolver);
-
- // Verify that reponse is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).getOutputStream();
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader("Vary", "*");
-
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- // Reset
- result.reset();
- reset(response, resolver);
-
- // Reconfigure
- when(response.getOutputStream()).thenReturn(result);
- headers.put("Cache-Control", Collections.singletonList("no-store"));
- doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers))
- .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
-
- value[3] = 'B';
-
- // Repeat invocation
- cache.doCached(request, response, resolver);
-
- // Verify that response is ok
- assertEquals(value.length, result.size());
- assertEquals(new String(value, StandardCharsets.UTF_8), new String(result.toByteArray(), StandardCharsets.UTF_8));
- assertArrayEquals(value, result.toByteArray());
-
- verify(response).setStatus(HttpServletResponse.SC_OK);
- verify(response, atLeastOnce()).getOutputStream();
- verify(response, atLeastOnce()).setHeader(eq("Date"), anyString());
- verify(response, atLeastOnce()).setHeader("Vary", "*");
-
- verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class));
- }
-
- @Ignore("TODO")
- @Test
- public void testVaryVariations() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- public void testVariationsWithSameContentType() {
- // I believe there is a bug if two variations has same content type...
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- // Test failing request (IOException)
- public void testIOException() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- public void testCacheException() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- public void testRuntimeException() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- // Test failing (negative) HTTP response (401, 404, 410, 500, etc)
- public void testNegativeCache() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- public void testNegativeCacheExpires() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- // Test If-None-Match/ETag support
- public void testIfNoneMatch() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- // Test If-Modified-Since support
- public void testIfModifiedSince() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- // Test that data really expires when TTL is over
- public void testTimeToLive() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- public void testMaxAgeRequest() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- // Test that for requests with authorization, responses are not shared between different authorized users, unless response is marked as Cache-Control: public
- public void testAuthorizedRequestPublic() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- public void testAuthorizedRequestPrivate() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- public void testPutPostDeleteInvalidatesCache() {
- fail("TODO");
- }
-
- @Ignore("TODO")
- @Test
- // TODO: Move out to separate package/test, just keep it here for PoC
- public void testClientRequest() {
- fail("Not implemented");
- }
-
- @Ignore("TODO")
- @Test
- // TODO: Move out to separate package/test, just keep it here for PoC
- public void testServletRequest() {
- fail("Not implemented");
- }
-
- private static class ResolveAnswer implements Answer {
- private final int status;
- private final byte[] value;
- private final Map> headers;
-
- public ResolveAnswer(byte[] value) {
- this(HttpServletResponse.SC_OK, value, null);
- }
-
- public ResolveAnswer(final int status, byte[] value, Map> headers) {
- this.status = status;
- this.value = value;
- this.headers = headers != null ? headers : Collections.>emptyMap();
- }
-
- public Void answer(InvocationOnMock invocation) throws Throwable {
- CacheResponse res = (CacheResponse) invocation.getArguments()[1];
-
- res.setStatus(status);
- res.setHeader("Date", HTTPUtil.formatHTTPDate(System.currentTimeMillis()));
-
- for (Map.Entry> header : headers.entrySet()) {
- for (String value : header.getValue()) {
- res.addHeader(header.getKey(), value);
- }
- }
-
- res.getOutputStream().write(value);
-
- return null;
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageFilterTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageFilterTest.java
deleted file mode 100644
index 8868a964..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageFilterTest.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright (c) 2011, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image;
-
-import com.twelvemonkeys.io.FileUtil;
-import com.twelvemonkeys.servlet.OutputStreamAdapter;
-import com.twelvemonkeys.util.StringTokenIterator;
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import javax.servlet.*;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
-
-/**
- * ImageFilterTest
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haraldk$
- * @version $Id: ImageFilterTest.java,v 1.0 07.04.11 14.14 haraldk Exp$
- */
-public class ImageFilterTest {
-
- @Test
- public void passThroughIfNotTrigger() throws ServletException, IOException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig filterConfig = mock(FilterConfig.class);
- when(filterConfig.getFilterName()).thenReturn("dummy");
- when(filterConfig.getServletContext()).thenReturn(context);
- when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
-
- DummyFilter filter = new DummyFilter() {
- @Override
- protected boolean trigger(ServletRequest pRequest) {
- return false;
- }
- };
- filter.init(filterConfig);
-
- // Request/response setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- HttpServletResponse response = mock(HttpServletResponse.class);
-
- FilterChain chain = mock(FilterChain.class);
-
- // Execute
- filter.doFilter(request, response, chain);
-
- // Verifications
- verify(chain).doFilter(request, response);
- verify(response, never()).getOutputStream();
- verify(response, never()).getWriter();
- }
-
- @Test
- public void normalFilter() throws ServletException, IOException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig filterConfig = mock(FilterConfig.class);
- when(filterConfig.getFilterName()).thenReturn("dummy");
- when(filterConfig.getServletContext()).thenReturn(context);
- when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
-
- DummyFilter filter = new DummyFilter();
- filter.init(filterConfig);
-
- // Request/response setup
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- ServletOutputStream out = spy(new OutputStreamAdapter(stream));
-
- HttpServletRequest request = mock(HttpServletRequest.class);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(out);
-
- FilterChain chain = mock(FilterChain.class);
- doAnswer(new Answer() {
- public Void answer(InvocationOnMock invocation) throws Throwable {
- HttpServletResponse response = (HttpServletResponse) invocation.getArguments()[1];
-
- response.setContentType("image/png");
- response.setContentLength(104417);
- InputStream stream = getClass().getResourceAsStream("/com/twelvemonkeys/servlet/image/12monkeys-splash.png");
- assertNotNull("Missing test resource", stream);
- FileUtil.copy(stream, response.getOutputStream());
-
- return null;
- }
- }).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
-
- // Execute
- filter.doFilter(request, response, chain);
-
- // Verifications
- int length = stream.size();
-
- verify(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
- verify(response).setContentType("image/png");
- verify(response, atMost(1)).setContentLength(length); // setContentLength not implemented, avoid future bugs
- verify(out, atLeastOnce()).flush();
-
- // Extra verification here, until we come up with something better
- assertTrue(
- String.format("Unlikely length for PNG (please run manual check): %s bytes, expected about 85000 bytes", length),
- length >= 60000 && length <= 120000
- );
- }
-
- @Test
- public void filterNoContent() throws ServletException, IOException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig filterConfig = mock(FilterConfig.class);
- when(filterConfig.getFilterName()).thenReturn("dummy");
- when(filterConfig.getServletContext()).thenReturn(context);
- when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
-
- DummyFilter filter = new DummyFilter();
- filter.init(filterConfig);
-
- // Request/response setup
- ServletOutputStream out = mock(ServletOutputStream.class);
-
- HttpServletRequest request = mock(HttpServletRequest.class);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(out);
-
- FilterChain chain = mock(FilterChain.class);
- doAnswer(new Answer() {
- public Void answer(InvocationOnMock invocation) throws Throwable {
- HttpServletResponse response = (HttpServletResponse) invocation.getArguments()[1];
-
- response.setContentType("image/x-imaginary");
-
- return null;
- }
- }).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
-
- // Execute
- filter.doFilter(request, response, chain);
-
- // Verifications
- verify(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
- verify(response).setContentType("image/x-imaginary");
- verify(out, atLeastOnce()).flush();
- }
-
- @Test
- public void triggerWhenTriggerParamsNull() throws ServletException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig filterConfig = mock(FilterConfig.class);
- when(filterConfig.getFilterName()).thenReturn("dummy");
- when(filterConfig.getServletContext()).thenReturn(context);
- when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
-
- DummyFilter filter = new DummyFilter();
-
- filter.init(filterConfig);
-
- // Execute/Verifications
- assertTrue(filter.trigger(mock(HttpServletRequest.class)));
- }
-
- @Test
- public void triggerWithTriggerParams() throws ServletException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig filterConfig = mock(FilterConfig.class);
- when(filterConfig.getFilterName()).thenReturn("dummy");
- when(filterConfig.getServletContext()).thenReturn(context);
- when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("triggerParams"));
- when(filterConfig.getInitParameter("triggerParams")).thenReturn("foo");
-
- DummyFilter filter = new DummyFilter();
-
- filter.init(filterConfig);
-
- // Request/response setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getParameter("foo")).thenReturn("doit");
-
-
- // Execute/Verifications
- assertTrue(filter.trigger(request));
- }
-
- @Test
- public void dontTriggerWithoutTriggerParams() throws ServletException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig filterConfig = mock(FilterConfig.class);
- when(filterConfig.getFilterName()).thenReturn("dummy");
- when(filterConfig.getServletContext()).thenReturn(context);
- when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("triggerParams"));
- when(filterConfig.getInitParameter("triggerParams")).thenReturn("foo");
-
- DummyFilter filter = new DummyFilter();
-
- filter.init(filterConfig);
-
- // Request/response setup
- HttpServletRequest request = mock(HttpServletRequest.class);
-
-
- // Execute/Verifications
- assertFalse(filter.trigger(request));
- }
-
- @Test
- public void testChaining() throws ServletException, IOException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig fooConfig = mock(FilterConfig.class);
- when(fooConfig.getFilterName()).thenReturn("foo");
- when(fooConfig.getServletContext()).thenReturn(context);
- when(fooConfig.getInitParameterNames()).thenReturn(new StringTokenIterator(""));
-
- final AtomicReference imageRef = new AtomicReference();
- final AtomicReference responseRef = new AtomicReference();
-
- DummyFilter fooFilter = new DummyFilter() {
- @Override
- protected RenderedImage doFilter(BufferedImage image, ServletRequest request, ImageServletResponse response) throws IOException {
- // NOTE: Post-filtering, this method is run after barFilter.doFilter
- assertEquals(imageRef.get(), image);
- assertEquals(responseRef.get(), response);
-
- return image;
- }
- };
- fooFilter.init(fooConfig);
-
- FilterConfig barConfig = mock(FilterConfig.class);
- when(barConfig.getFilterName()).thenReturn("bar");
- when(barConfig.getServletContext()).thenReturn(context);
- when(barConfig.getInitParameterNames()).thenReturn(new StringTokenIterator(""));
-
- final DummyFilter barFilter = new DummyFilter() {
- @Override
- protected RenderedImage doFilter(BufferedImage image, ServletRequest request, ImageServletResponse response) throws IOException {
- // NOTE: Post-filtering, this method is run before fooFilter.doFilter
- Graphics2D graphics = image.createGraphics();
- try {
- graphics.drawRect(10, 10, 100, 100);
- }
- finally {
- graphics.dispose();
- }
-
- // Store references for later, make sure this is first and only set.
- assertTrue(imageRef.compareAndSet(null, image));
- assertTrue(responseRef.compareAndSet(null, response));
-
- return image;
- }
- };
- barFilter.init(barConfig);
-
- // Request/response setup
- ServletOutputStream out = mock(ServletOutputStream.class);
- HttpServletRequest request = mock(HttpServletRequest.class);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(out);
-
- FilterChain chain = mock(FilterChain.class);
- final AtomicBoolean first = new AtomicBoolean(false);
- doAnswer(new Answer() {
- public Void answer(InvocationOnMock invocation) throws Throwable {
- HttpServletRequest request = (HttpServletRequest) invocation.getArguments()[0];
- HttpServletResponse response = (HttpServletResponse) invocation.getArguments()[1];
-
- // Fake chaining here..
- if (first.compareAndSet(false, true)) {
- barFilter.doFilter(request, response, (FilterChain) invocation.getMock());
- return null;
- }
-
- // Otherwise, fake servlet/file response
- response.setContentType("image/gif");
- InputStream stream = getClass().getResourceAsStream("/com/twelvemonkeys/servlet/image/tux.gif");
- assertNotNull("Missing test resource", stream);
- FileUtil.copy(stream, response.getOutputStream());
-
- return null;
- }
- }).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
-
- // Execute
- fooFilter.doFilter(request, response, chain);
-
- // Verifications
- verify(chain, times(2)).doFilter(any(ServletRequest.class), any(ImageServletResponse.class));
- verify(response).setContentType("image/gif");
- verify(out, atLeastOnce()).flush();
-
- // NOTE:
- // We verify that the image is the same in both ImageFilter implementations, to make sure the image is only
- // decoded once, then encoded once.
- // But this test is not necessarily 100% reliable...
- }
-
- @Test(expected = ServletException.class)
- public void passThroughIfNotTriggerException() throws ServletException, IOException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig filterConfig = mock(FilterConfig.class);
- when(filterConfig.getFilterName()).thenReturn("dummy");
- when(filterConfig.getServletContext()).thenReturn(context);
- when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
-
- DummyFilter filter = new DummyFilter() {
- @Override
- protected boolean trigger(ServletRequest pRequest) {
- return false;
- }
- };
- filter.init(filterConfig);
-
- // Request/response setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- HttpServletResponse response = mock(HttpServletResponse.class);
-
- FilterChain chain = mock(FilterChain.class);
- doThrow(new ServletException("Something went terribly wrong. Take shelter.")).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
-
- // Execute
- try {
- filter.doFilter(request, response, chain);
- }
- finally {
- // Verifications
- verify(chain).doFilter(request, response);
- verify(response, never()).getOutputStream();
- verify(response, never()).getWriter();
- }
- }
-
- @Test(expected = ServletException.class)
- public void normalFilterException() throws ServletException, IOException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig filterConfig = mock(FilterConfig.class);
- when(filterConfig.getFilterName()).thenReturn("dummy");
- when(filterConfig.getServletContext()).thenReturn(context);
- when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
-
- DummyFilter filter = new DummyFilter();
- filter.init(filterConfig);
-
- // Request/response setup
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- ServletOutputStream out = spy(new OutputStreamAdapter(stream));
-
- HttpServletRequest request = mock(HttpServletRequest.class);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(out);
-
- FilterChain chain = mock(FilterChain.class);
- doThrow(new ServletException("Something went terribly wrong. Take shelter.")).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
-
- // Execute
- try {
- filter.doFilter(request, response, chain);
- }
- finally {
- // Verifications
- verify(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
- }
- }
-
- @Test
- public void passThroughIfNotTriggerSendError() throws ServletException, IOException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig filterConfig = mock(FilterConfig.class);
- when(filterConfig.getFilterName()).thenReturn("dummy");
- when(filterConfig.getServletContext()).thenReturn(context);
- when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
-
- DummyFilter filter = new DummyFilter() {
- @Override
- protected boolean trigger(ServletRequest pRequest) {
- return false;
- }
- };
- filter.init(filterConfig);
-
- // Request/response setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- HttpServletResponse response = mock(HttpServletResponse.class);
-
- FilterChain chain = mock(FilterChain.class);
- doAnswer(new Answer() {
- public Void answer(InvocationOnMock invocation) throws Throwable {
- HttpServletResponse response = (HttpServletResponse) invocation.getArguments()[1];
- response.sendError(HttpServletResponse.SC_FORBIDDEN, "I'm afraid I can't do that.");
-
- return null;
- }
- }).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
-
- // Execute
- filter.doFilter(request, response, chain);
-
- // Verifications
- verify(chain).doFilter(request, response);
- verify(response, never()).getOutputStream();
- verify(response, never()).getWriter();
- }
-
- @Test
- public void normalFilterSendError() throws ServletException, IOException {
- // Filter init & setup
- ServletContext context = mock(ServletContext.class);
-
- FilterConfig filterConfig = mock(FilterConfig.class);
- when(filterConfig.getFilterName()).thenReturn("dummy");
- when(filterConfig.getServletContext()).thenReturn(context);
- when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
-
- DummyFilter filter = new DummyFilter();
- filter.init(filterConfig);
-
- // Request/response setup
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- ServletOutputStream out = spy(new OutputStreamAdapter(stream));
-
- HttpServletRequest request = mock(HttpServletRequest.class);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(out);
-
- FilterChain chain = mock(FilterChain.class);
- doAnswer(new Answer() {
- public Void answer(InvocationOnMock invocation) throws Throwable {
- HttpServletResponse response = (HttpServletResponse) invocation.getArguments()[1];
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "I've just picked up a fault in the AE35 unit.");
-
- return null;
- }
- }).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
-
- // Execute
- filter.doFilter(request, response, chain);
-
- // Verifications
- verify(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
- verify(response, atMost(1)).setContentLength(stream.size()); // setContentLength not implemented, avoid future bugs
- verify(out, atLeastOnce()).flush();
- }
-
- private static class DummyFilter extends ImageFilter {
- @Override
- protected RenderedImage doFilter(BufferedImage image, ServletRequest request, ImageServletResponse response) throws IOException {
- return image;
- }
- }
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTest.java
deleted file mode 100755
index c50f9ae8..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTest.java
+++ /dev/null
@@ -1,1612 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image;
-
-import com.twelvemonkeys.image.BufferedImageIcon;
-import com.twelvemonkeys.image.ImageUtil;
-import com.twelvemonkeys.io.FastByteArrayOutputStream;
-import com.twelvemonkeys.io.FileUtil;
-import com.twelvemonkeys.servlet.OutputStreamAdapter;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import javax.imageio.ImageIO;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.swing.*;
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.awt.image.IndexColorModel;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
-
-/**
- * ImageServletResponseImplTest
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- * @version $Id: twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTest.java#6 $
- */
-public class ImageServletResponseImplTest {
- private static final String CONTENT_TYPE_BMP = "image/bmp";
- private static final String CONTENT_TYPE_FOO = "foo/bar";
- private static final String CONTENT_TYPE_GIF = "image/gif";
- private static final String CONTENT_TYPE_JPEG = "image/jpeg";
- private static final String CONTENT_TYPE_PNG = "image/png";
- private static final String CONTENT_TYPE_TEXT = "text/plain";
-
- private static final String IMAGE_NAME_PNG = "12monkeys-splash.png";
- private static final String IMAGE_NAME_GIF = "tux.gif";
- private static final String IMAGE_NAME_PNG_INDEXED = "star.png";
-
- private static final Dimension IMAGE_DIMENSION_PNG = new Dimension(300, 410);
- private static final Dimension IMAGE_DIMENSION_GIF = new Dimension(250, 250);
- private static final Dimension IMAGE_DIMENSION_PNG_INDEXED = new Dimension(199, 192);
-
- private static final int STREAM_DEFAULT_SIZE = 2000;
-
- private HttpServletRequest request;
- private ServletContext context;
-
- @Before
- public void init() throws Exception {
- request = mock(HttpServletRequest.class);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- context = mock(ServletContext.class);
- when(context.getResource("/" + IMAGE_NAME_PNG)).thenReturn(getClass().getResource(IMAGE_NAME_PNG));
- when(context.getResource("/" + IMAGE_NAME_GIF)).thenReturn(getClass().getResource(IMAGE_NAME_GIF));
- when(context.getResource("/" + IMAGE_NAME_PNG_INDEXED)).thenReturn(getClass().getResource(IMAGE_NAME_PNG_INDEXED));
- when(context.getMimeType("file.bmp")).thenReturn(CONTENT_TYPE_BMP);
- when(context.getMimeType("file.foo")).thenReturn(CONTENT_TYPE_FOO);
- when(context.getMimeType("file.gif")).thenReturn(CONTENT_TYPE_GIF);
- when(context.getMimeType("file.jpeg")).thenReturn(CONTENT_TYPE_JPEG);
- when(context.getMimeType("file.png")).thenReturn(CONTENT_TYPE_PNG);
- when(context.getMimeType("file.txt")).thenReturn(CONTENT_TYPE_TEXT);
-
- MockLogger mockLogger = new MockLogger();
- doAnswer(mockLogger).when(context).log(anyString());
- doAnswer(mockLogger).when(context).log(anyString(), any(Throwable.class));
- //noinspection deprecation
- doAnswer(mockLogger).when(context).log(any(Exception.class), anyString());
- }
-
- private void fakeResponse(HttpServletRequest pRequest, ImageServletResponseImpl pImageResponse) throws IOException {
- String uri = pRequest.getRequestURI();
- int index = uri.lastIndexOf('/');
- assertTrue(uri, index >= 0);
-
- String name = uri.substring(index + 1);
- InputStream in = getClass().getResourceAsStream(name);
-
- if (in == null) {
- pImageResponse.sendError(HttpServletResponse.SC_NOT_FOUND, uri + " not found");
- }
- else {
- String ext = name.substring(name.lastIndexOf("."));
- pImageResponse.setContentType(context.getMimeType("file" + ext));
- pImageResponse.setContentLength(234);
- try {
- ServletOutputStream out = pImageResponse.getOutputStream();
- try {
- FileUtil.copy(in, out);
- }
- finally {
- out.close();
- }
- }
- finally {
- in.close();
- }
- }
- }
-
- @Test
- public void testBasicResponse() throws IOException {
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
-
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
- assertEquals(IMAGE_DIMENSION_PNG.width, image.getWidth());
- assertEquals(IMAGE_DIMENSION_PNG.height, image.getHeight());
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).setContentType(CONTENT_TYPE_PNG);
- verify(response).getOutputStream();
- }
-
- // 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
- // for performance reasons, but we still want that to work
-
- @Test
- public void testNoOpResponse() throws IOException {
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
-
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // TODO: Is there a way we can avoid calling flush?
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is untouched
- assertTrue("Data differs", Arrays.equals(FileUtil.read(getClass().getResourceAsStream(IMAGE_NAME_PNG)), out.toByteArray()));
-
- verify(response).setContentType(CONTENT_TYPE_PNG);
- verify(response).getOutputStream();
- }
-
- // Transcode original PNG to JPEG with no other changes
- @Test
- public void testTranscodeResponsePNGToJPEG() throws IOException {
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
-
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Force transcode to JPEG
- imageResponse.setOutputContentType("image/jpeg");
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Assert JPEG
- ByteArrayInputStream input = out.createInputStream();
- assertEquals(0xFF, input.read());
- assertEquals(0xD8, input.read());
- assertEquals(0xFF, input.read());
-
- // Test that image data is still readable
- /*
- File tempFile = File.createTempFile("imageservlet-test-", ".jpeg");
- FileOutputStream stream = new FileOutputStream(tempFile);
- out.writeTo(stream);
- stream.close();
- System.err.println("open " + tempFile);
- */
-
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(IMAGE_DIMENSION_PNG.width, outImage.getWidth());
- assertEquals(IMAGE_DIMENSION_PNG.height, outImage.getHeight());
-
- BufferedImage image = flatten(ImageIO.read(context.getResource("/" + IMAGE_NAME_PNG)), Color.BLACK);
-
- /*
- tempFile = File.createTempFile("imageservlet-test-", ".png");
- stream = new FileOutputStream(tempFile);
- ImageIO.write(image, "PNG", stream);
- stream.close();
- System.err.println("open " + tempFile);
- */
-
- // JPEG compression trashes the image completely...
- assertSimilarImage(image, outImage, 144f);
-
- verify(response).setContentType(CONTENT_TYPE_JPEG);
- verify(response).getOutputStream();
- }
-
- // WORKAROUND: Bug in GIFImageWriteParam, compression type is not set by default
- // (even if there's only one possible compression mode/type combo; MODE_EXPLICIT/"LZW")
- @Test
- public void testTranscodeResponsePNGToGIFWithQuality() throws IOException {
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
-
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
- when(request.getAttribute(ImageServletResponse.ATTRIB_OUTPUT_QUALITY)).thenReturn(.5f); // Force quality setting in param
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Force transcode to GIF
- imageResponse.setOutputContentType("image/gif");
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Assert GIF
- ByteArrayInputStream stream = out.createInputStream();
- assertEquals('G', stream.read());
- assertEquals('I', stream.read());
- assertEquals('F', stream.read());
- assertEquals('8', stream.read());
- assertEquals('9', stream.read());
- assertEquals('a', stream.read());
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(IMAGE_DIMENSION_PNG.width, outImage.getWidth());
- assertEquals(IMAGE_DIMENSION_PNG.height, outImage.getHeight());
-
- BufferedImage image = ImageIO.read(context.getResource("/" + IMAGE_NAME_PNG));
-
- // Should keep transparency, but is now binary
-// showIt(image, outImage, null);
- assertSimilarImageTransparent(image, outImage, 50f);
-
- verify(response).setContentType(CONTENT_TYPE_GIF);
- verify(response).getOutputStream();
- }
-
- // WORKAROUND: Bug in GIFImageWriter may throw NPE if transparent pixels
- // See: http://bugs.sun.com/view_bug.do?bug_id=6287936
- @Test
- public void testTranscodeResponsePNGToGIF() throws IOException {
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Force transcode to GIF
- imageResponse.setOutputContentType("image/gif");
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(IMAGE_DIMENSION_PNG.width, outImage.getWidth());
- assertEquals(IMAGE_DIMENSION_PNG.height, outImage.getHeight());
-
- BufferedImage image = ImageIO.read(context.getResource("/" + IMAGE_NAME_PNG));
-
- // Should keep transparency, but is now binary
-// showIt(image, outImage, null);
- assertSimilarImageTransparent(image, outImage, 50f);
-
- verify(response).setContentType(CONTENT_TYPE_GIF);
- verify(response).getOutputStream();
- }
-
- @Test
- public void testTranscodeResponseIndexColorModelGIFToJPEG() throws IOException {
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_GIF);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Force transcode to JPEG
- imageResponse.setOutputContentType("image/jpeg");
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Assert JPEG
- ByteArrayInputStream stream = out.createInputStream();
- assertEquals(0xFF, stream.read());
- assertEquals(0xD8, stream.read());
- assertEquals(0xFF, stream.read());
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(IMAGE_DIMENSION_GIF.width, outImage.getWidth());
- assertEquals(IMAGE_DIMENSION_GIF.height, outImage.getHeight());
-
- BufferedImage image = flatten(ImageIO.read(context.getResource("/" + IMAGE_NAME_GIF)), Color.WHITE);
-
- assertSimilarImage(image, outImage, 96f);
- }
-
- @Test
- // TODO: Insert bug id/reference here for regression tracking
- public void testIndexedColorModelResizePNG() throws IOException {
- // Results differ with algorithm, so we test each algorithm by itself
- int[] algorithms = new int[] {Image.SCALE_DEFAULT, Image.SCALE_FAST, Image.SCALE_SMOOTH, Image.SCALE_REPLICATE, Image.SCALE_AREA_AVERAGING, 77};
-
- for (int algorithm : algorithms) {
- Dimension size = new Dimension(100, 100);
-
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE_UNIFORM)).thenReturn(false);
- when(request.getAttribute(ImageServletResponse.ATTRIB_IMAGE_RESAMPLE_ALGORITHM)).thenReturn(algorithm);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG_INDEXED);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- imageResponse.getImage();
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Assert format is still PNG
- ByteArrayInputStream inputStream = out.createInputStream();
- assertEquals(0x89, inputStream.read());
- assertEquals('P', inputStream.read());
- assertEquals('N', inputStream.read());
- assertEquals('G', inputStream.read());
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(size.width, outImage.getWidth());
- assertEquals(size.height, outImage.getHeight());
-
- BufferedImage read = ImageIO.read(context.getResource("/" + IMAGE_NAME_PNG_INDEXED));
- BufferedImage image = ImageUtil.createResampled(read, size.width, size.height, imageResponse.getResampleAlgorithmFromRequest());
-
-// showIt(image, outImage, null);
-
- assertSimilarImageTransparent(image, outImage, 10f);
- }
- }
-
- private static BufferedImage flatten(final BufferedImage pImage, final Color pBackgroundColor) {
- BufferedImage image = ImageUtil.toBuffered(pImage, BufferedImage.TYPE_INT_ARGB);
-
- Graphics2D g = image.createGraphics();
- try {
- g.setComposite(AlphaComposite.DstOver);
- g.setColor(pBackgroundColor);
- g.fillRect(0, 0, pImage.getWidth(), pImage.getHeight());
- }
- finally {
- g.dispose();
- }
-
- return image;
- }
-
- /**
- * Makes sure images are the same, taking JPEG artifacts into account.
- *
- * @param pExpected the expected image
- * @param pActual the actual image
- * @param pArtifactThreshold the maximum allowed difference between the expected and actual pixel value
- */
- private void assertSimilarImage(final BufferedImage pExpected, final BufferedImage pActual, final float pArtifactThreshold) {
- for (int y = 0; y < pExpected.getHeight(); y++) {
- for (int x = 0; x < pExpected.getWidth(); x++) {
- int expected = pExpected.getRGB(x, y);
- int actual = pActual.getRGB(x, y);
-
- // Multiply in the alpha component
- float alpha = ((expected >> 24) & 0xff) / 255f;
-
- assertEquals(alpha * ((expected >> 16) & 0xff), (actual >> 16) & 0xff, pArtifactThreshold);
- assertEquals(alpha * ((expected >> 8) & 0xff), (actual >> 8) & 0xff, pArtifactThreshold);
- assertEquals(alpha * ((expected) & 0xff), actual & 0xff, pArtifactThreshold);
- }
- }
- }
-
- private void assertSimilarImageTransparent(final BufferedImage pExpected, final BufferedImage pActual, final float pArtifactThreshold) {
- IndexColorModel icm = pActual.getColorModel() instanceof IndexColorModel ? (IndexColorModel) pActual.getColorModel() : null;
- Object pixel = null;
-
- for (int y = 0; y < pExpected.getHeight(); y++) {
- for (int x = 0; x < pExpected.getWidth(); x++) {
- int expected = pExpected.getRGB(x, y);
- int actual = pActual.getRGB(x, y);
-
- if (icm != null) {
- // Look up, using ICM
-
- int alpha = (expected >> 24) & 0xff;
- boolean transparent = alpha < 0x40;
-
- if (transparent) {
- int expectedLookedUp = icm.getRGB(icm.getTransparentPixel());
- assertRGBEquals(x, y, expectedLookedUp & 0xff000000, actual & 0xff000000, 0);
- }
- else {
- pixel = icm.getDataElements(expected, pixel);
- int expectedLookedUp = icm.getRGB(pixel);
- assertRGBEquals(x, y, expectedLookedUp & 0xffffff, actual & 0xffffff, pArtifactThreshold);
- }
- }
- else {
- // Multiply out alpha for each component if pre-multiplied
-// int expectedR = (int) ((((expected >> 16) & 0xff) * alpha) / 255f);
-// int expectedG = (int) ((((expected >> 8) & 0xff) * alpha) / 255f);
-// int expectedB = (int) (((expected & 0xff) * alpha) / 255f);
-
- assertRGBEquals(x, y, expected, actual, pArtifactThreshold);
- }
- }
- }
- }
-
- private void assertRGBEquals(int x, int y, int expected, int actual, float pArtifactThreshold) {
- int expectedA = (expected >> 24) & 0xff;
- int expectedR = (expected >> 16) & 0xff;
- int expectedG = (expected >> 8) & 0xff;
- int expectedB = expected & 0xff;
-
- try {
- assertEquals("Alpha", expectedA, (actual >> 24) & 0xff, pArtifactThreshold);
- assertEquals("RGB", 0, (Math.abs(expectedR - ((actual >> 16) & 0xff)) +
- Math.abs(expectedG - ((actual >> 8) & 0xff)) +
- Math.abs(expectedB - ((actual) & 0xff))) / 3.0, pArtifactThreshold);
- }
- catch (AssertionError e) {
- AssertionError assertionError = new AssertionError(String.format("@[%d,%d] expected: 0x%08x but was: 0x%08x", x, y, expected, actual));
- assertionError.initCause(e);
- throw assertionError;
- }
- }
-
- @Test
- public void testReplaceResponse() throws IOException {
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
-
- // Do something with image
- // NOTE: BMP writer can't write ARGB so this image is converted (same goes for JPEG)
- // TODO: Make conversion testing more explicit
- image = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
- imageResponse.setImage(image);
- imageResponse.setOutputContentType("image/bmp");
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
- assertSimilarImage(image, outImage, 0);
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_BMP);
- }
-
- // TODO: Test with AOI attributes (rename thes to source-region?)
- // TODO: Test with scale attributes
- // More?
-
- // Make sure we don't change semantics here...
-
- @Test
- public void testNotFoundInput() throws IOException {
- // Need special setup
- request = mock(HttpServletRequest.class);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/monkey-business.gif");
-
- HttpServletResponse response = mock(HttpServletResponse.class);
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), anyString());
- }
-
- // NOTE: This means it's up to some Filter to decide wether we should filter the given request
-
- @Test
- public void testUnsupportedInput() throws IOException {
- assertFalse("Test is invalid, rewrite test", ImageIO.getImageReadersByFormatName("txt").hasNext());
-
- // Need special setup
- request = mock(HttpServletRequest.class);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/foo.txt");
-
- HttpServletResponse response = mock(HttpServletResponse.class);
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
-
- fakeResponse(request, imageResponse);
- try {
- // Force transcode
- imageResponse.setOutputContentType("image/png");
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- fail("Should throw IOException in case of unspupported input");
- }
- catch (IOException e) {
- String message = e.getMessage().toLowerCase();
- assertTrue("Wrong message: " + e.getMessage(), message.contains("transcode"));
- assertTrue("Wrong message: " + e.getMessage(), message.contains("reader"));
- assertTrue("Wrong message: " + e.getMessage(), message.contains("text"));
-
- // Failure here suggests a different error condition than the one we expected
- }
- }
-
- @Test
- public void testUnsupportedOutput() throws IOException {
- assertFalse("Test is invalid, rewrite test", ImageIO.getImageWritersByFormatName("foo").hasNext());
-
- HttpServletResponse response = mock(HttpServletResponse.class);
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
-
- fakeResponse(request, imageResponse);
- try {
- // Force transcode to unsupported format
- imageResponse.setOutputContentType("application/xml+foo");
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- fail("Should throw IOException in case of unspupported output");
- }
- catch (IOException e) {
- String message = e.getMessage().toLowerCase();
- assertTrue("Wrong message: " + e.getMessage(), message.contains("transcode"));
- assertTrue("Wrong message: " + e.getMessage(), message.contains("writer"));
- assertTrue("Wrong message: " + e.getMessage(), message.contains("foo"));
-
- // Failure here suggests a different error condition than the one we expected
- }
- }
-
- // TODO: Test that we handle image conversion to a suitable format, before writing response
- // 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
-
- @Test
- public void testReadWithSourceRegion() throws IOException {
- Rectangle sourceRegion = new Rectangle(100, 100, 100, 100);
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
- assertEquals(sourceRegion.width, image.getWidth());
- assertEquals(sourceRegion.height, image.getHeight());
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- @Test
- public void testReadWithNonSquareSourceRegion() throws IOException {
- Rectangle sourceRegion = new Rectangle(100, 100, 100, 80);
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
-
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
- assertEquals(sourceRegion.width, image.getWidth());
- assertEquals(sourceRegion.height, image.getHeight());
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- @Test
- public void testReadWithCenteredUniformSourceRegion() throws IOException {
- // Negative x/y values means centered
- Rectangle sourceRegion = new Rectangle(-1, -1, 300, 300);
-
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI_UNIFORM)).thenReturn(true);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
-
- assertEquals(sourceRegion.width, image.getWidth());
- assertEquals(sourceRegion.height, image.getHeight());
-
- BufferedImage original = ImageIO.read(getClass().getResource(IMAGE_NAME_PNG));
-
- // Sanity check
- assertNotNull(original);
- assertEquals(IMAGE_DIMENSION_PNG.width, original.getWidth());
- assertEquals(IMAGE_DIMENSION_PNG.height, original.getHeight());
-
- // Center
- sourceRegion.setLocation(
- (int) Math.round((IMAGE_DIMENSION_PNG.width - sourceRegion.getWidth()) / 2.0),
- (int) Math.round((IMAGE_DIMENSION_PNG.height - sourceRegion.getHeight()) / 2.0)
- );
-
- // Test that we have exactly the pixels we should
- for (int y = 0; y < sourceRegion.height; y++) {
- for (int x = 0; x < sourceRegion.width; x++) {
- assertEquals(original.getRGB(x + sourceRegion.x, y + sourceRegion.y), image.getRGB(x, y));
- }
- }
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- @Test
- public void testReadWithCenteredUniformNonSquareSourceRegion() throws IOException {
- // Negative x/y values means centered
- Rectangle sourceRegion = new Rectangle(-1, -1, 410, 300);
-
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI_UNIFORM)).thenReturn(true);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Image wider than bounding box", IMAGE_DIMENSION_PNG.width >= image.getWidth());
- assertTrue("Image taller than bounding box", IMAGE_DIMENSION_PNG.height >= image.getHeight());
- assertTrue("Image not maximized to bounding box", IMAGE_DIMENSION_PNG.width == image.getWidth() || IMAGE_DIMENSION_PNG.height == image.getHeight());
-
- // Above tests that one of the sides equal, we now need to test that the other follows aspect
- double destAspect = sourceRegion.getWidth() / sourceRegion.getHeight();
- double srcAspect = IMAGE_DIMENSION_PNG.getWidth() / IMAGE_DIMENSION_PNG.getHeight();
-
- if (srcAspect >= destAspect) {
- // Dst is narrower than src
- assertEquals(IMAGE_DIMENSION_PNG.height, image.getHeight());
- assertEquals(
- "Image width does not follow aspect",
- Math.round(IMAGE_DIMENSION_PNG.getHeight() * destAspect), image.getWidth()
- );
- }
- else {
- // Dst is wider than src
- assertEquals(IMAGE_DIMENSION_PNG.width, image.getWidth());
- assertEquals(
- "Image height does not follow aspect",
- Math.round(IMAGE_DIMENSION_PNG.getWidth() / destAspect), image.getHeight()
- );
- }
-
- BufferedImage original = ImageIO.read(getClass().getResource(IMAGE_NAME_PNG));
-
- // Sanity check
- assertNotNull(original);
- assertEquals(IMAGE_DIMENSION_PNG.width, original.getWidth());
- assertEquals(IMAGE_DIMENSION_PNG.height, original.getHeight());
-
- // Center
- sourceRegion.setLocation(
- (int) Math.round((IMAGE_DIMENSION_PNG.width - image.getWidth()) / 2.0),
- (int) Math.round((IMAGE_DIMENSION_PNG.height - image.getHeight()) / 2.0)
- );
- sourceRegion.setSize(image.getWidth(), image.getHeight());
-
- // Test that we have exactly the pixels we should
- for (int y = 0; y < sourceRegion.height; y++) {
- for (int x = 0; x < sourceRegion.width; x++) {
- assertEquals(original.getRGB(x + sourceRegion.x, y + sourceRegion.y), image.getRGB(x, y));
- }
- }
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- @Test
- public void testReadWithResize() throws IOException {
- Dimension size = new Dimension(100, 120);
-
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
-
- assertTrue("Image wider than bounding box", size.width >= image.getWidth());
- assertTrue("Image taller than bounding box", size.height >= image.getHeight());
- assertTrue("Image not maximized to bounding box", size.width == image.getWidth() || size.height == image.getHeight());
-
- // Above tests that one of the sides equal, we now need to test that the other follows aspect
- if (size.width == image.getWidth()) {
- assertEquals(Math.round(size.getWidth() * IMAGE_DIMENSION_PNG.getWidth() / IMAGE_DIMENSION_PNG.getHeight()), image.getHeight());
- }
- else {
- assertEquals(Math.round(size.getHeight() * IMAGE_DIMENSION_PNG.getWidth() / IMAGE_DIMENSION_PNG.getHeight()), image.getWidth());
- }
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- @Test
- public void testReadWithNonUniformResize() throws IOException {
- Dimension size = new Dimension(150, 150);
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE_UNIFORM)).thenReturn(false);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
- assertEquals(size.width, image.getWidth());
- assertEquals(size.height, image.getHeight());
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- @Test
- public void testReadWithSourceRegionAndResize() throws IOException {
- Rectangle sourceRegion = new Rectangle(100, 100, 200, 200);
- Dimension size = new Dimension(100, 120);
-
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
-
- assertTrue("Image wider than bounding box", size.width >= image.getWidth());
- assertTrue("Image taller than bounding box", size.height >= image.getHeight());
- assertTrue("Image not maximized to bounding box", size.width == image.getWidth() || size.height == image.getHeight());
-
- // Above tests that one of the sides equal, we now need to test that the other follows aspect
- if (size.width == image.getWidth()) {
- assertEquals(Math.round(size.getWidth() * sourceRegion.getWidth() / sourceRegion.getHeight()), image.getHeight());
- }
- else {
- assertEquals(Math.round(size.getHeight() * sourceRegion.getWidth() / sourceRegion.getHeight()), image.getWidth());
- }
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- @Test
- public void testReadWithSourceRegionAndNonUniformResize() throws IOException {
- Rectangle sourceRegion = new Rectangle(100, 100, 200, 200);
- Dimension size = new Dimension(150, 150);
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE_UNIFORM)).thenReturn(false);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
- assertEquals(size.width, image.getWidth());
- assertEquals(size.height, image.getHeight());
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- @Test
- public void testReadWithUniformSourceRegionAndResizeSquare() throws IOException {
- Rectangle sourceRegion = new Rectangle(-1, -1, 300, 300);
- Dimension size = new Dimension(100, 120);
-
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI_UNIFORM)).thenReturn(true);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Image wider than bounding box", size.width >= image.getWidth());
- assertTrue("Image taller than bounding box", size.height >= image.getHeight());
- assertTrue("Image not maximized to bounding box", size.width == image.getWidth() || size.height == image.getHeight());
-
- // Above tests that one of the sides equal, we now need to test that the other follows aspect
- if (size.width == image.getWidth()) {
- assertEquals(
- "Image height does not follow aspect",
- Math.round(size.getWidth() / (sourceRegion.getWidth() / sourceRegion.getHeight())), image.getHeight()
- );
- }
- else {
- System.out.println("size: " + size);
- System.out.println("image: " + new Dimension(image.getWidth(), image.getHeight()));
- assertEquals(
- "Image width does not follow aspect",
- Math.round(size.getHeight() * (sourceRegion.getWidth() / sourceRegion.getHeight())), image.getWidth()
- );
- }
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- @Test
- public void testReadWithNonSquareUniformSourceRegionAndResize() throws IOException {
- Rectangle sourceRegion = new Rectangle(-1, -1, 170, 300);
- Dimension size = new Dimension(150, 120);
-
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI_UNIFORM)).thenReturn(true);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
-
- // Flush image to wrapped response
- imageResponse.flush();
-
-// File tempFile = File.createTempFile("test", ".png");
-// FileUtil.write(tempFile, out.toByteArray());
-// System.out.println("tempFile: " + tempFile);
-
- assertTrue("Image wider than bounding box", size.width >= image.getWidth());
- assertTrue("Image taller than bounding box", size.height >= image.getHeight());
- assertTrue("Image not maximized to bounding box", size.width == image.getWidth() || size.height == image.getHeight());
-
- // Above tests that one of the sides equal, we now need to test that the other follows aspect
- if (size.width == image.getWidth()) {
- assertEquals(
- "Image height does not follow aspect",
- Math.round(size.getWidth() / (sourceRegion.getWidth() / sourceRegion.getHeight())), image.getHeight()
- );
- }
- else {
-// System.out.println("size: " + size);
-// System.out.println("image: " + new Dimension(image.getWidth(), image.getHeight()));
- assertEquals(
- "Image width does not follow aspect",
- Math.round(size.getHeight() * (sourceRegion.getWidth() / sourceRegion.getHeight())), image.getWidth()
- );
- }
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- @Test
- public void testReadWithAllNegativeSourceRegion() throws IOException {
- Rectangle sourceRegion = new Rectangle(-1, -1, -1, -1);
- Dimension size = new Dimension(100, 120);
-
- // Custom setup
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI_UNIFORM)).thenReturn(true);
- when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion);
- when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size);
- when(request.getContextPath()).thenReturn("/ape");
- when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
-
- FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
-
- ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
- fakeResponse(request, imageResponse);
-
- // Make sure image is correctly loaded
- BufferedImage image = imageResponse.getImage();
- assertNotNull(image);
-
- assertTrue("Image wider than bounding box", size.width >= image.getWidth());
- assertTrue("Image taller than bounding box", size.height >= image.getHeight());
- assertTrue("Image not maximized to bounding box", size.width == image.getWidth() || size.height == image.getHeight());
-
- // Flush image to wrapped response
- imageResponse.flush();
-
- assertTrue("Content has no data", out.size() > 0);
-
- // Test that image data is still readable
- BufferedImage outImage = ImageIO.read(out.createInputStream());
- assertNotNull(outImage);
- assertEquals(image.getWidth(), outImage.getWidth());
- assertEquals(image.getHeight(), outImage.getHeight());
-
- verify(response).getOutputStream();
- verify(response).setContentType(CONTENT_TYPE_PNG);
- }
-
- // -----------------------------------------------------------------------------------------------------------------
- // Absolute AOI
- // -----------------------------------------------------------------------------------------------------------------
-
- @Test
- public void testGetAOIAbsolute() {
- assertEquals(new Rectangle(10, 10, 100, 100), ImageServletResponseImpl.getAOI(200, 200, 10, 10, 100, 100, false, false));
- }
-
- @Test
- public void testGetAOIAbsoluteOverflowX() {
- assertEquals(new Rectangle(10, 10, 90, 100), ImageServletResponseImpl.getAOI(100, 200, 10, 10, 100, 100, false, false));
- }
-
- @Test
- public void testGetAOIAbsoluteOverflowW() {
- assertEquals(new Rectangle(0, 10, 100, 100), ImageServletResponseImpl.getAOI(100, 200, 0, 10, 110, 100, false, false));
- }
-
- @Test
- public void testGetAOIAbsoluteOverflowY() {
- assertEquals(new Rectangle(10, 10, 100, 90), ImageServletResponseImpl.getAOI(200, 100, 10, 10, 100, 100, false, false));
- }
-
- @Test
- public void testGetAOIAbsoluteOverflowH() {
- assertEquals(new Rectangle(10, 0, 100, 100), ImageServletResponseImpl.getAOI(200, 100, 10, 0, 100, 110, false, false));
- }
-
- // -----------------------------------------------------------------------------------------------------------------
- // Uniform AOI centered
- // -----------------------------------------------------------------------------------------------------------------
-
- @Test
- public void testGetAOIUniformCenteredS2SUp() {
- assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 333, 333, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2SDown() {
- assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 33, 33, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2SNormalized() {
- assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 100, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2W() {
- assertEquals(new Rectangle(0, 25, 100, 50), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 200, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2WNormalized() {
- assertEquals(new Rectangle(0, 25, 100, 50), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 100, 50, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2N() {
- assertEquals(new Rectangle(25, 0, 50, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 100, 200, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2NNormalized() {
- assertEquals(new Rectangle(25, 0, 50, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 50, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2S() {
- assertEquals(new Rectangle(50, 0, 100, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 333, 333, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2SNormalized() {
- assertEquals(new Rectangle(50, 0, 100, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 100, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2W() {
- assertEquals(new Rectangle(0, 0, 200, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 100, 50, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2WW() {
- assertEquals(new Rectangle(0, 25, 200, 50), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 200, 50, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2WN() {
- assertEquals(new Rectangle(25, 0, 150, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 75, 50, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2WNNormalized() {
- assertEquals(new Rectangle(25, 0, 150, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 150, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2WNormalized() {
- assertEquals(new Rectangle(0, 0, 200, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 200, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2N() {
- assertEquals(new Rectangle(75, 0, 50, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 100, 200, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2NNormalized() {
- assertEquals(new Rectangle(75, 0, 50, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 50, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2S() {
- assertEquals(new Rectangle(0, 50, 100, 100), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 333, 333, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2SNormalized() {
- assertEquals(new Rectangle(0, 50, 100, 100), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2W() {
- assertEquals(new Rectangle(0, 75, 100, 50), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 200, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2WNormalized() {
- assertEquals(new Rectangle(0, 75, 100, 50), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 50, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2N() {
- assertEquals(new Rectangle(0, 0, 100, 200), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 50, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2NN() {
- assertEquals(new Rectangle(25, 0, 50, 200), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 25, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2NW() {
- assertEquals(new Rectangle(0, 33, 100, 133), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 75, 100, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2NWNormalized() {
- assertEquals(new Rectangle(0, 37, 100, 125), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 125, false, true));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2NNormalized() {
- assertEquals(new Rectangle(0, 0, 100, 200), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 200, false, true));
- }
-
- // -----------------------------------------------------------------------------------------------------------------
- // Absolute AOI centered
- // -----------------------------------------------------------------------------------------------------------------
-
- @Test
- public void testGetAOICenteredS2SUp() {
- assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 333, 333, false, false));
- }
-
- @Test
- public void testGetAOICenteredS2SDown() {
- assertEquals(new Rectangle(33, 33, 33, 33), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 33, 33, false, false));
- }
-
- @Test
- public void testGetAOICenteredS2SSame() {
- assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 100, 100, false, false));
- }
-
- @Test
- public void testGetAOICenteredS2WOverflow() {
- assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 200, 100, false, false));
- }
-
- @Test
- public void testGetAOICenteredS2W() {
- assertEquals(new Rectangle(40, 45, 20, 10), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 20, 10, false, false));
- }
-
- @Test
- public void testGetAOICenteredS2WMax() {
- assertEquals(new Rectangle(0, 25, 100, 50), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 100, 50, false, false));
- }
-
- @Test
- public void testGetAOICenteredS2NOverflow() {
- assertEquals(new Rectangle(0, 0, 100, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 100, 200, false, false));
- }
-
- @Test
- public void testGetAOICenteredS2N() {
- assertEquals(new Rectangle(45, 40, 10, 20), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 10, 20, false, false));
- }
-
- @Test
- public void testGetAOICenteredS2NMax() {
- assertEquals(new Rectangle(25, 0, 50, 100), ImageServletResponseImpl.getAOI(100, 100, -1, -1, 50, 100, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2SOverflow() {
- assertEquals(new Rectangle(0, 0, 200, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 333, 333, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2S() {
- assertEquals(new Rectangle(75, 25, 50, 50), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 50, 50, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2SMax() {
- assertEquals(new Rectangle(50, 0, 100, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 100, 100, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2WOverflow() {
- assertEquals(new Rectangle(0, 0, 200, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 300, 200, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2W() {
- assertEquals(new Rectangle(50, 25, 100, 50), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 100, 50, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2WW() {
- assertEquals(new Rectangle(10, 40, 180, 20), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 180, 20, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2WN() {
- assertEquals(new Rectangle(62, 25, 75, 50), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 75, 50, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2WSame() {
- assertEquals(new Rectangle(0, 0, 200, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 200, 100, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2NOverflow() {
- assertEquals(new Rectangle(50, 0, 100, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 100, 200, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2N() {
- assertEquals(new Rectangle(83, 25, 33, 50), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 33, 50, false, false));
- }
-
- @Test
- public void testGetAOICenteredW2NMax() {
- assertEquals(new Rectangle(75, 0, 50, 100), ImageServletResponseImpl.getAOI(200, 100, -1, -1, 50, 100, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2S() {
- assertEquals(new Rectangle(33, 83, 33, 33), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 33, 33, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2SMax() {
- assertEquals(new Rectangle(0, 50, 100, 100), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 100, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2WOverflow() {
- assertEquals(new Rectangle(0, 50, 100, 100), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 200, 100, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2W() {
- assertEquals(new Rectangle(40, 95, 20, 10), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 20, 10, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2WMax() {
- assertEquals(new Rectangle(0, 75, 100, 50), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 50, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2N() {
- assertEquals(new Rectangle(45, 90, 10, 20), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 10, 20, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2NSame() {
- assertEquals(new Rectangle(0, 0, 100, 200), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 200, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2NN() {
- assertEquals(new Rectangle(37, 50, 25, 100), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 25, 100, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2NW() {
- assertEquals(new Rectangle(12, 50, 75, 100), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 75, 100, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2NWMax() {
- assertEquals(new Rectangle(0, 37, 100, 125), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 125, false, false));
- }
-
- @Test
- public void testGetAOICenteredN2NMax() {
- assertEquals(new Rectangle(0, 0, 100, 200), ImageServletResponseImpl.getAOI(100, 200, -1, -1, 100, 200, false, false));
- }
-
- // TODO: Test percent
-
- // TODO: Test getSize()...
-
- private static class BlackLabel extends JLabel {
- private final Paint checkeredBG;
- private boolean opaque = true;
-
- public BlackLabel(final String text, final BufferedImage outImage) {
- super(text, new BufferedImageIcon(outImage), JLabel.CENTER);
- setOpaque(true);
- setBackground(Color.BLACK);
- setForeground(Color.WHITE);
- setVerticalAlignment(JLabel.CENTER);
- setVerticalTextPosition(JLabel.BOTTOM);
- setHorizontalTextPosition(JLabel.CENTER);
-
- checkeredBG = createTexture();
- }
-
- @Override
- public boolean isOpaque() {
- return opaque && super.isOpaque();
- }
-
- @Override
- protected void paintComponent(Graphics graphics) {
- Graphics2D g = (Graphics2D) graphics;
-
- int iconHeight = getIcon() == null ? 0 : getIcon().getIconHeight() + getIconTextGap();
-
- // Paint checkered bg behind icon
- g.setPaint(checkeredBG);
- g.fillRect(0, 0, getWidth(), getHeight());
-
- // Paint black bg behind text
- g.setColor(getBackground());
- g.fillRect(0, iconHeight, getWidth(), getHeight() - iconHeight);
-
- try {
- opaque = false;
- super.paintComponent(g);
- }
- finally {
- opaque = true;
- }
- }
-
- private static Paint createTexture() {
- GraphicsConfiguration graphicsConfiguration = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
- BufferedImage pattern = graphicsConfiguration.createCompatibleImage(20, 20);
- Graphics2D g = pattern.createGraphics();
- try {
- g.setColor(Color.LIGHT_GRAY);
- g.fillRect(0, 0, pattern.getWidth(), pattern.getHeight());
- g.setColor(Color.GRAY);
- g.fillRect(0, 0, pattern.getWidth() / 2, pattern.getHeight() / 2);
- g.fillRect(pattern.getWidth() / 2, pattern.getHeight() / 2, pattern.getWidth() / 2, pattern.getHeight() / 2);
- }
- finally {
- g.dispose();
- }
-
- return new TexturePaint(pattern, new Rectangle(pattern.getWidth(), pattern.getHeight()));
- }
- }
-
- private static class MockLogger implements Answer {
- public Void answer(InvocationOnMock invocation) throws Throwable {
- // either log(String), log(String, Throwable) or log(Exception, String)
- Object[] arguments = invocation.getArguments();
-
- String msg = (String) (arguments[0] instanceof String ? arguments[0] : arguments[1]);
- Throwable t = (Throwable) (arguments[0] instanceof Exception ? arguments[0] : arguments.length > 1 ? arguments[1] : null);
-
- System.out.println("mock-context: " + msg);
- if (t != null) {
- t.printStackTrace(System.out);
- }
-
- return null;
- }
- }
-
-}
diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterestTest.java b/servlet/src/test/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterestTest.java
deleted file mode 100644
index db0c9525..00000000
--- a/servlet/src/test/java/com/twelvemonkeys/servlet/image/aoi/AreaOfInterestTest.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.twelvemonkeys.servlet.image.aoi;
-
-import org.junit.Test;
-
-import java.awt.*;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * @author Erlend Hamnaberg
- * @version $Revision: $
- */
-public class AreaOfInterestTest {
- private static final Dimension SQUARE_200_200 = new Dimension(200, 200);
- private static final Dimension PORTRAIT_100_200 = new Dimension(100, 200);
- private static final Dimension LANDSCAPE_200_100 = new Dimension(200, 100);
- private static final Dimension SQUARE_100_100 = new Dimension(100, 100);
- // -----------------------------------------------------------------------------------------------------------------
- // Absolute AOI
- // -----------------------------------------------------------------------------------------------------------------
-
- @Test
- public void testGetAOIAbsolute() {
- assertEquals(new Rectangle(10, 10, 100, 100), new DefaultAreaOfInterest(SQUARE_200_200).getAOI(10, 10, 100, 100));
- }
-
- @Test
- public void testGetAOIAbsoluteOverflowX() {
- assertEquals(new Rectangle(10, 10, 90, 100), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(10, 10, 100, 100));
- }
-
- @Test
- public void testGetAOIAbsoluteOverflowW() {
- assertEquals(new Rectangle(0, 10, 100, 100), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(0, 10, 110, 100));
- }
-
- @Test
- public void testGetAOIAbsoluteOverflowY() {
- assertEquals(new Rectangle(10, 10, 100, 90), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(10, 10, 100, 100));
- }
-
- @Test
- public void testGetAOIAbsoluteOverflowH() {
- assertEquals(new Rectangle(10, 0, 100, 100), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(10, 0, 100, 110));
- }
-
- // -----------------------------------------------------------------------------------------------------------------
- // Uniform AOI centered
- // -----------------------------------------------------------------------------------------------------------------
-
- @Test
- public void testGetAOIUniformCenteredS2SUp() {
- assertEquals(new Rectangle(0, 0, 100, 100), new UniformAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 333, 333));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2SDown() {
- assertEquals(new Rectangle(0, 0, 100, 100), new UniformAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 33, 33));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2SNormalized() {
- assertEquals(new Rectangle(0, 0, 100, 100), new UniformAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 100, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2W() {
- assertEquals(new Rectangle(0, 25, 100, 50), new UniformAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 200, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2WNormalized() {
- assertEquals(new Rectangle(0, 25, 100, 50), new UniformAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 100, 50));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2N() {
- assertEquals(new Rectangle(25, 0, 50, 100), new UniformAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 100, 200));
- }
-
- @Test
- public void testGetAOIUniformCenteredS2NNormalized() {
- assertEquals(new Rectangle(25, 0, 50, 100), new UniformAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 50, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2S() {
- assertEquals(new Rectangle(50, 0, 100, 100), new UniformAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 333, 333));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2SNormalized() {
- assertEquals(new Rectangle(50, 0, 100, 100), new UniformAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 100, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2W() {
- assertEquals(new Rectangle(0, 0, 200, 100), new UniformAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 100, 50));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2WW() {
- assertEquals(new Rectangle(0, 25, 200, 50), new UniformAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 200, 50));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2WN() {
- assertEquals(new Rectangle(25, 0, 150, 100), new UniformAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 75, 50));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2WNNormalized() {
- assertEquals(new Rectangle(25, 0, 150, 100), new UniformAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 150, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2WNormalized() {
- assertEquals(new Rectangle(0, 0, 200, 100), new UniformAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 200, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2N() {
- assertEquals(new Rectangle(75, 0, 50, 100), new UniformAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 100, 200));
- }
-
- @Test
- public void testGetAOIUniformCenteredW2NNormalized() {
- assertEquals(new Rectangle(75, 0, 50, 100), new UniformAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 50, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2S() {
- assertEquals(new Rectangle(0, 50, 100, 100), new UniformAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 333, 333));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2SNormalized() {
- assertEquals(new Rectangle(0, 50, 100, 100), new UniformAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 100, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2W() {
- assertEquals(new Rectangle(0, 75, 100, 50), new UniformAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 200, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2WNormalized() {
- assertEquals(new Rectangle(0, 75, 100, 50), new UniformAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 100, 50));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2N() {
- assertEquals(new Rectangle(0, 0, 100, 200), new UniformAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 50, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2NN() {
- assertEquals(new Rectangle(25, 0, 50, 200), new UniformAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 25, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2NW() {
- assertEquals(new Rectangle(0, 33, 100, 133), new UniformAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 75, 100));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2NWNormalized() {
- assertEquals(new Rectangle(0, 37, 100, 125), new UniformAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 100, 125));
- }
-
- @Test
- public void testGetAOIUniformCenteredN2NNormalized() {
- assertEquals(new Rectangle(0, 0, 100, 200), new UniformAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 100, 200));
- }
-
- // -----------------------------------------------------------------------------------------------------------------
- // Absolute AOI centered
- // -----------------------------------------------------------------------------------------------------------------
-
- @Test
- public void testGetAOICenteredS2SUp() {
- assertEquals(new Rectangle(0, 0, 100, 100), new DefaultAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 333, 333));
- }
-
- @Test
- public void testGetAOICenteredS2SDown() {
- assertEquals(new Rectangle(33, 33, 33, 33), new DefaultAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 33, 33));
- }
-
- @Test
- public void testGetAOICenteredS2SSame() {
- assertEquals(new Rectangle(0, 0, 100, 100), new DefaultAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 100, 100));
- }
-
- @Test
- public void testGetAOICenteredS2WOverflow() {
- assertEquals(new Rectangle(0, 0, 100, 100), new DefaultAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 200, 100));
- }
-
- @Test
- public void testGetAOICenteredS2W() {
- assertEquals(new Rectangle(40, 45, 20, 10), new DefaultAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 20, 10));
- }
-
- @Test
- public void testGetAOICenteredS2WMax() {
- assertEquals(new Rectangle(0, 25, 100, 50), new DefaultAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 100, 50));
- }
-
- @Test
- public void testGetAOICenteredS2NOverflow() {
- assertEquals(new Rectangle(0, 0, 100, 100), new DefaultAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 100, 200));
- }
-
- @Test
- public void testGetAOICenteredS2N() {
- assertEquals(new Rectangle(45, 40, 10, 20), new DefaultAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 10, 20));
- }
-
- @Test
- public void testGetAOICenteredS2NMax() {
- assertEquals(new Rectangle(25, 0, 50, 100), new DefaultAreaOfInterest(SQUARE_100_100).getAOI(-1, -1, 50, 100));
- }
-
- @Test
- public void testGetAOICenteredW2SOverflow() {
- assertEquals(new Rectangle(0, 0, 200, 100), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 333, 333));
- }
-
- @Test
- public void testGetAOICenteredW2S() {
- assertEquals(new Rectangle(75, 25, 50, 50), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 50, 50));
- }
-
- @Test
- public void testGetAOICenteredW2SMax() {
- assertEquals(new Rectangle(50, 0, 100, 100), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 100, 100));
- }
-
- @Test
- public void testGetAOICenteredW2WOverflow() {
- assertEquals(new Rectangle(0, 0, 200, 100), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 300, 200));
- }
-
- @Test
- public void testGetAOICenteredW2W() {
- assertEquals(new Rectangle(50, 25, 100, 50), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 100, 50));
- }
-
- @Test
- public void testGetAOICenteredW2WW() {
- assertEquals(new Rectangle(10, 40, 180, 20), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 180, 20));
- }
-
- @Test
- public void testGetAOICenteredW2WN() {
- assertEquals(new Rectangle(62, 25, 75, 50), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 75, 50));
- }
-
- @Test
- public void testGetAOICenteredW2WSame() {
- assertEquals(new Rectangle(0, 0, 200, 100), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 200, 100));
- }
-
- @Test
- public void testGetAOICenteredW2NOverflow() {
- assertEquals(new Rectangle(50, 0, 100, 100), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 100, 200));
- }
-
- @Test
- public void testGetAOICenteredW2N() {
- assertEquals(new Rectangle(83, 25, 33, 50), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 33, 50));
- }
-
- @Test
- public void testGetAOICenteredW2NMax() {
- assertEquals(new Rectangle(75, 0, 50, 100), new DefaultAreaOfInterest(LANDSCAPE_200_100).getAOI(-1, -1, 50, 100));
- }
-
- @Test
- public void testGetAOICenteredN2S() {
- assertEquals(new Rectangle(33, 83, 33, 33), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 33, 33));
- }
-
- @Test
- public void testGetAOICenteredN2SMax() {
- assertEquals(new Rectangle(0, 50, 100, 100), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 100, 100));
- }
-
- @Test
- public void testGetAOICenteredN2WOverflow() {
- assertEquals(new Rectangle(0, 50, 100, 100), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 200, 100));
- }
-
- @Test
- public void testGetAOICenteredN2W() {
- assertEquals(new Rectangle(40, 95, 20, 10), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 20, 10));
- }
-
- @Test
- public void testGetAOICenteredN2WMax() {
- assertEquals(new Rectangle(0, 75, 100, 50), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 100, 50));
- }
-
- @Test
- public void testGetAOICenteredN2N() {
- assertEquals(new Rectangle(45, 90, 10, 20), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 10, 20));
- }
-
- @Test
- public void testGetAOICenteredN2NSame() {
- assertEquals(new Rectangle(0, 0, 100, 200), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 100, 200));
- }
-
- @Test
- public void testGetAOICenteredN2NN() {
- assertEquals(new Rectangle(37, 50, 25, 100), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 25, 100));
- }
-
- @Test
- public void testGetAOICenteredN2NW() {
- assertEquals(new Rectangle(12, 50, 75, 100), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 75, 100));
- }
-
- @Test
- public void testGetAOICenteredN2NWMax() {
- assertEquals(new Rectangle(0, 37, 100, 125), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 100, 125));
- }
-
- @Test
- public void testGetAOICenteredN2NMax() {
- assertEquals(new Rectangle(0, 0, 100, 200), new DefaultAreaOfInterest(PORTRAIT_100_200).getAOI(-1, -1, 100, 200));
- }
-
-}