Conflicts:
	sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/enc/DeflateEncoder.java
	sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/enc/InflateDecoder.java
	servlet/src/main/java/com/twelvemonkeys/servlet/GenericFilter.java
	servlet/src/main/java/com/twelvemonkeys/servlet/GenericServlet.java
	servlet/src/main/java/com/twelvemonkeys/servlet/HttpServlet.java
	servlet/src/main/java/com/twelvemonkeys/servlet/ServletResponseStreamDelegate.java
	servlet/src/main/java/com/twelvemonkeys/servlet/cache/CacheResponseWrapper.java
	servlet/src/main/java/com/twelvemonkeys/servlet/cache/HTTPCache.java
	servlet/src/main/java/com/twelvemonkeys/servlet/cache/SerlvetCacheResponseWrapper.java
	servlet/src/main/java/com/twelvemonkeys/servlet/cache/WritableCachedResponseImpl.java
	servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletResponseImpl.java
This commit is contained in:
Rune Bremnes
2014-02-24 10:28:26 +01:00
128 changed files with 7361 additions and 4827 deletions

View File

@@ -1,6 +1,6 @@
package com.twelvemonkeys.servlet.cache;
import com.twelvemonkeys.net.NetUtil;
import com.twelvemonkeys.net.HTTPUtil;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -644,7 +644,7 @@ public class HTTPCacheTestCase {
CacheResponse res = (CacheResponse) invocation.getArguments()[1];
res.setStatus(HttpServletResponse.SC_OK);
res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis()));
res.setHeader("Date", HTTPUtil.formatHTTPDate(System.currentTimeMillis()));
res.setHeader("Cache-Control", "public");
res.addHeader("X-Custom", "FOO");
res.addHeader("X-Custom", "BAR");
@@ -1126,7 +1126,7 @@ public class HTTPCacheTestCase {
CacheResponse res = (CacheResponse) invocation.getArguments()[1];
res.setStatus(status);
res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis()));
res.setHeader("Date", HTTPUtil.formatHTTPDate(System.currentTimeMillis()));
for (Map.Entry<String, List<String>> header : headers.entrySet()) {
for (String value : header.getValue()) {

View File

@@ -0,0 +1,119 @@
/*
* Copyright (c) 2014, 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 "TwelveMonkeys" 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 OWNER 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 org.junit.Test;
import javax.imageio.ImageReader;
import javax.imageio.spi.IIORegistry;
import javax.imageio.spi.ImageReaderSpi;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.IOException;
import java.util.Locale;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* IIOProviderContextListenerTest
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: IIOProviderContextListenerTest.java,v 1.0 02.01.14 12:33 haraldk Exp$
*/
public class IIOProviderContextListenerTest {
@Test
public void testContextInitialized() {
ServletContextListener listener = new IIOProviderContextListener();
listener.contextInitialized(mock(ServletContextEvent.class));
}
@Test
public void testContextDestroyed() {
ServletContext context = mock(ServletContext.class);
ServletContextEvent destroyed = mock(ServletContextEvent.class);
when(destroyed.getServletContext()).thenReturn(context);
ServletContextListener listener = new IIOProviderContextListener();
listener.contextInitialized(mock(ServletContextEvent.class));
listener.contextDestroyed(destroyed);
}
// Regression test for issue #29
@Test
public void testDestroyConcurrentModRegression() {
ServletContext context = mock(ServletContext.class);
ServletContextEvent destroyed = mock(ServletContextEvent.class);
when(destroyed.getServletContext()).thenReturn(context);
ServletContextListener listener = new IIOProviderContextListener();
listener.contextInitialized(mock(ServletContextEvent.class));
ImageReaderSpi provider1 = new MockImageReaderSpiOne();
ImageReaderSpi provider2 = new MockImageReaderSpiToo();
// NOTE: Fake registering for simplicity, but it still exposes the original problem with de-registering
IIORegistry registry = IIORegistry.getDefaultInstance();
registry.registerServiceProvider(provider1);
registry.registerServiceProvider(provider2);
assertTrue(registry.contains(provider1));
assertTrue(registry.contains(provider2));
listener.contextDestroyed(destroyed);
assertFalse(registry.contains(provider1));
assertFalse(registry.contains(provider2));
}
private static abstract class MockImageReaderSpiBase extends ImageReaderSpi {
@Override
public boolean canDecodeInput(Object source) throws IOException {
return false;
}
@Override
public ImageReader createReaderInstance(Object extension) throws IOException {
return null;
}
@Override
public String getDescription(Locale locale) {
return "I'm a mock. So don't mock me.";
}
}
private static final class MockImageReaderSpiOne extends MockImageReaderSpiBase {
}
private static final class MockImageReaderSpiToo extends MockImageReaderSpiBase {
}
}

View File

@@ -2,10 +2,13 @@ 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;
@@ -15,8 +18,8 @@ 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.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
@@ -30,7 +33,7 @@ import static org.mockito.Mockito.*;
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haku $
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTestCase.java#6 $
* @version $Id: twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTestCase.java#6 $
*/
public class ImageServletResponseImplTestCase {
private static final String CONTENT_TYPE_BMP = "image/bmp";
@@ -42,9 +45,13 @@ public class ImageServletResponseImplTestCase {
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;
@@ -58,12 +65,19 @@ public class ImageServletResponseImplTestCase {
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 {
@@ -98,7 +112,7 @@ public class ImageServletResponseImplTestCase {
@Test
public void testBasicResponse() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -118,7 +132,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -133,7 +147,7 @@ public class ImageServletResponseImplTestCase {
@Test
public void testNoOpResponse() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -157,7 +171,7 @@ public class ImageServletResponseImplTestCase {
// Transcode original PNG to JPEG with no other changes
@Test
public void testTranscodeResponsePNGToJPEG() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -173,6 +187,12 @@ public class ImageServletResponseImplTestCase {
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");
@@ -182,7 +202,7 @@ public class ImageServletResponseImplTestCase {
System.err.println("open " + tempFile);
*/
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(IMAGE_DIMENSION_PNG.width, outImage.getWidth());
assertEquals(IMAGE_DIMENSION_PNG.height, outImage.getHeight());
@@ -208,43 +228,53 @@ public class ImageServletResponseImplTestCase {
// (even if there's only one possible compression mode/type combo; MODE_EXPLICIT/"LZW")
@Test
public void testTranscodeResponsePNGToGIFWithQuality() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
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
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);
ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context);
fakeResponse(request, imageResponse);
// Force transcode to GIF
imageResponse.setOutputContentType("image/gif");
// Force transcode to GIF
imageResponse.setOutputContentType("image/gif");
// Flush image to wrapped response
imageResponse.flush();
// Flush image to wrapped response
imageResponse.flush();
assertTrue("Content has no data", out.size() > 0);
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
assertNotNull(outImage);
assertEquals(IMAGE_DIMENSION_PNG.width, outImage.getWidth());
assertEquals(IMAGE_DIMENSION_PNG.height, outImage.getHeight());
// 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());
BufferedImage image = ImageIO.read(context.getResource("/" + IMAGE_NAME_PNG));
// 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());
// Should keep transparency, but is now binary
assertSimilarImageTransparent(image, outImage, 120f);
BufferedImage image = ImageIO.read(context.getResource("/" + IMAGE_NAME_PNG));
verify(response).setContentType(CONTENT_TYPE_GIF);
verify(response).getOutputStream();
}
// 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 {
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -260,7 +290,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(IMAGE_DIMENSION_PNG.width, outImage.getWidth());
assertEquals(IMAGE_DIMENSION_PNG.height, outImage.getHeight());
@@ -268,7 +298,8 @@ public class ImageServletResponseImplTestCase {
BufferedImage image = ImageIO.read(context.getResource("/" + IMAGE_NAME_PNG));
// Should keep transparency, but is now binary
assertSimilarImageTransparent(image, outImage, 120f);
// showIt(image, outImage, null);
assertSimilarImageTransparent(image, outImage, 50f);
verify(response).setContentType(CONTENT_TYPE_GIF);
verify(response).getOutputStream();
@@ -297,13 +328,13 @@ public class ImageServletResponseImplTestCase {
}
@Test
public void testTranscodeResponseIndexedCM() throws IOException {
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);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -318,8 +349,14 @@ public class ImageServletResponseImplTestCase {
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(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(IMAGE_DIMENSION_GIF.width, outImage.getWidth());
assertEquals(IMAGE_DIMENSION_GIF.height, outImage.getHeight());
@@ -329,6 +366,59 @@ public class ImageServletResponseImplTestCase {
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);
@@ -369,32 +459,64 @@ public class ImageServletResponseImplTestCase {
}
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);
int alpha = (expected >> 24) & 0xff;
if (icm != null) {
// Look up, using ICM
boolean transparent = alpha < 0x40;
int alpha = (expected >> 24) & 0xff;
boolean transparent = alpha < 0x40;
// Multiply out alpha for each component
int expectedR = (int) ((((expected >> 16) & 0xff) * alpha) / 255f);
int expectedG = (int) ((((expected >> 8 ) & 0xff) * alpha) / 255f);
int expectedB = (int) ((( expected & 0xff) * alpha) / 255f);
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);
assertEquals("a(" + x + "," + y + ")", transparent ? 0 : 0xff, (actual >> 24) & 0xff);
assertEquals("R(" + x + "," + y + ")", expectedR, (actual >> 16) & 0xff, pArtifactThreshold);
assertEquals("G(" + x + "," + y + ")", expectedG, (actual >> 8) & 0xff, pArtifactThreshold);
assertEquals("B(" + x + "," + y + ")", expectedB, actual & 0xff, pArtifactThreshold);
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 {
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -418,7 +540,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -527,7 +649,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -546,7 +668,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -564,7 +686,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -584,7 +706,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -605,7 +727,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -645,7 +767,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -666,7 +788,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -729,7 +851,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -748,7 +870,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -777,7 +899,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -796,7 +918,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -815,7 +937,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -836,7 +958,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -865,7 +987,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -886,7 +1008,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -905,7 +1027,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -927,7 +1049,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -964,7 +1086,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -986,7 +1108,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -1027,7 +1149,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -1049,7 +1171,7 @@ public class ImageServletResponseImplTestCase {
when(request.getContextPath()).thenReturn("/ape");
when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FastByteArrayOutputStream out = new FastByteArrayOutputStream(STREAM_DEFAULT_SIZE);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out));
@@ -1070,7 +1192,7 @@ public class ImageServletResponseImplTestCase {
assertTrue("Content has no data", out.size() > 0);
// Test that image data is still readable
BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
BufferedImage outImage = ImageIO.read(out.createInputStream());
assertNotNull(outImage);
assertEquals(image.getWidth(), outImage.getWidth());
assertEquals(image.getHeight(), outImage.getHeight());
@@ -1401,6 +1523,9 @@ public class ImageServletResponseImplTestCase {
// 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);
@@ -1409,6 +1534,71 @@ public class ImageServletResponseImplTestCase {
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<Void> {
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;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB