mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-05-01 00:00:02 -04:00
New code style. No functional changes.
This commit is contained in:
+74
-6
@@ -63,7 +63,7 @@ public class MappedBufferImage {
|
|||||||
File file = args.length > 0 ? new File(args[0]) : null;
|
File file = args.length > 0 ? new File(args[0]) : null;
|
||||||
|
|
||||||
if (file != null && file.exists()) {
|
if (file != null && file.exists()) {
|
||||||
// Load image using ImageIO
|
// Load image using ImageIO
|
||||||
ImageInputStream input = ImageIO.createImageInputStream(file);
|
ImageInputStream input = ImageIO.createImageInputStream(file);
|
||||||
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
|
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
|
||||||
|
|
||||||
@@ -90,6 +90,7 @@ public class MappedBufferImage {
|
|||||||
// image = MappedImageFactory.createCompatibleMappedImage(w, h, cm2);
|
// image = MappedImageFactory.createCompatibleMappedImage(w, h, cm2);
|
||||||
// image = MappedImageFactory.createCompatibleMappedImage(w, h, cm);
|
// image = MappedImageFactory.createCompatibleMappedImage(w, h, cm);
|
||||||
// image = MappedImageFactory.createCompatibleMappedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
|
// image = MappedImageFactory.createCompatibleMappedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
|
||||||
|
// image = MappedImageFactory.createCompatibleMappedImage(w, h, BufferedImage.TYPE_INT_BGR);
|
||||||
image = MappedImageFactory.createCompatibleMappedImage(w, h, type);
|
image = MappedImageFactory.createCompatibleMappedImage(w, h, type);
|
||||||
// image = type.createBufferedImage(w, h);
|
// image = type.createBufferedImage(w, h);
|
||||||
|
|
||||||
@@ -121,8 +122,18 @@ public class MappedBufferImage {
|
|||||||
paintDots(w, h, image);
|
paintDots(w, h, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Make re-sampling optional
|
||||||
|
if (true) {
|
||||||
|
image = resampleImage(image, 800);
|
||||||
|
}
|
||||||
|
|
||||||
int bytesPerPixel = image.getColorModel().getPixelSize() / 8; // Calculate first to avoid overflow
|
int bytesPerPixel = image.getColorModel().getPixelSize() / 8; // Calculate first to avoid overflow
|
||||||
JFrame frame = new JFrame(String.format("Test [%s x %s] (%s)", w, h, toHumanReadableSize(w * h * bytesPerPixel))) {
|
String size = toHumanReadableSize(w * h * bytesPerPixel);
|
||||||
|
showIt(w, h, image, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showIt(final int w, final int h, BufferedImage image, final String size) {
|
||||||
|
JFrame frame = new JFrame(String.format("Test [%s x %s] (%s)", w, h, size)) {
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
// TODO: This looks like a useful util method...
|
// TODO: This looks like a useful util method...
|
||||||
@@ -144,26 +155,83 @@ public class MappedBufferImage {
|
|||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void paintDots(int w, int h, BufferedImage image) {
|
private static BufferedImage resampleImage(final BufferedImage image, final int width) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
|
float aspect = image.getHeight() / (float) image.getWidth();
|
||||||
|
int height = Math.round(width * aspect);
|
||||||
|
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(threads);
|
||||||
|
|
||||||
|
// NOTE: The createCompatibleDestImage takes the byte order/layout into account, unlike the cm.createCompatibleWritableRaster
|
||||||
|
final BufferedImage output = new ResampleOp(width, height).createCompatibleDestImage(image, null);
|
||||||
|
|
||||||
|
final int inStep = (int) Math.ceil(image.getHeight() / (double) threads);
|
||||||
|
final int outStep = (int) Math.ceil(height / (double) threads);
|
||||||
|
|
||||||
|
// Resample image in slices
|
||||||
|
for (int i = 0; i < threads; i++) {
|
||||||
|
final int inY = i * inStep;
|
||||||
|
final int outY = i * outStep;
|
||||||
|
final int inHeight = Math.min(inStep, image.getHeight() - inY);
|
||||||
|
final int outHeight = Math.min(outStep, output.getHeight() - outY);
|
||||||
|
executorService.submit(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
BufferedImage in = image.getSubimage(0, inY, image.getWidth(), inHeight);
|
||||||
|
BufferedImage out = output.getSubimage(0, outY, width, outHeight);
|
||||||
|
new ResampleOp(width, outHeight, ResampleOp.FILTER_LANCZOS).filter(in, out);
|
||||||
|
// BufferedImage out = new ResampleOp(width, outHeight, ResampleOp.FILTER_LANCZOS).filter(in, null);
|
||||||
|
// ImageUtil.drawOnto(output.getSubimage(0, outY, width, outHeight), out);
|
||||||
|
|
||||||
|
// showIt(width, outHeight, out, "foo");
|
||||||
|
}
|
||||||
|
catch (RuntimeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println("Starting image scale on single thread, waiting for execution to complete...");
|
||||||
|
// BufferedImage output = new ResampleOp(width, height, ResampleOp.FILTER_LANCZOS).filter(image, null);
|
||||||
|
System.out.printf("Started image scale on %d threads, waiting for execution to complete...%n", threads);
|
||||||
|
|
||||||
|
Boolean done = null;
|
||||||
|
try {
|
||||||
|
executorService.shutdown();
|
||||||
|
done = executorService.awaitTermination(5L, TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
catch (InterruptedException ignore) {
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.printf("%s scaling image in %d ms%n", (done == null ? "Interrupted" : !done ? "Timed out" : "Done"), System.currentTimeMillis() - start);
|
||||||
|
System.out.println("image = " + output);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void paintDots(int width, int height, final BufferedImage image) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
int s = 300;
|
int s = 300;
|
||||||
int ws = w / s;
|
int ws = width / s;
|
||||||
int hs = h / s;
|
int hs = height / s;
|
||||||
|
|
||||||
Color[] colors = new Color[] {
|
Color[] colors = new Color[] {
|
||||||
Color.WHITE, Color.ORANGE, Color.BLUE, Color.MAGENTA, Color.BLACK, Color.RED, Color.CYAN,
|
Color.WHITE, Color.ORANGE, Color.BLUE, Color.MAGENTA, Color.BLACK, Color.RED, Color.CYAN,
|
||||||
Color.GRAY, Color.GREEN, Color.YELLOW, Color.PINK, Color.LIGHT_GRAY, Color.DARK_GRAY
|
Color.GRAY, Color.GREEN, Color.YELLOW, Color.PINK, Color.LIGHT_GRAY, Color.DARK_GRAY
|
||||||
};
|
};
|
||||||
|
|
||||||
Random r = new Random();
|
|
||||||
ExecutorService executorService = Executors.newFixedThreadPool(threads);
|
ExecutorService executorService = Executors.newFixedThreadPool(threads);
|
||||||
|
|
||||||
int step = (int) Math.ceil(hs / (double) threads);
|
int step = (int) Math.ceil(hs / (double) threads);
|
||||||
|
Random r = new Random();
|
||||||
|
|
||||||
for (int i = 0; i < threads; i++) {
|
for (int i = 0; i < threads; i++) {
|
||||||
executorService.submit(new PaintDotsTask(image, s, ws, colors, r, i * step, i * step + step));
|
executorService.submit(new PaintDotsTask(image, s, ws, colors, r, i * step, i * step + step));
|
||||||
}
|
}
|
||||||
|
|
||||||
System.err.printf("Started painting in %d threads, waiting for execution to complete...%n", threads);
|
System.err.printf("Started painting in %d threads, waiting for execution to complete...%n", threads);
|
||||||
|
|
||||||
Boolean done = null;
|
Boolean done = null;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public abstract class MappedFileBuffer extends DataBuffer {
|
|||||||
private final Buffer buffer;
|
private final Buffer buffer;
|
||||||
|
|
||||||
private MappedFileBuffer(final int type, final int size, final int numBanks) throws IOException {
|
private MappedFileBuffer(final int type, final int size, final int numBanks) throws IOException {
|
||||||
super(type, Validate.isTrue(size < 0, size, "Integer overflow for size: %d"), numBanks);
|
super(type, Validate.isTrue(size >= 0, size, "Integer overflow for size: %d"), numBanks);
|
||||||
|
|
||||||
int componentSize = DataBuffer.getDataTypeSize(type) / 8;
|
int componentSize = DataBuffer.getDataTypeSize(type) / 8;
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -45,7 +45,9 @@ import java.io.IOException;
|
|||||||
* @author last modified by $Author: haraldk$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: MappedImageFactory.java,v 1.0 May 26, 2010 5:07:01 PM haraldk Exp$
|
* @version $Id: MappedImageFactory.java,v 1.0 May 26, 2010 5:07:01 PM haraldk Exp$
|
||||||
*/
|
*/
|
||||||
public class MappedImageFactory {
|
public final class MappedImageFactory {
|
||||||
|
private MappedImageFactory() {}
|
||||||
|
|
||||||
public static BufferedImage createCompatibleMappedImage(int width, int height, int type) throws IOException {
|
public static BufferedImage createCompatibleMappedImage(int width, int height, int type) throws IOException {
|
||||||
BufferedImage temp = new BufferedImage(1, 1, type);
|
BufferedImage temp = new BufferedImage(1, 1, type);
|
||||||
return createCompatibleMappedImage(width, height, temp.getSampleModel().createCompatibleSampleModel(width, height), temp.getColorModel());
|
return createCompatibleMappedImage(width, height, temp.getSampleModel().createCompatibleSampleModel(width, height), temp.getColorModel());
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ abstract class AbstractServletMapAdapter extends AbstractMap<String, List<String
|
|||||||
|
|
||||||
private final static List<String> NULL_LIST = new ArrayList<String>();
|
private final static List<String> NULL_LIST = new ArrayList<String>();
|
||||||
|
|
||||||
private transient Map<String, List<String>> mCache = new HashMap<String, List<String>>();
|
private transient Map<String, List<String>> cache = new HashMap<String, List<String>>();
|
||||||
private transient int mSize = -1;
|
private transient int size = -1;
|
||||||
private transient AbstractSet<Entry<String, List<String>>> mEntries;
|
private transient AbstractSet<Entry<String, List<String>>> entries;
|
||||||
|
|
||||||
protected abstract Iterator<String> keysImpl();
|
protected abstract Iterator<String> keysImpl();
|
||||||
|
|
||||||
@@ -34,17 +34,18 @@ abstract class AbstractServletMapAdapter extends AbstractMap<String, List<String
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getValues(final String pName) {
|
private List<String> getValues(final String pName) {
|
||||||
List<String> values = mCache.get(pName);
|
List<String> values = cache.get(pName);
|
||||||
|
|
||||||
if (values == null) {
|
if (values == null) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
Iterator<String> headers = valuesImpl(pName);
|
Iterator<String> headers = valuesImpl(pName);
|
||||||
|
|
||||||
if (headers == null) {
|
if (headers == null) {
|
||||||
mCache.put(pName, NULL_LIST);
|
cache.put(pName, NULL_LIST);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
values = toList(headers);
|
values = toList(headers);
|
||||||
mCache.put(pName, values);
|
cache.put(pName, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,24 +60,24 @@ abstract class AbstractServletMapAdapter extends AbstractMap<String, List<String
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
if (mSize == -1) {
|
if (size == -1) {
|
||||||
computeSize();
|
computeSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mSize;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeSize() {
|
private void computeSize() {
|
||||||
mSize = 0;
|
size = 0;
|
||||||
|
|
||||||
for (Iterator<String> names = keysImpl(); names.hasNext(); names.next()) {
|
for (Iterator<String> names = keysImpl(); names.hasNext(); names.next()) {
|
||||||
mSize++;
|
size++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Entry<String, List<String>>> entrySet() {
|
public Set<Entry<String, List<String>>> entrySet() {
|
||||||
if (mEntries == null) {
|
if (entries == null) {
|
||||||
mEntries = new AbstractSet<Entry<String, List<String>>>() {
|
entries = new AbstractSet<Entry<String, List<String>>>() {
|
||||||
public Iterator<Entry<String, List<String>>> iterator() {
|
public Iterator<Entry<String, List<String>>> iterator() {
|
||||||
return new Iterator<Entry<String, List<String>>>() {
|
return new Iterator<Entry<String, List<String>>>() {
|
||||||
Iterator<String> mHeaderNames = keysImpl();
|
Iterator<String> mHeaderNames = keysImpl();
|
||||||
@@ -102,7 +103,7 @@ abstract class AbstractServletMapAdapter extends AbstractMap<String, List<String
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return mEntries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class HeaderEntry implements Entry<String, List<String>> {
|
private class HeaderEntry implements Entry<String, List<String>> {
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ public class BrowserHelperFilter extends GenericFilter {
|
|||||||
private static final String HTTP_HEADER_ACCEPT = "Accept";
|
private static final String HTTP_HEADER_ACCEPT = "Accept";
|
||||||
protected static final String HTTP_HEADER_USER_AGENT = "User-Agent";
|
protected static final String HTTP_HEADER_USER_AGENT = "User-Agent";
|
||||||
|
|
||||||
private Pattern[] mKnownAgentPatterns;
|
private Pattern[] knownAgentPatterns;
|
||||||
private String[] mKnownAgentAccpets;
|
private String[] knownAgentAccepts;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the accept-mappings for this filter
|
* Sets the accept-mappings for this filter
|
||||||
@@ -100,8 +100,8 @@ public class BrowserHelperFilter extends GenericFilter {
|
|||||||
log("Could not parse User-Agent identification for " + agent, e);
|
log("Could not parse User-Agent identification for " + agent, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
mKnownAgentPatterns = patterns.toArray(new Pattern[patterns.size()]);
|
knownAgentPatterns = patterns.toArray(new Pattern[patterns.size()]);
|
||||||
mKnownAgentAccpets = accepts.toArray(new String[accepts.size()]);
|
knownAgentAccepts = accepts.toArray(new String[accepts.size()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
@@ -110,7 +110,7 @@ public class BrowserHelperFilter extends GenericFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void init() throws ServletException {
|
public void init() throws ServletException {
|
||||||
if (mKnownAgentAccpets == null || mKnownAgentAccpets.length == 0) {
|
if (knownAgentAccepts == null || knownAgentAccepts.length == 0) {
|
||||||
throw new ServletConfigException("No User-Agent/Accept mappings for filter: " + getFilterName());
|
throw new ServletConfigException("No User-Agent/Accept mappings for filter: " + getFilterName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,16 +120,16 @@ public class BrowserHelperFilter extends GenericFilter {
|
|||||||
//System.out.println("--> Trying to find User-Agent/Accept headers...");
|
//System.out.println("--> Trying to find User-Agent/Accept headers...");
|
||||||
HttpServletRequest request = (HttpServletRequest) pRequest;
|
HttpServletRequest request = (HttpServletRequest) pRequest;
|
||||||
// Check if User-Agent is in list of known agents
|
// Check if User-Agent is in list of known agents
|
||||||
if (mKnownAgentPatterns != null && mKnownAgentPatterns.length > 0) {
|
if (knownAgentPatterns != null && knownAgentPatterns.length > 0) {
|
||||||
String agent = request.getHeader(HTTP_HEADER_USER_AGENT);
|
String agent = request.getHeader(HTTP_HEADER_USER_AGENT);
|
||||||
//System.out.println("--> User-Agent: " + agent);
|
//System.out.println("--> User-Agent: " + agent);
|
||||||
|
|
||||||
for (int i = 0; i < mKnownAgentPatterns.length; i++) {
|
for (int i = 0; i < knownAgentPatterns.length; i++) {
|
||||||
Pattern pattern = mKnownAgentPatterns[i];
|
Pattern pattern = knownAgentPatterns[i];
|
||||||
//System.out.println("--> Pattern: " + pattern);
|
//System.out.println("--> Pattern: " + pattern);
|
||||||
if (pattern.matcher(agent).matches()) {
|
if (pattern.matcher(agent).matches()) {
|
||||||
// TODO: Consider merge known with real accpet, in case plugins add extra capabilities?
|
// TODO: Consider merge known with real accpet, in case plugins add extra capabilities?
|
||||||
final String fakeAccept = mKnownAgentAccpets[i];
|
final String fakeAccept = knownAgentAccepts[i];
|
||||||
|
|
||||||
//System.out.println("--> User-Agent: " + agent + " accepts: " + fakeAccept);
|
//System.out.println("--> User-Agent: " + agent + " accepts: " + fakeAccept);
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import java.util.Enumeration;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/DebugServlet.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/DebugServlet.java#1 $
|
||||||
*/
|
*/
|
||||||
public class DebugServlet extends GenericServlet {
|
public class DebugServlet extends GenericServlet {
|
||||||
private long mDateModified;
|
private long dateModified;
|
||||||
|
|
||||||
public final void service(ServletRequest pRequest, ServletResponse pResponse) throws ServletException, IOException {
|
public final void service(ServletRequest pRequest, ServletResponse pResponse) throws ServletException, IOException {
|
||||||
service((HttpServletRequest) pRequest, (HttpServletResponse) pResponse);
|
service((HttpServletRequest) pRequest, (HttpServletResponse) pResponse);
|
||||||
@@ -53,13 +53,13 @@ public class DebugServlet extends GenericServlet {
|
|||||||
|
|
||||||
public void init() throws ServletException {
|
public void init() throws ServletException {
|
||||||
super.init();
|
super.init();
|
||||||
mDateModified = System.currentTimeMillis();
|
dateModified = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException {
|
public void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException {
|
||||||
pResponse.setContentType("text/plain");
|
pResponse.setContentType("text/plain");
|
||||||
// Include these to allow browser caching
|
// Include these to allow browser caching
|
||||||
pResponse.setDateHeader("Last-Modified", mDateModified);
|
pResponse.setDateHeader("Last-Modified", dateModified);
|
||||||
pResponse.setHeader("ETag", getServletName());
|
pResponse.setHeader("ETag", getServletName());
|
||||||
|
|
||||||
ServletOutputStream out = pResponse.getOutputStream();
|
ServletOutputStream out = pResponse.getOutputStream();
|
||||||
|
|||||||
@@ -71,14 +71,14 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
/**
|
/**
|
||||||
* The filter config.
|
* The filter config.
|
||||||
*/
|
*/
|
||||||
private transient FilterConfig mFilterConfig = null;
|
private transient FilterConfig filterConfig = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes sure the filter runs once per request
|
* Makes sure the filter runs once per request
|
||||||
* <p/>
|
* <p/>
|
||||||
* see #isRunOnce
|
* see #isRunOnce
|
||||||
*
|
*
|
||||||
* @see #mOncePerRequest
|
* @see #oncePerRequest
|
||||||
* see #ATTRIB_RUN_ONCE_VALUE
|
* see #ATTRIB_RUN_ONCE_VALUE
|
||||||
*/
|
*/
|
||||||
private final static String ATTRIB_RUN_ONCE_EXT = ".REQUEST_HANDLED";
|
private final static String ATTRIB_RUN_ONCE_EXT = ".REQUEST_HANDLED";
|
||||||
@@ -90,17 +90,17 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
* <p/>
|
* <p/>
|
||||||
* see #isRunOnce
|
* see #isRunOnce
|
||||||
*
|
*
|
||||||
* @see #mOncePerRequest
|
* @see #oncePerRequest
|
||||||
* see #ATTRIB_RUN_ONCE_VALUE
|
* see #ATTRIB_RUN_ONCE_VALUE
|
||||||
*/
|
*/
|
||||||
private String mAttribRunOnce = null;
|
private String attribRunOnce = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes sure the filter runs once per request
|
* Makes sure the filter runs once per request
|
||||||
* <p/>
|
* <p/>
|
||||||
* see #isRunOnce
|
* see #isRunOnce
|
||||||
*
|
*
|
||||||
* @see #mOncePerRequest
|
* @see #oncePerRequest
|
||||||
* see #ATTRIB_RUN_ONCE_EXT
|
* see #ATTRIB_RUN_ONCE_EXT
|
||||||
*/
|
*/
|
||||||
private static final Object ATTRIB_RUN_ONCE_VALUE = new Object();
|
private static final Object ATTRIB_RUN_ONCE_VALUE = new Object();
|
||||||
@@ -119,7 +119,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
* <pre><dispatcher>REQUEST</dispatcher></pre>
|
* <pre><dispatcher>REQUEST</dispatcher></pre>
|
||||||
* </em>
|
* </em>
|
||||||
*/
|
*/
|
||||||
protected boolean mOncePerRequest = false;
|
protected boolean oncePerRequest = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does nothing.
|
* Does nothing.
|
||||||
@@ -153,7 +153,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store filter config
|
// Store filter config
|
||||||
mFilterConfig = pConfig;
|
filterConfig = pConfig;
|
||||||
|
|
||||||
// Configure this
|
// Configure this
|
||||||
try {
|
try {
|
||||||
@@ -164,8 +164,8 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create run-once attribute name
|
// Create run-once attribute name
|
||||||
mAttribRunOnce = pConfig.getFilterName() + ATTRIB_RUN_ONCE_EXT;
|
attribRunOnce = pConfig.getFilterName() + ATTRIB_RUN_ONCE_EXT;
|
||||||
log("init (oncePerRequest=" + mOncePerRequest + ", attribRunOnce=" + mAttribRunOnce + ")");
|
log("init (oncePerRequest=" + oncePerRequest + ", attribRunOnce=" + attribRunOnce + ")");
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
*/
|
*/
|
||||||
public final void doFilter(final ServletRequest pRequest, final ServletResponse pResponse, final FilterChain pFilterChain) throws IOException, ServletException {
|
public final void doFilter(final ServletRequest pRequest, final ServletResponse pResponse, final FilterChain pFilterChain) throws IOException, ServletException {
|
||||||
// If request filter and already run, continue chain and return fast
|
// If request filter and already run, continue chain and return fast
|
||||||
if (mOncePerRequest && isRunOnce(pRequest)) {
|
if (oncePerRequest && isRunOnce(pRequest)) {
|
||||||
pFilterChain.doFilter(pRequest, pResponse);
|
pFilterChain.doFilter(pRequest, pResponse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -227,18 +227,18 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
*/
|
*/
|
||||||
private boolean isRunOnce(final ServletRequest pRequest) {
|
private boolean isRunOnce(final ServletRequest pRequest) {
|
||||||
// If request already filtered, return true (skip)
|
// If request already filtered, return true (skip)
|
||||||
if (pRequest.getAttribute(mAttribRunOnce) == ATTRIB_RUN_ONCE_VALUE) {
|
if (pRequest.getAttribute(attribRunOnce) == ATTRIB_RUN_ONCE_VALUE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set attribute and return false (continue)
|
// Set attribute and return false (continue)
|
||||||
pRequest.setAttribute(mAttribRunOnce, ATTRIB_RUN_ONCE_VALUE);
|
pRequest.setAttribute(attribRunOnce, ATTRIB_RUN_ONCE_VALUE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked once, or each time a request/response pair is passed through the
|
* Invoked once, or each time a request/response pair is passed through the
|
||||||
* chain, depending on the {@link #mOncePerRequest} member variable.
|
* chain, depending on the {@link #oncePerRequest} member variable.
|
||||||
*
|
*
|
||||||
* @param pRequest the servlet request
|
* @param pRequest the servlet request
|
||||||
* @param pResponse the servlet response
|
* @param pResponse the servlet response
|
||||||
@@ -247,7 +247,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
* @throws IOException if an I/O error occurs
|
* @throws IOException if an I/O error occurs
|
||||||
* @throws ServletException if an exception occurs during the filter process
|
* @throws ServletException if an exception occurs during the filter process
|
||||||
*
|
*
|
||||||
* @see #mOncePerRequest
|
* @see #oncePerRequest
|
||||||
* @see #doFilter doFilter
|
* @see #doFilter doFilter
|
||||||
* @see Filter#doFilter Filter.doFilter
|
* @see Filter#doFilter Filter.doFilter
|
||||||
*/
|
*/
|
||||||
@@ -262,7 +262,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
*/
|
*/
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
log("destroy");
|
log("destroy");
|
||||||
mFilterConfig = null;
|
filterConfig = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -273,7 +273,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
* @see FilterConfig#getFilterName
|
* @see FilterConfig#getFilterName
|
||||||
*/
|
*/
|
||||||
public String getFilterName() {
|
public String getFilterName() {
|
||||||
return mFilterConfig.getFilterName();
|
return filterConfig.getFilterName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -287,7 +287,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
*/
|
*/
|
||||||
public ServletContext getServletContext() {
|
public ServletContext getServletContext() {
|
||||||
// TODO: Create a servlet context wrapper that lets you log to a log4j appender?
|
// TODO: Create a servlet context wrapper that lets you log to a log4j appender?
|
||||||
return mFilterConfig.getServletContext();
|
return filterConfig.getServletContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -300,7 +300,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
* parameter
|
* parameter
|
||||||
*/
|
*/
|
||||||
public String getInitParameter(final String pKey) {
|
public String getInitParameter(final String pKey) {
|
||||||
return mFilterConfig.getInitParameter(pKey);
|
return filterConfig.getInitParameter(pKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -312,7 +312,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
* containing the mNames of the servlet's initialization parameters
|
* containing the mNames of the servlet's initialization parameters
|
||||||
*/
|
*/
|
||||||
public Enumeration getInitParameterNames() {
|
public Enumeration getInitParameterNames() {
|
||||||
return mFilterConfig.getInitParameterNames();
|
return filterConfig.getInitParameterNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -363,7 +363,7 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
* @see FilterConfig
|
* @see FilterConfig
|
||||||
*/
|
*/
|
||||||
public FilterConfig getFilterConfig() {
|
public FilterConfig getFilterConfig() {
|
||||||
return mFilterConfig;
|
return filterConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -374,10 +374,10 @@ public abstract class GenericFilter implements Filter, FilterConfig, Serializabl
|
|||||||
*
|
*
|
||||||
* @param pOncePerRequest {@code true} if the filter should run only
|
* @param pOncePerRequest {@code true} if the filter should run only
|
||||||
* once per request
|
* once per request
|
||||||
* @see #mOncePerRequest
|
* @see #oncePerRequest
|
||||||
*/
|
*/
|
||||||
@InitParam(name = "once-per-request")
|
@InitParam(name = "once-per-request")
|
||||||
public void setOncePerRequest(final boolean pOncePerRequest) {
|
public void setOncePerRequest(final boolean pOncePerRequest) {
|
||||||
mOncePerRequest = pOncePerRequest;
|
oncePerRequest = pOncePerRequest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
* the method matching the signature {@code void setX(<Type>)},
|
* the method matching the signature {@code void setX(<Type>)},
|
||||||
* for every init-parameter {@code x}. Both camelCase and lisp-style paramter
|
* for every init-parameter {@code x}. Both camelCase and lisp-style paramter
|
||||||
* naming is supported, lisp-style names will be converted to camelCase.
|
* naming is supported, lisp-style names will be converted to camelCase.
|
||||||
* Parameter values are automatically converted from string represenation to
|
* Parameter values are automatically converted from string representation to
|
||||||
* most basic types, if neccessary.
|
* most basic types, if necessary.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||||
* @author last modified by $Author: haku $
|
* @author last modified by $Author: haku $
|
||||||
@@ -70,7 +70,7 @@ public abstract class GenericServlet extends javax.servlet.GenericServlet {
|
|||||||
* @see BeanUtil#configure(Object, java.util.Map, boolean)
|
* @see BeanUtil#configure(Object, java.util.Map, boolean)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void init(ServletConfig pConfig) throws ServletException {
|
public void init(final ServletConfig pConfig) throws ServletException {
|
||||||
if (pConfig == null) {
|
if (pConfig == null) {
|
||||||
throw new ServletConfigException("servletconfig == null");
|
throw new ServletConfigException("servletconfig == null");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import java.lang.annotation.*;
|
|||||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||||
* @author last modified by $Author: haku $
|
* @author last modified by $Author: haku $
|
||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/InitParam.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/InitParam.java#1 $
|
||||||
|
* @see com.twelvemonkeys.servlet.ServletConfigurator
|
||||||
* @see com.twelvemonkeys.servlet.GenericFilter#init(javax.servlet.FilterConfig)
|
* @see com.twelvemonkeys.servlet.GenericFilter#init(javax.servlet.FilterConfig)
|
||||||
* @see com.twelvemonkeys.servlet.GenericServlet#init(javax.servlet.ServletConfig)
|
* @see com.twelvemonkeys.servlet.GenericServlet#init(javax.servlet.ServletConfig)
|
||||||
* @see com.twelvemonkeys.servlet.HttpServlet#init(javax.servlet.ServletConfig)
|
* @see com.twelvemonkeys.servlet.HttpServlet#init(javax.servlet.ServletConfig)
|
||||||
@@ -45,8 +46,10 @@ import java.lang.annotation.*;
|
|||||||
@Documented
|
@Documented
|
||||||
@Inherited
|
@Inherited
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target({ElementType.METHOD/*, TODO: ElementType.FIELD*/})
|
||||||
public @interface InitParam {
|
public @interface InitParam {
|
||||||
// TODO: Rename to value, to allow skipping name = "..."
|
static final String UNDEFINED = "";
|
||||||
String name() default "";
|
String name() default UNDEFINED;
|
||||||
|
String defaultValue() default UNDEFINED; // TODO: Consider separate annotation?
|
||||||
|
boolean required() default false; // TODO: Consider separate annotation?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet;
|
package com.twelvemonkeys.servlet;
|
||||||
|
|
||||||
|
import com.twelvemonkeys.lang.Validate;
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@@ -67,7 +69,7 @@ import java.io.OutputStream;
|
|||||||
public class OutputStreamAdapter extends ServletOutputStream {
|
public class OutputStreamAdapter extends ServletOutputStream {
|
||||||
|
|
||||||
/** The wrapped {@code OutputStream}. */
|
/** The wrapped {@code OutputStream}. */
|
||||||
protected final OutputStream mOut;
|
protected final OutputStream out;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@code OutputStreamAdapter}.
|
* Creates an {@code OutputStreamAdapter}.
|
||||||
@@ -76,11 +78,9 @@ public class OutputStreamAdapter extends ServletOutputStream {
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if {@code pOut} is {@code null}.
|
* @throws IllegalArgumentException if {@code pOut} is {@code null}.
|
||||||
*/
|
*/
|
||||||
public OutputStreamAdapter(OutputStream pOut) {
|
public OutputStreamAdapter(final OutputStream pOut) {
|
||||||
if (pOut == null) {
|
Validate.notNull(pOut, "out");
|
||||||
throw new IllegalArgumentException("out == null");
|
out = pOut;
|
||||||
}
|
|
||||||
mOut = pOut;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,11 +89,12 @@ public class OutputStreamAdapter extends ServletOutputStream {
|
|||||||
* @return the wrapped {@code OutputStream}.
|
* @return the wrapped {@code OutputStream}.
|
||||||
*/
|
*/
|
||||||
public OutputStream getOutputStream() {
|
public OutputStream getOutputStream() {
|
||||||
return mOut;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ServletOutputStream adapted from " + mOut.toString();
|
return "ServletOutputStream adapted from " + out.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,20 +104,17 @@ public class OutputStreamAdapter extends ServletOutputStream {
|
|||||||
*
|
*
|
||||||
* @throws IOException if an error occurs during writing
|
* @throws IOException if an error occurs during writing
|
||||||
*/
|
*/
|
||||||
public void write(int pByte)
|
public void write(final int pByte) throws IOException {
|
||||||
throws IOException {
|
out.write(pByte);
|
||||||
mOut.write(pByte);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overide for efficiency
|
// Overide for efficiency
|
||||||
public void write(byte pBytes[])
|
public void write(final byte pBytes[]) throws IOException {
|
||||||
throws IOException {
|
out.write(pBytes);
|
||||||
mOut.write(pBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overide for efficiency
|
// Overide for efficiency
|
||||||
public void write(byte pBytes[], int pOff, int pLen)
|
public void write(final byte pBytes[], final int pOff, final int pLen) throws IOException {
|
||||||
throws IOException {
|
out.write(pBytes, pOff, pLen);
|
||||||
mOut.write(pBytes, pOff, pLen);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,11 +71,11 @@ import java.util.Enumeration;
|
|||||||
public class ProxyServlet extends GenericServlet {
|
public class ProxyServlet extends GenericServlet {
|
||||||
|
|
||||||
/** Remote server host name or IP address */
|
/** Remote server host name or IP address */
|
||||||
protected String mRemoteServer = null;
|
protected String remoteServer = null;
|
||||||
/** Remote server port */
|
/** Remote server port */
|
||||||
protected int mRemotePort = 80;
|
protected int remotePort = 80;
|
||||||
/** Remote server "mount" path */
|
/** Remote server "mount" path */
|
||||||
protected String mRemotePath = "";
|
protected String remotePath = "";
|
||||||
|
|
||||||
private static final String HTTP_REQUEST_HEADER_HOST = "host";
|
private static final String HTTP_REQUEST_HEADER_HOST = "host";
|
||||||
private static final String HTTP_RESPONSE_HEADER_SERVER = "server";
|
private static final String HTTP_RESPONSE_HEADER_SERVER = "server";
|
||||||
@@ -88,7 +88,7 @@ public class ProxyServlet extends GenericServlet {
|
|||||||
* @param pRemoteServer
|
* @param pRemoteServer
|
||||||
*/
|
*/
|
||||||
public void setRemoteServer(String pRemoteServer) {
|
public void setRemoteServer(String pRemoteServer) {
|
||||||
mRemoteServer = pRemoteServer;
|
remoteServer = pRemoteServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,7 +99,7 @@ public class ProxyServlet extends GenericServlet {
|
|||||||
*/
|
*/
|
||||||
public void setRemotePort(String pRemotePort) {
|
public void setRemotePort(String pRemotePort) {
|
||||||
try {
|
try {
|
||||||
mRemotePort = Integer.parseInt(pRemotePort);
|
remotePort = Integer.parseInt(pRemotePort);
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e) {
|
catch (NumberFormatException e) {
|
||||||
log("RemotePort must be a number!", e);
|
log("RemotePort must be a number!", e);
|
||||||
@@ -121,7 +121,7 @@ public class ProxyServlet extends GenericServlet {
|
|||||||
pRemotePath = "/" + pRemotePath;
|
pRemotePath = "/" + pRemotePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
mRemotePath = pRemotePath;
|
remotePath = pRemotePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,7 +153,7 @@ public class ProxyServlet extends GenericServlet {
|
|||||||
*/
|
*/
|
||||||
protected void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException {
|
protected void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException {
|
||||||
// Sanity check configuration
|
// Sanity check configuration
|
||||||
if (mRemoteServer == null) {
|
if (remoteServer == null) {
|
||||||
log(MESSAGE_REMOTE_SERVER_NOT_CONFIGURED);
|
log(MESSAGE_REMOTE_SERVER_NOT_CONFIGURED);
|
||||||
pResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
pResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
||||||
MESSAGE_REMOTE_SERVER_NOT_CONFIGURED);
|
MESSAGE_REMOTE_SERVER_NOT_CONFIGURED);
|
||||||
@@ -164,7 +164,7 @@ public class ProxyServlet extends GenericServlet {
|
|||||||
try {
|
try {
|
||||||
// Recreate request URI for remote request
|
// Recreate request URI for remote request
|
||||||
String requestURI = createRemoteRequestURI(pRequest);
|
String requestURI = createRemoteRequestURI(pRequest);
|
||||||
URL remoteURL = new URL(pRequest.getScheme(), mRemoteServer, mRemotePort, requestURI);
|
URL remoteURL = new URL(pRequest.getScheme(), remoteServer, remotePort, requestURI);
|
||||||
|
|
||||||
// Get connection, with method from original request
|
// Get connection, with method from original request
|
||||||
// NOTE: The actual connection is not done before we ask for streams...
|
// NOTE: The actual connection is not done before we ask for streams...
|
||||||
@@ -319,7 +319,7 @@ public class ProxyServlet extends GenericServlet {
|
|||||||
* @return a {@code String} representing the remote request URI
|
* @return a {@code String} representing the remote request URI
|
||||||
*/
|
*/
|
||||||
private String createRemoteRequestURI(HttpServletRequest pRequest) {
|
private String createRemoteRequestURI(HttpServletRequest pRequest) {
|
||||||
StringBuilder requestURI = new StringBuilder(mRemotePath);
|
StringBuilder requestURI = new StringBuilder(remotePath);
|
||||||
requestURI.append(pRequest.getPathInfo());
|
requestURI.append(pRequest.getPathInfo());
|
||||||
|
|
||||||
if (!StringUtil.isEmpty(pRequest.getQueryString())) {
|
if (!StringUtil.isEmpty(pRequest.getQueryString())) {
|
||||||
|
|||||||
@@ -53,14 +53,14 @@ class ServletConfigMapAdapter extends AbstractMap<String, String> implements Map
|
|||||||
ServletConfig, FilterConfig, ServletContext
|
ServletConfig, FilterConfig, ServletContext
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ConfigType mType;
|
private final ConfigType type;
|
||||||
|
|
||||||
private final ServletConfig mServletConfig;
|
private final ServletConfig servletConfig;
|
||||||
private final FilterConfig mFilterConfig;
|
private final FilterConfig filterConfig;
|
||||||
private final ServletContext mServletContext;
|
private final ServletContext servletContext;
|
||||||
|
|
||||||
// Cache the entry set
|
// Cache the entry set
|
||||||
private transient Set<Entry<String, String>> mEntrySet;
|
private transient Set<Entry<String, String>> entrySet;
|
||||||
|
|
||||||
public ServletConfigMapAdapter(final ServletConfig pConfig) {
|
public ServletConfigMapAdapter(final ServletConfig pConfig) {
|
||||||
this(pConfig, ConfigType.ServletConfig);
|
this(pConfig, ConfigType.ServletConfig);
|
||||||
@@ -78,23 +78,23 @@ class ServletConfigMapAdapter extends AbstractMap<String, String> implements Map
|
|||||||
// Could happen if client code invokes with null reference
|
// Could happen if client code invokes with null reference
|
||||||
Validate.notNull(pConfig, "config");
|
Validate.notNull(pConfig, "config");
|
||||||
|
|
||||||
mType = pType;
|
type = pType;
|
||||||
|
|
||||||
switch (mType) {
|
switch (type) {
|
||||||
case ServletConfig:
|
case ServletConfig:
|
||||||
mServletConfig = (ServletConfig) pConfig;
|
servletConfig = (ServletConfig) pConfig;
|
||||||
mFilterConfig = null;
|
filterConfig = null;
|
||||||
mServletContext = null;
|
servletContext = null;
|
||||||
break;
|
break;
|
||||||
case FilterConfig:
|
case FilterConfig:
|
||||||
mServletConfig = null;
|
servletConfig = null;
|
||||||
mFilterConfig = (FilterConfig) pConfig;
|
filterConfig = (FilterConfig) pConfig;
|
||||||
mServletContext = null;
|
servletContext = null;
|
||||||
break;
|
break;
|
||||||
case ServletContext:
|
case ServletContext:
|
||||||
mServletConfig = null;
|
servletConfig = null;
|
||||||
mFilterConfig = null;
|
filterConfig = null;
|
||||||
mServletContext = (ServletContext) pConfig;
|
servletContext = (ServletContext) pConfig;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Wrong type: " + pType);
|
throw new IllegalArgumentException("Wrong type: " + pType);
|
||||||
@@ -107,13 +107,13 @@ class ServletConfigMapAdapter extends AbstractMap<String, String> implements Map
|
|||||||
* @return the servlet or filter name
|
* @return the servlet or filter name
|
||||||
*/
|
*/
|
||||||
public final String getName() {
|
public final String getName() {
|
||||||
switch (mType) {
|
switch (type) {
|
||||||
case ServletConfig:
|
case ServletConfig:
|
||||||
return mServletConfig.getServletName();
|
return servletConfig.getServletName();
|
||||||
case FilterConfig:
|
case FilterConfig:
|
||||||
return mFilterConfig.getFilterName();
|
return filterConfig.getFilterName();
|
||||||
case ServletContext:
|
case ServletContext:
|
||||||
return mServletContext.getServletContextName();
|
return servletContext.getServletContextName();
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
@@ -125,49 +125,49 @@ class ServletConfigMapAdapter extends AbstractMap<String, String> implements Map
|
|||||||
* @return the servlet context
|
* @return the servlet context
|
||||||
*/
|
*/
|
||||||
public final ServletContext getServletContext() {
|
public final ServletContext getServletContext() {
|
||||||
switch (mType) {
|
switch (type) {
|
||||||
case ServletConfig:
|
case ServletConfig:
|
||||||
return mServletConfig.getServletContext();
|
return servletConfig.getServletContext();
|
||||||
case FilterConfig:
|
case FilterConfig:
|
||||||
return mFilterConfig.getServletContext();
|
return filterConfig.getServletContext();
|
||||||
case ServletContext:
|
case ServletContext:
|
||||||
return mServletContext;
|
return servletContext;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Enumeration getInitParameterNames() {
|
public final Enumeration getInitParameterNames() {
|
||||||
switch (mType) {
|
switch (type) {
|
||||||
case ServletConfig:
|
case ServletConfig:
|
||||||
return mServletConfig.getInitParameterNames();
|
return servletConfig.getInitParameterNames();
|
||||||
case FilterConfig:
|
case FilterConfig:
|
||||||
return mFilterConfig.getInitParameterNames();
|
return filterConfig.getInitParameterNames();
|
||||||
case ServletContext:
|
case ServletContext:
|
||||||
return mServletContext.getInitParameterNames();
|
return servletContext.getInitParameterNames();
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String getInitParameter(final String pName) {
|
public final String getInitParameter(final String pName) {
|
||||||
switch (mType) {
|
switch (type) {
|
||||||
case ServletConfig:
|
case ServletConfig:
|
||||||
return mServletConfig.getInitParameter(pName);
|
return servletConfig.getInitParameter(pName);
|
||||||
case FilterConfig:
|
case FilterConfig:
|
||||||
return mFilterConfig.getInitParameter(pName);
|
return filterConfig.getInitParameter(pName);
|
||||||
case ServletContext:
|
case ServletContext:
|
||||||
return mServletContext.getInitParameter(pName);
|
return servletContext.getInitParameter(pName);
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Entry<String, String>> entrySet() {
|
public Set<Entry<String, String>> entrySet() {
|
||||||
if (mEntrySet == null) {
|
if (entrySet == null) {
|
||||||
mEntrySet = createEntrySet();
|
entrySet = createEntrySet();
|
||||||
}
|
}
|
||||||
return mEntrySet;
|
return entrySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Entry<String, String>> createEntrySet() {
|
private Set<Entry<String, String>> createEntrySet() {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.twelvemonkeys.servlet;
|
package com.twelvemonkeys.servlet;
|
||||||
|
|
||||||
|
import com.twelvemonkeys.lang.Validate;
|
||||||
import com.twelvemonkeys.util.CollectionUtil;
|
import com.twelvemonkeys.util.CollectionUtil;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@@ -15,25 +16,21 @@ import java.util.Iterator;
|
|||||||
*/
|
*/
|
||||||
class ServletHeadersMapAdapter extends AbstractServletMapAdapter {
|
class ServletHeadersMapAdapter extends AbstractServletMapAdapter {
|
||||||
|
|
||||||
protected final HttpServletRequest mRequest;
|
protected final HttpServletRequest request;
|
||||||
|
|
||||||
public ServletHeadersMapAdapter(HttpServletRequest pRequest) {
|
public ServletHeadersMapAdapter(HttpServletRequest pRequest) {
|
||||||
if (pRequest == null) {
|
request = Validate.notNull(pRequest, "request");
|
||||||
throw new IllegalArgumentException("request == null");
|
|
||||||
}
|
|
||||||
mRequest = pRequest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Iterator<String> valuesImpl(String pName) {
|
protected Iterator<String> valuesImpl(String pName) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
Enumeration<String> headers = mRequest.getHeaders(pName);
|
Enumeration<String> headers = request.getHeaders(pName);
|
||||||
return headers == null ? null : CollectionUtil.iterator(headers);
|
return headers == null ? null : CollectionUtil.iterator(headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Iterator<String> keysImpl() {
|
protected Iterator<String> keysImpl() {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
Enumeration<String> headerNames = mRequest.getHeaderNames();
|
Enumeration<String> headerNames = request.getHeaderNames();
|
||||||
return headerNames == null ? null : CollectionUtil.iterator(headerNames);
|
return headerNames == null ? null : CollectionUtil.iterator(headerNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package com.twelvemonkeys.servlet;
|
package com.twelvemonkeys.servlet;
|
||||||
|
|
||||||
|
import com.twelvemonkeys.lang.Validate;
|
||||||
import com.twelvemonkeys.util.CollectionUtil;
|
import com.twelvemonkeys.util.CollectionUtil;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServletParametersMapAdapter
|
* ServletParametersMapAdapter
|
||||||
@@ -15,23 +16,20 @@ import java.util.Enumeration;
|
|||||||
*/
|
*/
|
||||||
class ServletParametersMapAdapter extends AbstractServletMapAdapter {
|
class ServletParametersMapAdapter extends AbstractServletMapAdapter {
|
||||||
|
|
||||||
protected final HttpServletRequest mRequest;
|
protected final HttpServletRequest request;
|
||||||
|
|
||||||
public ServletParametersMapAdapter(HttpServletRequest pRequest) {
|
public ServletParametersMapAdapter(HttpServletRequest pRequest) {
|
||||||
if (pRequest == null) {
|
request = Validate.notNull(pRequest, "request");
|
||||||
throw new IllegalArgumentException("request == null");
|
|
||||||
}
|
|
||||||
mRequest = pRequest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Iterator<String> valuesImpl(String pName) {
|
protected Iterator<String> valuesImpl(String pName) {
|
||||||
String[] values = mRequest.getParameterValues(pName);
|
String[] values = request.getParameterValues(pName);
|
||||||
return values == null ? null : CollectionUtil.iterator(values);
|
return values == null ? null : CollectionUtil.iterator(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Iterator<String> keysImpl() {
|
protected Iterator<String> keysImpl() {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
Enumeration<String> names = mRequest.getParameterNames();
|
Enumeration<String> names = request.getParameterNames();
|
||||||
return names == null ? null : CollectionUtil.iterator(names);
|
return names == null ? null : CollectionUtil.iterator(names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-21
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet;
|
package com.twelvemonkeys.servlet;
|
||||||
|
|
||||||
|
import com.twelvemonkeys.lang.Validate;
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -43,44 +45,41 @@ import java.io.OutputStream;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/ServletResponseStreamDelegate.java#2 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/ServletResponseStreamDelegate.java#2 $
|
||||||
*/
|
*/
|
||||||
public class ServletResponseStreamDelegate {
|
public class ServletResponseStreamDelegate {
|
||||||
private Object mOut = null;
|
private Object out = null;
|
||||||
protected final ServletResponse mResponse;
|
protected final ServletResponse response;
|
||||||
|
|
||||||
public ServletResponseStreamDelegate(ServletResponse pResponse) {
|
public ServletResponseStreamDelegate(ServletResponse pResponse) {
|
||||||
if (pResponse == null) {
|
response = Validate.notNull(pResponse, "response");
|
||||||
throw new IllegalArgumentException("response == null");
|
|
||||||
}
|
|
||||||
mResponse = pResponse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Intentionally NOT threadsafe, as one request/response should be
|
// NOTE: Intentionally NOT threadsafe, as one request/response should be
|
||||||
// handled by one thread ONLY.
|
// handled by one thread ONLY.
|
||||||
public final ServletOutputStream getOutputStream() throws IOException {
|
public final ServletOutputStream getOutputStream() throws IOException {
|
||||||
if (mOut == null) {
|
if (out == null) {
|
||||||
OutputStream out = createOutputStream();
|
OutputStream out = createOutputStream();
|
||||||
mOut = out instanceof ServletOutputStream ? out : new OutputStreamAdapter(out);
|
this.out = out instanceof ServletOutputStream ? out : new OutputStreamAdapter(out);
|
||||||
}
|
}
|
||||||
else if (mOut instanceof PrintWriter) {
|
else if (out instanceof PrintWriter) {
|
||||||
throw new IllegalStateException("getWriter() allready called.");
|
throw new IllegalStateException("getWriter() allready called.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ServletOutputStream) mOut;
|
return (ServletOutputStream) out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Intentionally NOT threadsafe, as one request/response should be
|
// NOTE: Intentionally NOT threadsafe, as one request/response should be
|
||||||
// handled by one thread ONLY.
|
// handled by one thread ONLY.
|
||||||
public final PrintWriter getWriter() throws IOException {
|
public final PrintWriter getWriter() throws IOException {
|
||||||
if (mOut == null) {
|
if (out == null) {
|
||||||
// NOTE: getCharacterEncoding may should not return null
|
// NOTE: getCharacterEncoding may should not return null
|
||||||
OutputStream out = createOutputStream();
|
OutputStream out = createOutputStream();
|
||||||
String charEncoding = mResponse.getCharacterEncoding();
|
String charEncoding = response.getCharacterEncoding();
|
||||||
mOut = new PrintWriter(charEncoding != null ? new OutputStreamWriter(out, charEncoding) : new OutputStreamWriter(out));
|
this.out = new PrintWriter(charEncoding != null ? new OutputStreamWriter(out, charEncoding) : new OutputStreamWriter(out));
|
||||||
}
|
}
|
||||||
else if (mOut instanceof ServletOutputStream) {
|
else if (out instanceof ServletOutputStream) {
|
||||||
throw new IllegalStateException("getOutputStream() allready called.");
|
throw new IllegalStateException("getOutputStream() allready called.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (PrintWriter) mOut;
|
return (PrintWriter) out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,20 +94,20 @@ public class ServletResponseStreamDelegate {
|
|||||||
* @throws IOException if an I/O exception occurs
|
* @throws IOException if an I/O exception occurs
|
||||||
*/
|
*/
|
||||||
protected OutputStream createOutputStream() throws IOException {
|
protected OutputStream createOutputStream() throws IOException {
|
||||||
return mResponse.getOutputStream();
|
return response.getOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flushBuffer() throws IOException {
|
public void flushBuffer() throws IOException {
|
||||||
if (mOut instanceof ServletOutputStream) {
|
if (out instanceof ServletOutputStream) {
|
||||||
((ServletOutputStream) mOut).flush();
|
((ServletOutputStream) out).flush();
|
||||||
}
|
}
|
||||||
else if (mOut != null) {
|
else if (out != null) {
|
||||||
((PrintWriter) mOut).flush();
|
((PrintWriter) out).flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetBuffer() {
|
public void resetBuffer() {
|
||||||
// TODO: Is this okay? Probably not... :-)
|
// TODO: Is this okay? Probably not... :-)
|
||||||
mOut = null;
|
out = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -706,21 +706,21 @@ public final class ServletUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class HttpServletResponseHandler implements InvocationHandler {
|
private static class HttpServletResponseHandler implements InvocationHandler {
|
||||||
private final ServletResponseWrapper mResponse;
|
private final ServletResponseWrapper response;
|
||||||
|
|
||||||
HttpServletResponseHandler(final ServletResponseWrapper pResponse) {
|
HttpServletResponseHandler(final ServletResponseWrapper pResponse) {
|
||||||
mResponse = pResponse;
|
response = pResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object invoke(final Object pProxy, final Method pMethod, final Object[] pArgs) throws Throwable {
|
public Object invoke(final Object pProxy, final Method pMethod, final Object[] pArgs) throws Throwable {
|
||||||
try {
|
try {
|
||||||
// TODO: Allow partial implementing?
|
// TODO: Allow partial implementing?
|
||||||
if (pMethod.getDeclaringClass().isInstance(mResponse)) {
|
if (pMethod.getDeclaringClass().isInstance(response)) {
|
||||||
return pMethod.invoke(mResponse, pArgs);
|
return pMethod.invoke(response, pArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method is not implemented in wrapper
|
// Method is not implemented in wrapper
|
||||||
return pMethod.invoke(mResponse.getResponse(), pArgs);
|
return pMethod.invoke(response.getResponse(), pArgs);
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
// Unwrap, to avoid UndeclaredThrowableException...
|
// Unwrap, to avoid UndeclaredThrowableException...
|
||||||
@@ -730,21 +730,21 @@ public final class ServletUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class HttpServletRequestHandler implements InvocationHandler {
|
private static class HttpServletRequestHandler implements InvocationHandler {
|
||||||
private final ServletRequestWrapper mRequest;
|
private final ServletRequestWrapper request;
|
||||||
|
|
||||||
HttpServletRequestHandler(final ServletRequestWrapper pRequest) {
|
HttpServletRequestHandler(final ServletRequestWrapper pRequest) {
|
||||||
mRequest = pRequest;
|
request = pRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object invoke(final Object pProxy, final Method pMethod, final Object[] pArgs) throws Throwable {
|
public Object invoke(final Object pProxy, final Method pMethod, final Object[] pArgs) throws Throwable {
|
||||||
try {
|
try {
|
||||||
// TODO: Allow partial implementing?
|
// TODO: Allow partial implementing?
|
||||||
if (pMethod.getDeclaringClass().isInstance(mRequest)) {
|
if (pMethod.getDeclaringClass().isInstance(request)) {
|
||||||
return pMethod.invoke(mRequest, pArgs);
|
return pMethod.invoke(request, pArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method is not implemented in wrapper
|
// Method is not implemented in wrapper
|
||||||
return pMethod.invoke(mRequest.getRequest(), pArgs);
|
return pMethod.invoke(request.getRequest(), pArgs);
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
// Unwrap, to avoid UndeclaredThrowableException...
|
// Unwrap, to avoid UndeclaredThrowableException...
|
||||||
|
|||||||
@@ -67,13 +67,13 @@ public class ThrottleFilter extends GenericFilter {
|
|||||||
/**
|
/**
|
||||||
* Minimum free thread count, defaults to {@code 10}
|
* Minimum free thread count, defaults to {@code 10}
|
||||||
*/
|
*/
|
||||||
protected int mMaxConcurrentThreadCount = 10;
|
protected int maxConcurrentThreadCount = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of running request threads
|
* The number of running request threads
|
||||||
*/
|
*/
|
||||||
private int mRunningThreads = 0;
|
private int runningThreads = 0;
|
||||||
private final Object mRunningThreadsLock = new Object();
|
private final Object runningThreadsLock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default response message sent to user agents, if the request is rejected
|
* Default response message sent to user agents, if the request is rejected
|
||||||
@@ -89,17 +89,17 @@ public class ThrottleFilter extends GenericFilter {
|
|||||||
/**
|
/**
|
||||||
* The reposne message sent to user agenta, if the request is rejected
|
* The reposne message sent to user agenta, if the request is rejected
|
||||||
*/
|
*/
|
||||||
private Map mResponseMessageNames = new HashMap(10);
|
private Map<String, String> responseMessageNames = new HashMap<String, String>(10);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The reposne message sent to user agents, if the request is rejected
|
* The reposne message sent to user agents, if the request is rejected
|
||||||
*/
|
*/
|
||||||
private String[] mResponseMessageTypes = null;
|
private String[] responseMessageTypes = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache for response messages
|
* Cache for response messages
|
||||||
*/
|
*/
|
||||||
private Map mResponseCache = new HashMap(10);
|
private Map<String, CacheEntry> responseCache = new HashMap<String, CacheEntry>(10);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,7 +110,7 @@ public class ThrottleFilter extends GenericFilter {
|
|||||||
public void setMaxConcurrentThreadCount(String pMaxConcurrentThreadCount) {
|
public void setMaxConcurrentThreadCount(String pMaxConcurrentThreadCount) {
|
||||||
if (!StringUtil.isEmpty(pMaxConcurrentThreadCount)) {
|
if (!StringUtil.isEmpty(pMaxConcurrentThreadCount)) {
|
||||||
try {
|
try {
|
||||||
mMaxConcurrentThreadCount = Integer.parseInt(pMaxConcurrentThreadCount);
|
maxConcurrentThreadCount = Integer.parseInt(pMaxConcurrentThreadCount);
|
||||||
}
|
}
|
||||||
catch (NumberFormatException nfe) {
|
catch (NumberFormatException nfe) {
|
||||||
// Use default
|
// Use default
|
||||||
@@ -133,23 +133,24 @@ public class ThrottleFilter extends GenericFilter {
|
|||||||
public void setResponseMessages(String pResponseMessages) {
|
public void setResponseMessages(String pResponseMessages) {
|
||||||
// Split string in type=filename pairs
|
// Split string in type=filename pairs
|
||||||
String[] mappings = StringUtil.toStringArray(pResponseMessages, ", \r\n\t");
|
String[] mappings = StringUtil.toStringArray(pResponseMessages, ", \r\n\t");
|
||||||
List types = new ArrayList();
|
List<String> types = new ArrayList<String>();
|
||||||
|
|
||||||
for (int i = 0; i < mappings.length; i++) {
|
for (String pair : mappings) {
|
||||||
// Split pairs on '='
|
// Split pairs on '='
|
||||||
String[] mapping = StringUtil.toStringArray(mappings[i], "= ");
|
String[] mapping = StringUtil.toStringArray(pair, "= ");
|
||||||
|
|
||||||
// Test for wrong mapping
|
// Test for wrong mapping
|
||||||
if ((mapping == null) || (mapping.length < 2)) {
|
if ((mapping == null) || (mapping.length < 2)) {
|
||||||
log("Error in init param \"responseMessages\": " + pResponseMessages);
|
log("Error in init param \"responseMessages\": " + pResponseMessages);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
types.add(mapping[0]);
|
types.add(mapping[0]);
|
||||||
mResponseMessageNames.put(mapping[0], mapping[1]);
|
responseMessageNames.put(mapping[0], mapping[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create arrays
|
// Create arrays
|
||||||
mResponseMessageTypes = (String[]) types.toArray(new String[types.size()]);
|
responseMessageTypes = types.toArray(new String[types.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,8 +160,7 @@ public class ThrottleFilter extends GenericFilter {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws ServletException
|
* @throws ServletException
|
||||||
*/
|
*/
|
||||||
protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain)
|
protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException, ServletException {
|
||||||
throws IOException, ServletException {
|
|
||||||
try {
|
try {
|
||||||
if (beginRequest()) {
|
if (beginRequest()) {
|
||||||
// Continue request
|
// Continue request
|
||||||
@@ -198,18 +198,19 @@ public class ThrottleFilter extends GenericFilter {
|
|||||||
* @return <CODE>true<CODE> if the request should be handled.
|
* @return <CODE>true<CODE> if the request should be handled.
|
||||||
*/
|
*/
|
||||||
private boolean beginRequest() {
|
private boolean beginRequest() {
|
||||||
synchronized (mRunningThreadsLock) {
|
synchronized (runningThreadsLock) {
|
||||||
mRunningThreads++;
|
runningThreads++;
|
||||||
}
|
}
|
||||||
return (mRunningThreads <= mMaxConcurrentThreadCount);
|
|
||||||
|
return (runningThreads <= maxConcurrentThreadCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the end of the request
|
* Marks the end of the request
|
||||||
*/
|
*/
|
||||||
private void doneRequest() {
|
private void doneRequest() {
|
||||||
synchronized (mRunningThreadsLock) {
|
synchronized (runningThreadsLock) {
|
||||||
mRunningThreads--;
|
runningThreads--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,12 +221,10 @@ public class ThrottleFilter extends GenericFilter {
|
|||||||
* @return the content type
|
* @return the content type
|
||||||
*/
|
*/
|
||||||
private String getContentType(HttpServletRequest pRequest) {
|
private String getContentType(HttpServletRequest pRequest) {
|
||||||
if (mResponseMessageTypes != null) {
|
if (responseMessageTypes != null) {
|
||||||
String accept = pRequest.getHeader("Accept");
|
String accept = pRequest.getHeader("Accept");
|
||||||
|
|
||||||
for (int i = 0; i < mResponseMessageTypes.length; i++) {
|
for (String type : responseMessageTypes) {
|
||||||
String type = mResponseMessageTypes[i];
|
|
||||||
|
|
||||||
// Note: This is not 100% correct way of doing content negotiation
|
// Note: This is not 100% correct way of doing content negotiation
|
||||||
// But we just want a compatible result, quick, so this is okay
|
// But we just want a compatible result, quick, so this is okay
|
||||||
if (StringUtil.contains(accept, type)) {
|
if (StringUtil.contains(accept, type)) {
|
||||||
@@ -245,17 +244,16 @@ public class ThrottleFilter extends GenericFilter {
|
|||||||
* @return the message
|
* @return the message
|
||||||
*/
|
*/
|
||||||
private String getMessage(String pContentType) {
|
private String getMessage(String pContentType) {
|
||||||
|
String fileName = responseMessageNames.get(pContentType);
|
||||||
String fileName = (String) mResponseMessageNames.get(pContentType);
|
|
||||||
|
|
||||||
// Get cached value
|
// Get cached value
|
||||||
CacheEntry entry = (CacheEntry) mResponseCache.get(fileName);
|
CacheEntry entry = responseCache.get(fileName);
|
||||||
|
|
||||||
if ((entry == null) || entry.isExpired()) {
|
if ((entry == null) || entry.isExpired()) {
|
||||||
|
|
||||||
// Create and add or replace cached value
|
// Create and add or replace cached value
|
||||||
entry = new CacheEntry(readMessage(fileName));
|
entry = new CacheEntry(readMessage(fileName));
|
||||||
mResponseCache.put(fileName, entry);
|
responseCache.put(fileName, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return value
|
// Return value
|
||||||
@@ -292,20 +290,20 @@ public class ThrottleFilter extends GenericFilter {
|
|||||||
* Keeps track of Cached objects
|
* Keeps track of Cached objects
|
||||||
*/
|
*/
|
||||||
private static class CacheEntry {
|
private static class CacheEntry {
|
||||||
private Object mValue;
|
private Object value;
|
||||||
private long mTimestamp = -1;
|
private long timestamp = -1;
|
||||||
|
|
||||||
CacheEntry(Object pValue) {
|
CacheEntry(Object pValue) {
|
||||||
mValue = pValue;
|
value = pValue;
|
||||||
mTimestamp = System.currentTimeMillis();
|
timestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
Object getValue() {
|
Object getValue() {
|
||||||
return mValue;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isExpired() {
|
boolean isExpired() {
|
||||||
return (System.currentTimeMillis() - mTimestamp) > 60000; // Cache 1 minute
|
return (System.currentTimeMillis() - timestamp) > 60000; // Cache 1 minute
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ import java.io.IOException;
|
|||||||
*/
|
*/
|
||||||
public class TimingFilter extends GenericFilter {
|
public class TimingFilter extends GenericFilter {
|
||||||
|
|
||||||
private String mAttribUsage = null;
|
private String attribUsage = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method init
|
* Method init
|
||||||
@@ -52,7 +52,7 @@ public class TimingFilter extends GenericFilter {
|
|||||||
* @throws ServletException
|
* @throws ServletException
|
||||||
*/
|
*/
|
||||||
public void init() throws ServletException {
|
public void init() throws ServletException {
|
||||||
mAttribUsage = getFilterName() + ".timerDelta";
|
attribUsage = getFilterName() + ".timerDelta";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,13 +66,13 @@ public class TimingFilter extends GenericFilter {
|
|||||||
protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain)
|
protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
// Get total usage of earlier filters on same level
|
// Get total usage of earlier filters on same level
|
||||||
Object usageAttrib = pRequest.getAttribute(mAttribUsage);
|
Object usageAttrib = pRequest.getAttribute(attribUsage);
|
||||||
long total = 0;
|
long total = 0;
|
||||||
|
|
||||||
if (usageAttrib instanceof Long) {
|
if (usageAttrib instanceof Long) {
|
||||||
// If set, get value, and remove attribute for nested resources
|
// If set, get value, and remove attribute for nested resources
|
||||||
total = ((Long) usageAttrib).longValue();
|
total = (Long) usageAttrib;
|
||||||
pRequest.removeAttribute(mAttribUsage);
|
pRequest.removeAttribute(attribUsage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start timing
|
// Start timing
|
||||||
@@ -87,10 +87,10 @@ public class TimingFilter extends GenericFilter {
|
|||||||
long end = System.currentTimeMillis();
|
long end = System.currentTimeMillis();
|
||||||
|
|
||||||
// Get time usage of included resources, add to total usage
|
// Get time usage of included resources, add to total usage
|
||||||
usageAttrib = pRequest.getAttribute(mAttribUsage);
|
usageAttrib = pRequest.getAttribute(attribUsage);
|
||||||
long usage = 0;
|
long usage = 0;
|
||||||
if (usageAttrib instanceof Long) {
|
if (usageAttrib instanceof Long) {
|
||||||
usage = ((Long) usageAttrib).longValue();
|
usage = (Long) usageAttrib;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the name of the included resource
|
// Get the name of the included resource
|
||||||
@@ -107,7 +107,7 @@ public class TimingFilter extends GenericFilter {
|
|||||||
|
|
||||||
// Store total usage
|
// Store total usage
|
||||||
total += delta;
|
total += delta;
|
||||||
pRequest.setAttribute(mAttribUsage, new Long(total));
|
pRequest.setAttribute(attribUsage, total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,28 +113,28 @@ import java.io.FilterOutputStream;
|
|||||||
*/
|
*/
|
||||||
public class TrimWhiteSpaceFilter extends GenericFilter {
|
public class TrimWhiteSpaceFilter extends GenericFilter {
|
||||||
|
|
||||||
private boolean mAutoFlush = true;
|
private boolean autoFlush = true;
|
||||||
|
|
||||||
@InitParam
|
@InitParam
|
||||||
public void setAutoFlush(final boolean pAutoFlush) {
|
public void setAutoFlush(final boolean pAutoFlush) {
|
||||||
mAutoFlush = pAutoFlush;
|
autoFlush = pAutoFlush;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() throws ServletException {
|
public void init() throws ServletException {
|
||||||
super.init();
|
super.init();
|
||||||
log("Automatic flushing is " + (mAutoFlush ? "enabled" : "disabled"));
|
log("Automatic flushing is " + (autoFlush ? "enabled" : "disabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException, ServletException {
|
protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException, ServletException {
|
||||||
ServletResponseWrapper wrapped = new TrimWSServletResponseWrapper(pResponse);
|
ServletResponseWrapper wrapped = new TrimWSServletResponseWrapper(pResponse);
|
||||||
pChain.doFilter(pRequest, ServletUtil.createWrapper(wrapped));
|
pChain.doFilter(pRequest, ServletUtil.createWrapper(wrapped));
|
||||||
if (mAutoFlush) {
|
if (autoFlush) {
|
||||||
wrapped.flushBuffer();
|
wrapped.flushBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class TrimWSFilterOutputStream extends FilterOutputStream {
|
static final class TrimWSFilterOutputStream extends FilterOutputStream {
|
||||||
boolean mLastWasWS = true; // Avoids leading WS by init to true
|
boolean lastWasWS = true; // Avoids leading WS by init to true
|
||||||
|
|
||||||
public TrimWSFilterOutputStream(OutputStream pOut) {
|
public TrimWSFilterOutputStream(OutputStream pOut) {
|
||||||
super(pOut);
|
super(pOut);
|
||||||
@@ -175,12 +175,12 @@ public class TrimWhiteSpaceFilter extends GenericFilter {
|
|||||||
if (!Character.isWhitespace((char) pByte)) {
|
if (!Character.isWhitespace((char) pByte)) {
|
||||||
// If char is not WS, just store
|
// If char is not WS, just store
|
||||||
super.write(pByte);
|
super.write(pByte);
|
||||||
mLastWasWS = false;
|
lastWasWS = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: Consider writing only 0x0a (LF) and 0x20 (space)
|
// TODO: Consider writing only 0x0a (LF) and 0x20 (space)
|
||||||
// Else, if char is WS, store first, skip the rest
|
// Else, if char is WS, store first, skip the rest
|
||||||
if (!mLastWasWS) {
|
if (!lastWasWS) {
|
||||||
if (pByte == 0x0d) { // Convert all CR/LF's to 0x0a
|
if (pByte == 0x0d) { // Convert all CR/LF's to 0x0a
|
||||||
super.write(0x0a);
|
super.write(0x0a);
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ public class TrimWhiteSpaceFilter extends GenericFilter {
|
|||||||
super.write(pByte);
|
super.write(pByte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mLastWasWS = true;
|
lastWasWS = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,23 +199,23 @@ public class TrimWhiteSpaceFilter extends GenericFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected OutputStream createOutputStream() throws IOException {
|
protected OutputStream createOutputStream() throws IOException {
|
||||||
return new TrimWSFilterOutputStream(mResponse.getOutputStream());
|
return new TrimWSFilterOutputStream(response.getOutputStream());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TrimWSServletResponseWrapper extends ServletResponseWrapper {
|
static class TrimWSServletResponseWrapper extends ServletResponseWrapper {
|
||||||
private final ServletResponseStreamDelegate mStreamDelegate = new TrimWSStreamDelegate(getResponse());
|
private final ServletResponseStreamDelegate streamDelegate = new TrimWSStreamDelegate(getResponse());
|
||||||
|
|
||||||
public TrimWSServletResponseWrapper(ServletResponse pResponse) {
|
public TrimWSServletResponseWrapper(ServletResponse pResponse) {
|
||||||
super(pResponse);
|
super(pResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServletOutputStream getOutputStream() throws IOException {
|
public ServletOutputStream getOutputStream() throws IOException {
|
||||||
return mStreamDelegate.getOutputStream();
|
return streamDelegate.getOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrintWriter getWriter() throws IOException {
|
public PrintWriter getWriter() throws IOException {
|
||||||
return mStreamDelegate.getWriter();
|
return streamDelegate.getWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentLength(int pLength) {
|
public void setContentLength(int pLength) {
|
||||||
@@ -224,12 +224,12 @@ public class TrimWhiteSpaceFilter extends GenericFilter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flushBuffer() throws IOException {
|
public void flushBuffer() throws IOException {
|
||||||
mStreamDelegate.flushBuffer();
|
streamDelegate.flushBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetBuffer() {
|
public void resetBuffer() {
|
||||||
mStreamDelegate.resetBuffer();
|
streamDelegate.resetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Consider picking up content-type/encoding, as we can only
|
// TODO: Consider picking up content-type/encoding, as we can only
|
||||||
|
|||||||
+9
-15
@@ -1,6 +1,7 @@
|
|||||||
package com.twelvemonkeys.servlet.cache;
|
package com.twelvemonkeys.servlet.cache;
|
||||||
|
|
||||||
import java.io.File;
|
import com.twelvemonkeys.lang.Validate;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,27 +12,20 @@ import java.net.URI;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/AbstractCacheRequest.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/AbstractCacheRequest.java#1 $
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractCacheRequest implements CacheRequest {
|
public abstract class AbstractCacheRequest implements CacheRequest {
|
||||||
private final URI mRequestURI;
|
private final URI requestURI;
|
||||||
private final String mMethod;
|
private final String method;
|
||||||
|
|
||||||
protected AbstractCacheRequest(final URI pRequestURI, final String pMethod) {
|
protected AbstractCacheRequest(final URI pRequestURI, final String pMethod) {
|
||||||
if (pRequestURI == null) {
|
requestURI = Validate.notNull(pRequestURI, "requestURI");
|
||||||
throw new IllegalArgumentException("request URI == null");
|
method = Validate.notNull(pMethod, "method");
|
||||||
}
|
|
||||||
if (pMethod == null) {
|
|
||||||
throw new IllegalArgumentException("method == null");
|
|
||||||
}
|
|
||||||
|
|
||||||
mRequestURI = pRequestURI;
|
|
||||||
mMethod = pMethod;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI getRequestURI() {
|
public URI getRequestURI() {
|
||||||
return mRequestURI;
|
return requestURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMethod() {
|
public String getMethod() {
|
||||||
return mMethod;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Consider overriding equals/hashcode
|
// TODO: Consider overriding equals/hashcode
|
||||||
@@ -39,7 +33,7 @@ public abstract class AbstractCacheRequest implements CacheRequest {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new StringBuilder(getClass().getSimpleName())
|
return new StringBuilder(getClass().getSimpleName())
|
||||||
.append("[URI=").append(mRequestURI)
|
.append("[URI=").append(requestURI)
|
||||||
.append(", parameters=").append(getParameters())
|
.append(", parameters=").append(getParameters())
|
||||||
.append(", headers=").append(getHeaders())
|
.append(", headers=").append(getHeaders())
|
||||||
.append("]").toString();
|
.append("]").toString();
|
||||||
|
|||||||
+8
-8
@@ -10,16 +10,16 @@ import java.util.*;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/AbstractCacheResponse.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/AbstractCacheResponse.java#1 $
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractCacheResponse implements CacheResponse {
|
public abstract class AbstractCacheResponse implements CacheResponse {
|
||||||
private int mStatus;
|
private int status;
|
||||||
private final Map<String, List<String>> mHeaders = new LinkedHashMap<String, List<String>>(); // Insertion order
|
private final Map<String, List<String>> headers = new LinkedHashMap<String, List<String>>(); // Insertion order
|
||||||
private final Map<String, List<String>> mReadableHeaders = Collections.unmodifiableMap(mHeaders);
|
private final Map<String, List<String>> readableHeaders = Collections.unmodifiableMap(headers);
|
||||||
|
|
||||||
public int getStatus() {
|
public int getStatus() {
|
||||||
return mStatus;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStatus(int pStatusCode) {
|
public void setStatus(int pStatusCode) {
|
||||||
mStatus = pStatusCode;
|
status = pStatusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addHeader(String pHeaderName, String pHeaderValue) {
|
public void addHeader(String pHeaderName, String pHeaderValue) {
|
||||||
@@ -31,15 +31,15 @@ public abstract class AbstractCacheResponse implements CacheResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setHeader(String pHeaderName, String pHeaderValue, boolean pAdd) {
|
private void setHeader(String pHeaderName, String pHeaderValue, boolean pAdd) {
|
||||||
List<String> values = pAdd ? mHeaders.get(pHeaderName) : null;
|
List<String> values = pAdd ? headers.get(pHeaderName) : null;
|
||||||
if (values == null) {
|
if (values == null) {
|
||||||
values = new ArrayList<String>();
|
values = new ArrayList<String>();
|
||||||
mHeaders.put(pHeaderName, values);
|
headers.put(pHeaderName, values);
|
||||||
}
|
}
|
||||||
values.add(pHeaderValue);
|
values.add(pHeaderValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, List<String>> getHeaders() {
|
public Map<String, List<String>> getHeaders() {
|
||||||
return mReadableHeaders;
|
return readableHeaders;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ import java.util.logging.Logger;
|
|||||||
*/
|
*/
|
||||||
public class CacheFilter extends GenericFilter {
|
public class CacheFilter extends GenericFilter {
|
||||||
|
|
||||||
HTTPCache mCache;
|
HTTPCache cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the filter
|
* Initializes the filter
|
||||||
@@ -99,7 +99,7 @@ public class CacheFilter extends GenericFilter {
|
|||||||
int maxCachedEntites = 10000;
|
int maxCachedEntites = 10000;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mCache = new HTTPCache(
|
cache = new HTTPCache(
|
||||||
getTempFolder(),
|
getTempFolder(),
|
||||||
expiryTime,
|
expiryTime,
|
||||||
memCacheSize * 1024 * 1024,
|
memCacheSize * 1024 * 1024,
|
||||||
@@ -120,7 +120,7 @@ public class CacheFilter extends GenericFilter {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
log("Created cache: " + mCache);
|
log("Created cache: " + cache);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e) {
|
catch (IllegalArgumentException e) {
|
||||||
throw new ServletConfigException("Could not create cache: " + e.toString(), e);
|
throw new ServletConfigException("Could not create cache: " + e.toString(), e);
|
||||||
@@ -136,8 +136,8 @@ public class CacheFilter extends GenericFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
log("Destroying cache: " + mCache);
|
log("Destroying cache: " + cache);
|
||||||
mCache = null;
|
cache = null;
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ public class CacheFilter extends GenericFilter {
|
|||||||
|
|
||||||
// Render fast
|
// Render fast
|
||||||
try {
|
try {
|
||||||
mCache.doCached(cacheRequest, cacheResponse, resolver);
|
cache.doCached(cacheRequest, cacheResponse, resolver);
|
||||||
}
|
}
|
||||||
catch (CacheException e) {
|
catch (CacheException e) {
|
||||||
if (e.getCause() instanceof ServletException) {
|
if (e.getCause() instanceof ServletException) {
|
||||||
|
|||||||
+45
-45
@@ -52,19 +52,19 @@ import java.io.PrintWriter;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/CacheResponseWrapper.java#3 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/CacheResponseWrapper.java#3 $
|
||||||
*/
|
*/
|
||||||
class CacheResponseWrapper extends HttpServletResponseWrapper {
|
class CacheResponseWrapper extends HttpServletResponseWrapper {
|
||||||
private ServletResponseStreamDelegate mStreamDelegate;
|
private ServletResponseStreamDelegate streamDelegate;
|
||||||
|
|
||||||
private CacheResponse mResponse;
|
private CacheResponse response;
|
||||||
private CachedEntity mCached;
|
private CachedEntity cached;
|
||||||
private WritableCachedResponse mCachedResponse;
|
private WritableCachedResponse cachedResponse;
|
||||||
|
|
||||||
private Boolean mCachable;
|
private Boolean cachable;
|
||||||
private int mStatus;
|
private int status;
|
||||||
|
|
||||||
public CacheResponseWrapper(final ServletCacheResponse pResponse, final CachedEntity pCached) {
|
public CacheResponseWrapper(final ServletCacheResponse pResponse, final CachedEntity pCached) {
|
||||||
super(pResponse.getResponse());
|
super(pResponse.getResponse());
|
||||||
mResponse = pResponse;
|
response = pResponse;
|
||||||
mCached = pCached;
|
cached = pCached;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,19 +75,19 @@ class CacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
methods below.
|
methods below.
|
||||||
*/
|
*/
|
||||||
private void init() {
|
private void init() {
|
||||||
mCachable = null;
|
cachable = null;
|
||||||
mStatus = SC_OK;
|
status = SC_OK;
|
||||||
mCachedResponse = mCached.createCachedResponse();
|
cachedResponse = cached.createCachedResponse();
|
||||||
mStreamDelegate = new ServletResponseStreamDelegate(this) {
|
streamDelegate = new ServletResponseStreamDelegate(this) {
|
||||||
protected OutputStream createOutputStream() throws IOException {
|
protected OutputStream createOutputStream() throws IOException {
|
||||||
// Test if this request is really cachable, otherwise,
|
// Test if this request is really cachable, otherwise,
|
||||||
// just write through to underlying response, and don't cache
|
// just write through to underlying response, and don't cache
|
||||||
if (isCachable()) {
|
if (isCachable()) {
|
||||||
return mCachedResponse.getOutputStream();
|
return cachedResponse.getOutputStream();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mCachedResponse.setStatus(mStatus);
|
cachedResponse.setStatus(status);
|
||||||
mCachedResponse.writeHeadersTo(CacheResponseWrapper.this.mResponse);
|
cachedResponse.writeHeadersTo(CacheResponseWrapper.this.response);
|
||||||
return super.getOutputStream();
|
return super.getOutputStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,25 +95,25 @@ class CacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CachedResponse getCachedResponse() {
|
CachedResponse getCachedResponse() {
|
||||||
return mCachedResponse.getCachedResponse();
|
return cachedResponse.getCachedResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCachable() {
|
public boolean isCachable() {
|
||||||
// NOTE: Intentionally not synchronized
|
// NOTE: Intentionally not synchronized
|
||||||
if (mCachable == null) {
|
if (cachable == null) {
|
||||||
mCachable = isCachableImpl();
|
cachable = isCachableImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mCachable;
|
return cachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCachableImpl() {
|
private boolean isCachableImpl() {
|
||||||
if (mStatus != SC_OK) {
|
if (status != SC_OK) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vary: *
|
// Vary: *
|
||||||
String[] values = mCachedResponse.getHeaderValues(HTTPCache.HEADER_VARY);
|
String[] values = cachedResponse.getHeaderValues(HTTPCache.HEADER_VARY);
|
||||||
if (values != null) {
|
if (values != null) {
|
||||||
for (String value : values) {
|
for (String value : values) {
|
||||||
if ("*".equals(value)) {
|
if ("*".equals(value)) {
|
||||||
@@ -123,7 +123,7 @@ class CacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cache-Control: no-cache, no-store, must-revalidate
|
// Cache-Control: no-cache, no-store, must-revalidate
|
||||||
values = mCachedResponse.getHeaderValues(HTTPCache.HEADER_CACHE_CONTROL);
|
values = cachedResponse.getHeaderValues(HTTPCache.HEADER_CACHE_CONTROL);
|
||||||
if (values != null) {
|
if (values != null) {
|
||||||
for (String value : values) {
|
for (String value : values) {
|
||||||
if (StringUtil.contains(value, "no-cache")
|
if (StringUtil.contains(value, "no-cache")
|
||||||
@@ -135,7 +135,7 @@ class CacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pragma: no-cache
|
// Pragma: no-cache
|
||||||
values = mCachedResponse.getHeaderValues(HTTPCache.HEADER_PRAGMA);
|
values = cachedResponse.getHeaderValues(HTTPCache.HEADER_PRAGMA);
|
||||||
if (values != null) {
|
if (values != null) {
|
||||||
for (String value : values) {
|
for (String value : values) {
|
||||||
if (StringUtil.contains(value, "no-cache")) {
|
if (StringUtil.contains(value, "no-cache")) {
|
||||||
@@ -148,16 +148,16 @@ class CacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void flushBuffer() throws IOException {
|
public void flushBuffer() throws IOException {
|
||||||
mStreamDelegate.flushBuffer();
|
streamDelegate.flushBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetBuffer() {
|
public void resetBuffer() {
|
||||||
// Servlet 2.3
|
// Servlet 2.3
|
||||||
mStreamDelegate.resetBuffer();
|
streamDelegate.resetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.reset();
|
super.reset();
|
||||||
}
|
}
|
||||||
// No else, might be cachable after all..
|
// No else, might be cachable after all..
|
||||||
@@ -165,26 +165,26 @@ class CacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ServletOutputStream getOutputStream() throws IOException {
|
public ServletOutputStream getOutputStream() throws IOException {
|
||||||
return mStreamDelegate.getOutputStream();
|
return streamDelegate.getOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrintWriter getWriter() throws IOException {
|
public PrintWriter getWriter() throws IOException {
|
||||||
return mStreamDelegate.getWriter();
|
return streamDelegate.getWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsHeader(String name) {
|
public boolean containsHeader(String name) {
|
||||||
return mCachedResponse.getHeaderValues(name) != null;
|
return cachedResponse.getHeaderValues(name) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendError(int pStatusCode, String msg) throws IOException {
|
public void sendError(int pStatusCode, String msg) throws IOException {
|
||||||
// NOT cachable
|
// NOT cachable
|
||||||
mStatus = pStatusCode;
|
status = pStatusCode;
|
||||||
super.sendError(pStatusCode, msg);
|
super.sendError(pStatusCode, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendError(int pStatusCode) throws IOException {
|
public void sendError(int pStatusCode) throws IOException {
|
||||||
// NOT cachable
|
// NOT cachable
|
||||||
mStatus = pStatusCode;
|
status = pStatusCode;
|
||||||
super.sendError(pStatusCode);
|
super.sendError(pStatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,63 +196,63 @@ class CacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
public void setStatus(int pStatusCode) {
|
public void setStatus(int pStatusCode) {
|
||||||
// NOT cachable unless pStatusCode == 200 (or a FEW others?)
|
// NOT cachable unless pStatusCode == 200 (or a FEW others?)
|
||||||
if (pStatusCode != SC_OK) {
|
if (pStatusCode != SC_OK) {
|
||||||
mStatus = pStatusCode;
|
status = pStatusCode;
|
||||||
super.setStatus(pStatusCode);
|
super.setStatus(pStatusCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendRedirect(String pLocation) throws IOException {
|
public void sendRedirect(String pLocation) throws IOException {
|
||||||
// NOT cachable
|
// NOT cachable
|
||||||
mStatus = SC_MOVED_TEMPORARILY;
|
status = SC_MOVED_TEMPORARILY;
|
||||||
super.sendRedirect(pLocation);
|
super.sendRedirect(pLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDateHeader(String pName, long pValue) {
|
public void setDateHeader(String pName, long pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.setDateHeader(pName, pValue);
|
super.setDateHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCachedResponse.setHeader(pName, NetUtil.formatHTTPDate(pValue));
|
cachedResponse.setHeader(pName, NetUtil.formatHTTPDate(pValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDateHeader(String pName, long pValue) {
|
public void addDateHeader(String pName, long pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.addDateHeader(pName, pValue);
|
super.addDateHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCachedResponse.addHeader(pName, NetUtil.formatHTTPDate(pValue));
|
cachedResponse.addHeader(pName, NetUtil.formatHTTPDate(pValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeader(String pName, String pValue) {
|
public void setHeader(String pName, String pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.setHeader(pName, pValue);
|
super.setHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCachedResponse.setHeader(pName, pValue);
|
cachedResponse.setHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addHeader(String pName, String pValue) {
|
public void addHeader(String pName, String pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.addHeader(pName, pValue);
|
super.addHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCachedResponse.addHeader(pName, pValue);
|
cachedResponse.addHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIntHeader(String pName, int pValue) {
|
public void setIntHeader(String pName, int pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.setIntHeader(pName, pValue);
|
super.setIntHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCachedResponse.setHeader(pName, String.valueOf(pValue));
|
cachedResponse.setHeader(pName, String.valueOf(pValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addIntHeader(String pName, int pValue) {
|
public void addIntHeader(String pName, int pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.addIntHeader(pName, pValue);
|
super.addIntHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCachedResponse.addHeader(pName, String.valueOf(pValue));
|
cachedResponse.addHeader(pName, String.valueOf(pValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setContentType(String type) {
|
public final void setContentType(String type) {
|
||||||
|
|||||||
+15
-17
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet.cache;
|
package com.twelvemonkeys.servlet.cache;
|
||||||
|
|
||||||
|
import com.twelvemonkeys.lang.Validate;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -39,21 +41,17 @@ import java.util.List;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/CachedEntityImpl.java#3 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/CachedEntityImpl.java#3 $
|
||||||
*/
|
*/
|
||||||
class CachedEntityImpl implements CachedEntity {
|
class CachedEntityImpl implements CachedEntity {
|
||||||
private String mCacheURI;
|
private String cacheURI;
|
||||||
private HTTPCache mCache;
|
private HTTPCache cache;
|
||||||
|
|
||||||
CachedEntityImpl(String pCacheURI, HTTPCache pCache) {
|
CachedEntityImpl(String pCacheURI, HTTPCache pCache) {
|
||||||
if (pCacheURI == null) {
|
cacheURI = Validate.notNull(pCacheURI, "cacheURI");
|
||||||
throw new IllegalArgumentException("cacheURI == null");
|
cache = pCache;
|
||||||
}
|
|
||||||
|
|
||||||
mCacheURI = pCacheURI;
|
|
||||||
mCache = pCache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(CacheRequest pRequest, CacheResponse pResponse) throws IOException {
|
public void render(CacheRequest pRequest, CacheResponse pResponse) throws IOException {
|
||||||
// Get cached content
|
// Get cached content
|
||||||
CachedResponse cached = mCache.getContent(mCacheURI, pRequest);
|
CachedResponse cached = cache.getContent(cacheURI, pRequest);
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (cached == null) {
|
if (cached == null) {
|
||||||
@@ -93,7 +91,7 @@ class CachedEntityImpl implements CachedEntity {
|
|||||||
}
|
}
|
||||||
catch (IllegalArgumentException e) {
|
catch (IllegalArgumentException e) {
|
||||||
// Seems to be a bug in FireFox 1.0.2..?!
|
// Seems to be a bug in FireFox 1.0.2..?!
|
||||||
mCache.log("Error in date header from user-agent. User-Agent: " + pRequest.getHeaders().get("User-Agent"), e);
|
cache.log("Error in date header from user-agent. User-Agent: " + pRequest.getHeaders().get("User-Agent"), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastModified == -1L || (ifModifiedSince < (lastModified / 1000L) * 1000L)) {
|
if (lastModified == -1L || (ifModifiedSince < (lastModified / 1000L) * 1000L)) {
|
||||||
@@ -134,8 +132,8 @@ class CachedEntityImpl implements CachedEntity {
|
|||||||
// CacheResponseWrapper response = (CacheResponseWrapper) pResponse;
|
// CacheResponseWrapper response = (CacheResponseWrapper) pResponse;
|
||||||
|
|
||||||
// if (response.isCachable()) {
|
// if (response.isCachable()) {
|
||||||
mCache.registerContent(
|
cache.registerContent(
|
||||||
mCacheURI,
|
cacheURI,
|
||||||
pRequest,
|
pRequest,
|
||||||
pResponse instanceof WritableCachedResponse ? ((WritableCachedResponse) pResponse).getCachedResponse() : pResponse
|
pResponse instanceof WritableCachedResponse ? ((WritableCachedResponse) pResponse).getCachedResponse() : pResponse
|
||||||
);
|
);
|
||||||
@@ -149,7 +147,7 @@ class CachedEntityImpl implements CachedEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isStale(CacheRequest pRequest) {
|
public boolean isStale(CacheRequest pRequest) {
|
||||||
return mCache.isContentStale(mCacheURI, pRequest);
|
return cache.isContentStale(cacheURI, pRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WritableCachedResponse createCachedResponse() {
|
public WritableCachedResponse createCachedResponse() {
|
||||||
@@ -157,16 +155,16 @@ class CachedEntityImpl implements CachedEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return (mCacheURI != null ? mCacheURI.hashCode() : 0) + 1397;
|
return (cacheURI != null ? cacheURI.hashCode() : 0) + 1397;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Object pOther) {
|
public boolean equals(Object pOther) {
|
||||||
return pOther instanceof CachedEntityImpl &&
|
return pOther instanceof CachedEntityImpl &&
|
||||||
((mCacheURI == null && ((CachedEntityImpl) pOther).mCacheURI == null) ||
|
((cacheURI == null && ((CachedEntityImpl) pOther).cacheURI == null) ||
|
||||||
mCacheURI != null && mCacheURI.equals(((CachedEntityImpl) pOther).mCacheURI));
|
cacheURI != null && cacheURI.equals(((CachedEntityImpl) pOther).cacheURI));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "CachedEntity[URI=" + mCacheURI + "]";
|
return "CachedEntity[URI=" + cacheURI + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+24
-26
@@ -29,6 +29,7 @@
|
|||||||
package com.twelvemonkeys.servlet.cache;
|
package com.twelvemonkeys.servlet.cache;
|
||||||
|
|
||||||
import com.twelvemonkeys.io.FastByteArrayOutputStream;
|
import com.twelvemonkeys.io.FastByteArrayOutputStream;
|
||||||
|
import com.twelvemonkeys.lang.Validate;
|
||||||
import com.twelvemonkeys.util.LinkedMap;
|
import com.twelvemonkeys.util.LinkedMap;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@@ -46,28 +47,25 @@ import java.util.Set;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/CachedResponseImpl.java#4 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/CachedResponseImpl.java#4 $
|
||||||
*/
|
*/
|
||||||
class CachedResponseImpl implements CachedResponse {
|
class CachedResponseImpl implements CachedResponse {
|
||||||
final protected Map<String, List<String>> mHeaders;
|
final protected Map<String, List<String>> headers;
|
||||||
protected int mHeadersSize;
|
protected int headersSize;
|
||||||
protected ByteArrayOutputStream mContent = null;
|
protected ByteArrayOutputStream content = null;
|
||||||
int mStatus;
|
int status;
|
||||||
|
|
||||||
protected CachedResponseImpl() {
|
protected CachedResponseImpl() {
|
||||||
mHeaders = new LinkedMap<String, List<String>>(); // Keep headers in insertion order
|
headers = new LinkedMap<String, List<String>>(); // Keep headers in insertion order
|
||||||
}
|
}
|
||||||
|
|
||||||
// For use by HTTPCache, when recreating CachedResponses from disk cache
|
// For use by HTTPCache, when recreating CachedResponses from disk cache
|
||||||
CachedResponseImpl(final int pStatus, final LinkedMap<String, List<String>> pHeaders, final int pHeaderSize, final byte[] pContent) {
|
CachedResponseImpl(final int pStatus, final LinkedMap<String, List<String>> pHeaders, final int pHeaderSize, final byte[] pContent) {
|
||||||
if (pHeaders == null) {
|
status = pStatus;
|
||||||
throw new IllegalArgumentException("headers == null");
|
headers = Validate.notNull(pHeaders, "headers");
|
||||||
}
|
headersSize = pHeaderSize;
|
||||||
mStatus = pStatus;
|
content = new FastByteArrayOutputStream(pContent);
|
||||||
mHeaders = pHeaders;
|
|
||||||
mHeadersSize = pHeaderSize;
|
|
||||||
mContent = new FastByteArrayOutputStream(pContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStatus() {
|
public int getStatus() {
|
||||||
return mStatus;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,11 +105,11 @@ class CachedResponseImpl implements CachedResponse {
|
|||||||
* @throws java.io.IOException
|
* @throws java.io.IOException
|
||||||
*/
|
*/
|
||||||
public void writeContentsTo(final OutputStream pStream) throws IOException {
|
public void writeContentsTo(final OutputStream pStream) throws IOException {
|
||||||
if (mContent == null) {
|
if (content == null) {
|
||||||
throw new IOException("Cache is null, no content to write.");
|
throw new IOException("Cache is null, no content to write.");
|
||||||
}
|
}
|
||||||
|
|
||||||
mContent.writeTo(pStream);
|
content.writeTo(pStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,7 +118,7 @@ class CachedResponseImpl implements CachedResponse {
|
|||||||
* @return an array of {@code String}s
|
* @return an array of {@code String}s
|
||||||
*/
|
*/
|
||||||
public String[] getHeaderNames() {
|
public String[] getHeaderNames() {
|
||||||
Set<String> headers = mHeaders.keySet();
|
Set<String> headers = this.headers.keySet();
|
||||||
return headers.toArray(new String[headers.size()]);
|
return headers.toArray(new String[headers.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +131,7 @@ class CachedResponseImpl implements CachedResponse {
|
|||||||
* such header in this response.
|
* such header in this response.
|
||||||
*/
|
*/
|
||||||
public String[] getHeaderValues(final String pHeaderName) {
|
public String[] getHeaderValues(final String pHeaderName) {
|
||||||
List<String> values = mHeaders.get(pHeaderName);
|
List<String> values = headers.get(pHeaderName);
|
||||||
if (values == null) {
|
if (values == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -153,13 +151,13 @@ class CachedResponseImpl implements CachedResponse {
|
|||||||
* such header in this response.
|
* such header in this response.
|
||||||
*/
|
*/
|
||||||
public String getHeaderValue(final String pHeaderName) {
|
public String getHeaderValue(final String pHeaderName) {
|
||||||
List<String> values = mHeaders.get(pHeaderName);
|
List<String> values = headers.get(pHeaderName);
|
||||||
return (values != null && values.size() > 0) ? values.get(0) : null;
|
return (values != null && values.size() > 0) ? values.get(0) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
// mContent.size() is exact size in bytes, mHeadersSize is an estimate
|
// content.size() is exact size in bytes, headersSize is an estimate
|
||||||
return (mContent != null ? mContent.size() : 0) + mHeadersSize;
|
return (content != null ? content.size() : 0) + headersSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(final Object pOther) {
|
public boolean equals(final Object pOther) {
|
||||||
@@ -180,9 +178,9 @@ class CachedResponseImpl implements CachedResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean equalsImpl(final CachedResponseImpl pOther) {
|
private boolean equalsImpl(final CachedResponseImpl pOther) {
|
||||||
return mHeadersSize == pOther.mHeadersSize &&
|
return headersSize == pOther.headersSize &&
|
||||||
(mContent == null ? pOther.mContent == null : mContent.equals(pOther.mContent)) &&
|
(content == null ? pOther.content == null : content.equals(pOther.content)) &&
|
||||||
mHeaders.equals(pOther.mHeaders);
|
headers.equals(pOther.headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean equalsGeneric(final CachedResponse pOther) {
|
private boolean equalsGeneric(final CachedResponse pOther) {
|
||||||
@@ -212,9 +210,9 @@ class CachedResponseImpl implements CachedResponse {
|
|||||||
|
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result;
|
int result;
|
||||||
result = mHeaders.hashCode();
|
result = headers.hashCode();
|
||||||
result = 29 * result + mHeadersSize;
|
result = 29 * result + headersSize;
|
||||||
result = 37 * result + (mContent != null ? mContent.hashCode() : 0);
|
result = 37 * result + (content != null ? content.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -13,13 +13,13 @@ import java.util.Map;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/ClientCacheRequest.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/ClientCacheRequest.java#1 $
|
||||||
*/
|
*/
|
||||||
public final class ClientCacheRequest extends AbstractCacheRequest {
|
public final class ClientCacheRequest extends AbstractCacheRequest {
|
||||||
private Map<String, List<String>> mParameters;
|
private Map<String, List<String>> parameters;
|
||||||
private Map<String, List<String>> mHeaders;
|
private Map<String, List<String>> headers;
|
||||||
|
|
||||||
public ClientCacheRequest(final URI pRequestURI,final Map<String, List<String>> pParameters, final Map<String, List<String>> pHeaders) {
|
public ClientCacheRequest(final URI pRequestURI,final Map<String, List<String>> pParameters, final Map<String, List<String>> pHeaders) {
|
||||||
super(pRequestURI, "GET"); // TODO: Consider supporting more than get? At least HEAD and OPTIONS...
|
super(pRequestURI, "GET"); // TODO: Consider supporting more than get? At least HEAD and OPTIONS...
|
||||||
mParameters = normalizeMap(pParameters);
|
parameters = normalizeMap(pParameters);
|
||||||
mHeaders = normalizeMap(pHeaders);
|
headers = normalizeMap(pHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <K, V> Map<K, V> normalizeMap(Map<K, V> pMap) {
|
private <K, V> Map<K, V> normalizeMap(Map<K, V> pMap) {
|
||||||
@@ -27,11 +27,11 @@ public final class ClientCacheRequest extends AbstractCacheRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, List<String>> getParameters() {
|
public Map<String, List<String>> getParameters() {
|
||||||
return mParameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, List<String>> getHeaders() {
|
public Map<String, List<String>> getHeaders() {
|
||||||
return mHeaders;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServerName() {
|
public String getServerName() {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ package com.twelvemonkeys.servlet.cache;
|
|||||||
|
|
||||||
import com.twelvemonkeys.io.FileUtil;
|
import com.twelvemonkeys.io.FileUtil;
|
||||||
import com.twelvemonkeys.lang.StringUtil;
|
import com.twelvemonkeys.lang.StringUtil;
|
||||||
|
import com.twelvemonkeys.lang.Validate;
|
||||||
import com.twelvemonkeys.net.MIMEUtil;
|
import com.twelvemonkeys.net.MIMEUtil;
|
||||||
import com.twelvemonkeys.net.NetUtil;
|
import com.twelvemonkeys.net.NetUtil;
|
||||||
import com.twelvemonkeys.util.LRUHashMap;
|
import com.twelvemonkeys.util.LRUHashMap;
|
||||||
@@ -153,30 +154,30 @@ public class HTTPCache {
|
|||||||
/**
|
/**
|
||||||
* The directory used for the disk-based cache
|
* The directory used for the disk-based cache
|
||||||
*/
|
*/
|
||||||
private File mTempDir;
|
private File tempDir;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates wether the disk-based cache should be deleted when the
|
* Indicates wether the disk-based cache should be deleted when the
|
||||||
* container shuts down/VM exits
|
* container shuts down/VM exits
|
||||||
*/
|
*/
|
||||||
private boolean mDeleteCacheOnExit;
|
private boolean deleteCacheOnExit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In-memory content cache
|
* In-memory content cache
|
||||||
*/
|
*/
|
||||||
private final Map<String, CachedResponse> mContentCache;
|
private final Map<String, CachedResponse> contentCache;
|
||||||
/**
|
/**
|
||||||
* In-memory enity cache
|
* In-memory enity cache
|
||||||
*/
|
*/
|
||||||
private final Map<String, CachedEntity> mEntityCache;
|
private final Map<String, CachedEntity> entityCache;
|
||||||
/**
|
/**
|
||||||
* In-memory varyiation-info cache
|
* In-memory varyiation-info cache
|
||||||
*/
|
*/
|
||||||
private final Map<String, Properties> mVaryCache;
|
private final Map<String, Properties> varyCache;
|
||||||
|
|
||||||
private long mDefaultExpiryTime = -1;
|
private long defaultExpiryTime = -1;
|
||||||
|
|
||||||
private final Logger mLogger;
|
private final Logger logger;
|
||||||
|
|
||||||
// Internal constructor for sublcasses only
|
// Internal constructor for sublcasses only
|
||||||
protected HTTPCache(
|
protected HTTPCache(
|
||||||
@@ -187,44 +188,33 @@ public class HTTPCache {
|
|||||||
final boolean pDeleteCacheOnExit,
|
final boolean pDeleteCacheOnExit,
|
||||||
final Logger pLogger
|
final Logger pLogger
|
||||||
) {
|
) {
|
||||||
if (pTempFolder == null) {
|
Validate.notNull(pTempFolder, "temp folder");
|
||||||
throw new IllegalArgumentException("temp folder == null");
|
Validate.isTrue(pTempFolder.exists() || pTempFolder.mkdirs(), pTempFolder.getAbsolutePath(), "Could not create required temp directory: %s");
|
||||||
}
|
Validate.isTrue(pTempFolder.canRead() && pTempFolder.canWrite(), pTempFolder.getAbsolutePath(), "Must have read/write access to temp folder: %s");
|
||||||
if (!pTempFolder.exists() && !pTempFolder.mkdirs()) {
|
|
||||||
throw new IllegalArgumentException("Could not create required temp directory: " + mTempDir.getAbsolutePath());
|
|
||||||
}
|
|
||||||
if (!(pTempFolder.canRead() && pTempFolder.canWrite())) {
|
|
||||||
throw new IllegalArgumentException("Must have read/write access to temp folder: " + mTempDir.getAbsolutePath());
|
|
||||||
}
|
|
||||||
if (pDefaultCacheExpiryTime < 0) {
|
|
||||||
throw new IllegalArgumentException("Negative expiry time");
|
|
||||||
}
|
|
||||||
if (pMaxMemCacheSize < 0) {
|
|
||||||
throw new IllegalArgumentException("Negative maximum memory cache size");
|
|
||||||
}
|
|
||||||
if (pMaxCachedEntites < 0) {
|
|
||||||
throw new IllegalArgumentException("Negative maximum number of cached entries");
|
|
||||||
}
|
|
||||||
|
|
||||||
mDefaultExpiryTime = pDefaultCacheExpiryTime;
|
Validate.isTrue(pDefaultCacheExpiryTime >= 0, pDefaultCacheExpiryTime, "Negative expiry time: %d");
|
||||||
|
Validate.isTrue(pMaxMemCacheSize >= 0, pDefaultCacheExpiryTime, "Negative maximum memory cache size: %d");
|
||||||
|
Validate.isTrue(pMaxCachedEntites >= 0, pDefaultCacheExpiryTime, "Negative maximum number of cached entries: %d");
|
||||||
|
|
||||||
|
defaultExpiryTime = pDefaultCacheExpiryTime;
|
||||||
|
|
||||||
if (pMaxMemCacheSize > 0) {
|
if (pMaxMemCacheSize > 0) {
|
||||||
// Map backing = new SizedLRUMap(pMaxMemCacheSize); // size in bytes
|
// Map backing = new SizedLRUMap(pMaxMemCacheSize); // size in bytes
|
||||||
// mContentCache = new TimeoutMap(backing, null, pDefaultCacheExpiryTime);
|
// contentCache = new TimeoutMap(backing, null, pDefaultCacheExpiryTime);
|
||||||
mContentCache = new SizedLRUMap<String, CachedResponse>(pMaxMemCacheSize); // size in bytes
|
contentCache = new SizedLRUMap<String, CachedResponse>(pMaxMemCacheSize); // size in bytes
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mContentCache = new NullMap<String, CachedResponse>();
|
contentCache = new NullMap<String, CachedResponse>();
|
||||||
}
|
}
|
||||||
|
|
||||||
mEntityCache = new LRUHashMap<String, CachedEntity>(pMaxCachedEntites);
|
entityCache = new LRUHashMap<String, CachedEntity>(pMaxCachedEntites);
|
||||||
mVaryCache = new LRUHashMap<String, Properties>(pMaxCachedEntites);
|
varyCache = new LRUHashMap<String, Properties>(pMaxCachedEntites);
|
||||||
|
|
||||||
mDeleteCacheOnExit = pDeleteCacheOnExit;
|
deleteCacheOnExit = pDeleteCacheOnExit;
|
||||||
|
|
||||||
mTempDir = pTempFolder;
|
tempDir = pTempFolder;
|
||||||
|
|
||||||
mLogger = pLogger != null ? pLogger : Logger.getLogger(getClass().getName());
|
logger = pLogger != null ? pLogger : Logger.getLogger(getClass().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -289,19 +279,15 @@ public class HTTPCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static File getTempFolder(String pName, ServletContext pContext) {
|
private static File getTempFolder(String pName, ServletContext pContext) {
|
||||||
if (pName == null) {
|
Validate.notNull(pName, "name");
|
||||||
throw new IllegalArgumentException("name == null");
|
Validate.isTrue(!StringUtil.isEmpty(pName), pName, "empty name: '%s'");
|
||||||
}
|
Validate.notNull(pContext, "context");
|
||||||
if (pName.trim().length() == 0) {
|
|
||||||
throw new IllegalArgumentException("Empty name");
|
|
||||||
}
|
|
||||||
if (pContext == null) {
|
|
||||||
throw new IllegalArgumentException("servlet context == null");
|
|
||||||
}
|
|
||||||
File tempRoot = (File) pContext.getAttribute("javax.servlet.context.tempdir");
|
File tempRoot = (File) pContext.getAttribute("javax.servlet.context.tempdir");
|
||||||
if (tempRoot == null) {
|
if (tempRoot == null) {
|
||||||
throw new IllegalStateException("Missing context attribute \"javax.servlet.context.tempdir\"");
|
throw new IllegalStateException("Missing context attribute \"javax.servlet.context.tempdir\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new File(tempRoot, pName);
|
return new File(tempRoot, pName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,36 +295,36 @@ public class HTTPCache {
|
|||||||
StringBuilder buf = new StringBuilder(getClass().getSimpleName());
|
StringBuilder buf = new StringBuilder(getClass().getSimpleName());
|
||||||
buf.append("[");
|
buf.append("[");
|
||||||
buf.append("Temp dir: ");
|
buf.append("Temp dir: ");
|
||||||
buf.append(mTempDir.getAbsolutePath());
|
buf.append(tempDir.getAbsolutePath());
|
||||||
if (mDeleteCacheOnExit) {
|
if (deleteCacheOnExit) {
|
||||||
buf.append(" (non-persistent)");
|
buf.append(" (non-persistent)");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
buf.append(" (persistent)");
|
buf.append(" (persistent)");
|
||||||
}
|
}
|
||||||
buf.append(", EntityCache: {");
|
buf.append(", EntityCache: {");
|
||||||
buf.append(mEntityCache.size());
|
buf.append(entityCache.size());
|
||||||
buf.append(" entries in a ");
|
buf.append(" entries in a ");
|
||||||
buf.append(mEntityCache.getClass().getName());
|
buf.append(entityCache.getClass().getName());
|
||||||
buf.append("}, VaryCache: {");
|
buf.append("}, VaryCache: {");
|
||||||
buf.append(mVaryCache.size());
|
buf.append(varyCache.size());
|
||||||
buf.append(" entries in a ");
|
buf.append(" entries in a ");
|
||||||
buf.append(mVaryCache.getClass().getName());
|
buf.append(varyCache.getClass().getName());
|
||||||
buf.append("}, ContentCache: {");
|
buf.append("}, ContentCache: {");
|
||||||
buf.append(mContentCache.size());
|
buf.append(contentCache.size());
|
||||||
buf.append(" entries in a ");
|
buf.append(" entries in a ");
|
||||||
buf.append(mContentCache.getClass().getName());
|
buf.append(contentCache.getClass().getName());
|
||||||
buf.append("}]");
|
buf.append("}]");
|
||||||
|
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void log(final String pMessage) {
|
void log(final String pMessage) {
|
||||||
mLogger.log(Level.INFO, pMessage);
|
logger.log(Level.INFO, pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void log(final String pMessage, Throwable pException) {
|
void log(final String pMessage, Throwable pException) {
|
||||||
mLogger.log(Level.WARNING, pMessage, pException);
|
logger.log(Level.WARNING, pMessage, pException);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -363,16 +349,16 @@ public class HTTPCache {
|
|||||||
|
|
||||||
// Get/create cached entity
|
// Get/create cached entity
|
||||||
CachedEntity cached;
|
CachedEntity cached;
|
||||||
synchronized (mEntityCache) {
|
synchronized (entityCache) {
|
||||||
cached = mEntityCache.get(cacheURI);
|
cached = entityCache.get(cacheURI);
|
||||||
if (cached == null) {
|
if (cached == null) {
|
||||||
cached = new CachedEntityImpl(cacheURI, this);
|
cached = new CachedEntityImpl(cacheURI, this);
|
||||||
mEntityCache.put(cacheURI, cached);
|
entityCache.put(cacheURI, cached);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// else if (not cached || stale), resolve through wrapped (caching) response
|
// else if (not cached ||�stale), resolve through wrapped (caching) response
|
||||||
// else render to response
|
// else render to response
|
||||||
|
|
||||||
// TODO: This is a bottleneck for uncachable resources. Should not
|
// TODO: This is a bottleneck for uncachable resources. Should not
|
||||||
@@ -412,11 +398,11 @@ public class HTTPCache {
|
|||||||
|
|
||||||
// Get/create cached entity
|
// Get/create cached entity
|
||||||
CachedEntity cached;
|
CachedEntity cached;
|
||||||
synchronized (mEntityCache) {
|
synchronized (entityCache) {
|
||||||
cached = mEntityCache.get(cacheURI);
|
cached = entityCache.get(cacheURI);
|
||||||
if (cached != null) {
|
if (cached != null) {
|
||||||
// TODO; Remove all variants
|
// TODO; Remove all variants
|
||||||
mEntityCache.remove(cacheURI);
|
entityCache.remove(cacheURI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,7 +517,7 @@ public class HTTPCache {
|
|||||||
File file = null;
|
File file = null;
|
||||||
|
|
||||||
// Get base dir
|
// Get base dir
|
||||||
File base = new File(mTempDir, "./" + pCacheURI);
|
File base = new File(tempDir, "./" + pCacheURI);
|
||||||
final String basePath = base.getAbsolutePath();
|
final String basePath = base.getAbsolutePath();
|
||||||
File directory = base.getParentFile();
|
File directory = base.getParentFile();
|
||||||
|
|
||||||
@@ -603,7 +589,7 @@ public class HTTPCache {
|
|||||||
synchronized (pVariations) {
|
synchronized (pVariations) {
|
||||||
try {
|
try {
|
||||||
File file = getVaryPropertiesFile(pCacheURI);
|
File file = getVaryPropertiesFile(pCacheURI);
|
||||||
if (!file.exists() && mDeleteCacheOnExit) {
|
if (!file.exists() && deleteCacheOnExit) {
|
||||||
file.deleteOnExit();
|
file.deleteOnExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,11 +610,11 @@ public class HTTPCache {
|
|||||||
private Properties getVaryProperties(final String pCacheURI) {
|
private Properties getVaryProperties(final String pCacheURI) {
|
||||||
Properties variations;
|
Properties variations;
|
||||||
|
|
||||||
synchronized (mVaryCache) {
|
synchronized (varyCache) {
|
||||||
variations = mVaryCache.get(pCacheURI);
|
variations = varyCache.get(pCacheURI);
|
||||||
if (variations == null) {
|
if (variations == null) {
|
||||||
variations = loadVaryProperties(pCacheURI);
|
variations = loadVaryProperties(pCacheURI);
|
||||||
mVaryCache.put(pCacheURI, variations);
|
varyCache.put(pCacheURI, variations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,7 +643,7 @@ public class HTTPCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private File getVaryPropertiesFile(final String pCacheURI) {
|
private File getVaryPropertiesFile(final String pCacheURI) {
|
||||||
return new File(mTempDir, "./" + pCacheURI + FILE_EXT_VARY);
|
return new File(tempDir, "./" + pCacheURI + FILE_EXT_VARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String generateCacheURI(final CacheRequest pRequest) {
|
private static String generateCacheURI(final CacheRequest pRequest) {
|
||||||
@@ -769,18 +755,18 @@ public class HTTPCache {
|
|||||||
extension = "[NULL]";
|
extension = "[NULL]";
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (mContentCache) {
|
synchronized (contentCache) {
|
||||||
mContentCache.put(pCacheURI + '.' + extension, pCachedResponse);
|
contentCache.put(pCacheURI + '.' + extension, pCachedResponse);
|
||||||
|
|
||||||
// This will be the default version
|
// This will be the default version
|
||||||
if (!mContentCache.containsKey(pCacheURI)) {
|
if (!contentCache.containsKey(pCacheURI)) {
|
||||||
mContentCache.put(pCacheURI, pCachedResponse);
|
contentCache.put(pCacheURI, pCachedResponse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the cached content to disk
|
// Write the cached content to disk
|
||||||
File content = new File(mTempDir, "./" + pCacheURI + '.' + extension);
|
File content = new File(tempDir, "./" + pCacheURI + '.' + extension);
|
||||||
if (mDeleteCacheOnExit && !content.exists()) {
|
if (deleteCacheOnExit && !content.exists()) {
|
||||||
content.deleteOnExit();
|
content.deleteOnExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -809,7 +795,7 @@ public class HTTPCache {
|
|||||||
|
|
||||||
// Write the cached headers to disk (in pseudo-properties-format)
|
// Write the cached headers to disk (in pseudo-properties-format)
|
||||||
File headers = new File(content.getAbsolutePath() + FILE_EXT_HEADERS);
|
File headers = new File(content.getAbsolutePath() + FILE_EXT_HEADERS);
|
||||||
if (mDeleteCacheOnExit && !headers.exists()) {
|
if (deleteCacheOnExit && !headers.exists()) {
|
||||||
headers.deleteOnExit();
|
headers.deleteOnExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -872,13 +858,13 @@ public class HTTPCache {
|
|||||||
String extension = getVaryExtension(pCacheURI, pRequest);
|
String extension = getVaryExtension(pCacheURI, pRequest);
|
||||||
|
|
||||||
CachedResponse response;
|
CachedResponse response;
|
||||||
synchronized (mContentCache) {
|
synchronized (contentCache) {
|
||||||
// System.out.println(" ## HTTPCache ## Looking up content with ext: \"" + extension + "\" from memory cache (" + mContentCache /*.size()*/ + " entries)...");
|
// System.out.println(" ## HTTPCache ## Looking up content with ext: \"" + extension + "\" from memory cache (" + contentCache /*.size()*/ + " entries)...");
|
||||||
if ("ANY".equals(extension)) {
|
if ("ANY".equals(extension)) {
|
||||||
response = mContentCache.get(pCacheURI);
|
response = contentCache.get(pCacheURI);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
response = mContentCache.get(pCacheURI + '.' + extension);
|
response = contentCache.get(pCacheURI + '.' + extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
@@ -932,7 +918,7 @@ public class HTTPCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
response = new CachedResponseImpl(STATUS_OK, headerMap, headerSize, contents);
|
response = new CachedResponseImpl(STATUS_OK, headerMap, headerSize, contents);
|
||||||
mContentCache.put(pCacheURI + '.' + FileUtil.getExtension(content), response);
|
contentCache.put(pCacheURI + '.' + FileUtil.getExtension(content), response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
@@ -997,7 +983,7 @@ public class HTTPCache {
|
|||||||
// If Cache-Control: max-age is present, use it, otherwise default
|
// If Cache-Control: max-age is present, use it, otherwise default
|
||||||
int maxAge = getIntHeader(response, HEADER_CACHE_CONTROL, "max-age");
|
int maxAge = getIntHeader(response, HEADER_CACHE_CONTROL, "max-age");
|
||||||
if (maxAge == -1) {
|
if (maxAge == -1) {
|
||||||
expires = lastModified + mDefaultExpiryTime;
|
expires = lastModified + defaultExpiryTime;
|
||||||
//// System.out.println(" ## HTTPCache ## Expires is " + NetUtil.formatHTTPDate(expires) + ", using lastModified + defaultExpiry");
|
//// System.out.println(" ## HTTPCache ## Expires is " + NetUtil.formatHTTPDate(expires) + ", using lastModified + defaultExpiry");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
+39
-39
@@ -55,16 +55,16 @@ import java.util.Map;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/SerlvetCacheResponseWrapper.java#2 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/SerlvetCacheResponseWrapper.java#2 $
|
||||||
*/
|
*/
|
||||||
class SerlvetCacheResponseWrapper extends HttpServletResponseWrapper {
|
class SerlvetCacheResponseWrapper extends HttpServletResponseWrapper {
|
||||||
private ServletResponseStreamDelegate mStreamDelegate;
|
private ServletResponseStreamDelegate streamDelegate;
|
||||||
|
|
||||||
private CacheResponse mCacheResponse;
|
private CacheResponse cacheResponse;
|
||||||
|
|
||||||
private Boolean mCachable;
|
private Boolean cachable;
|
||||||
private int mStatus;
|
private int status;
|
||||||
|
|
||||||
public SerlvetCacheResponseWrapper(final HttpServletResponse pServletResponse, final CacheResponse pResponse) {
|
public SerlvetCacheResponseWrapper(final HttpServletResponse pServletResponse, final CacheResponse pResponse) {
|
||||||
super(pServletResponse);
|
super(pServletResponse);
|
||||||
mCacheResponse = pResponse;
|
cacheResponse = pResponse;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,18 +76,18 @@ class SerlvetCacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
methods below.
|
methods below.
|
||||||
*/
|
*/
|
||||||
private void init() {
|
private void init() {
|
||||||
mCachable = null;
|
cachable = null;
|
||||||
mStatus = SC_OK;
|
status = SC_OK;
|
||||||
mStreamDelegate = new ServletResponseStreamDelegate(this) {
|
streamDelegate = new ServletResponseStreamDelegate(this) {
|
||||||
protected OutputStream createOutputStream() throws IOException {
|
protected OutputStream createOutputStream() throws IOException {
|
||||||
// Test if this request is really cachable, otherwise,
|
// Test if this request is really cachable, otherwise,
|
||||||
// just write through to underlying response, and don't cache
|
// just write through to underlying response, and don't cache
|
||||||
if (isCachable()) {
|
if (isCachable()) {
|
||||||
return mCacheResponse.getOutputStream();
|
return cacheResponse.getOutputStream();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: We need to tell the cache about this, somehow...
|
// TODO: We need to tell the cache about this, somehow...
|
||||||
writeHeaders(mCacheResponse, (HttpServletResponse) getResponse());
|
writeHeaders(cacheResponse, (HttpServletResponse) getResponse());
|
||||||
return super.getOutputStream();
|
return super.getOutputStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,21 +111,21 @@ class SerlvetCacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
|
|
||||||
public boolean isCachable() {
|
public boolean isCachable() {
|
||||||
// NOTE: Intentionally not synchronized
|
// NOTE: Intentionally not synchronized
|
||||||
if (mCachable == null) {
|
if (cachable == null) {
|
||||||
mCachable = isCachableImpl();
|
cachable = isCachableImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mCachable;
|
return cachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCachableImpl() {
|
private boolean isCachableImpl() {
|
||||||
// TODO: This code is duped in the cache...
|
// TODO: This code is duped in the cache...
|
||||||
if (mStatus != SC_OK) {
|
if (status != SC_OK) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vary: *
|
// Vary: *
|
||||||
List<String> values = mCacheResponse.getHeaders().get(HTTPCache.HEADER_VARY);
|
List<String> values = cacheResponse.getHeaders().get(HTTPCache.HEADER_VARY);
|
||||||
if (values != null) {
|
if (values != null) {
|
||||||
for (String value : values) {
|
for (String value : values) {
|
||||||
if ("*".equals(value)) {
|
if ("*".equals(value)) {
|
||||||
@@ -135,7 +135,7 @@ class SerlvetCacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cache-Control: no-cache, no-store, must-revalidate
|
// Cache-Control: no-cache, no-store, must-revalidate
|
||||||
values = mCacheResponse.getHeaders().get(HTTPCache.HEADER_CACHE_CONTROL);
|
values = cacheResponse.getHeaders().get(HTTPCache.HEADER_CACHE_CONTROL);
|
||||||
if (values != null) {
|
if (values != null) {
|
||||||
for (String value : values) {
|
for (String value : values) {
|
||||||
if (StringUtil.contains(value, "no-cache")
|
if (StringUtil.contains(value, "no-cache")
|
||||||
@@ -147,7 +147,7 @@ class SerlvetCacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pragma: no-cache
|
// Pragma: no-cache
|
||||||
values = mCacheResponse.getHeaders().get(HTTPCache.HEADER_PRAGMA);
|
values = cacheResponse.getHeaders().get(HTTPCache.HEADER_PRAGMA);
|
||||||
if (values != null) {
|
if (values != null) {
|
||||||
for (String value : values) {
|
for (String value : values) {
|
||||||
if (StringUtil.contains(value, "no-cache")) {
|
if (StringUtil.contains(value, "no-cache")) {
|
||||||
@@ -160,16 +160,16 @@ class SerlvetCacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void flushBuffer() throws IOException {
|
public void flushBuffer() throws IOException {
|
||||||
mStreamDelegate.flushBuffer();
|
streamDelegate.flushBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetBuffer() {
|
public void resetBuffer() {
|
||||||
// Servlet 2.3
|
// Servlet 2.3
|
||||||
mStreamDelegate.resetBuffer();
|
streamDelegate.resetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.reset();
|
super.reset();
|
||||||
}
|
}
|
||||||
// No else, might be cachable after all..
|
// No else, might be cachable after all..
|
||||||
@@ -177,26 +177,26 @@ class SerlvetCacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ServletOutputStream getOutputStream() throws IOException {
|
public ServletOutputStream getOutputStream() throws IOException {
|
||||||
return mStreamDelegate.getOutputStream();
|
return streamDelegate.getOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrintWriter getWriter() throws IOException {
|
public PrintWriter getWriter() throws IOException {
|
||||||
return mStreamDelegate.getWriter();
|
return streamDelegate.getWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsHeader(String name) {
|
public boolean containsHeader(String name) {
|
||||||
return mCacheResponse.getHeaders().get(name) != null;
|
return cacheResponse.getHeaders().get(name) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendError(int pStatusCode, String msg) throws IOException {
|
public void sendError(int pStatusCode, String msg) throws IOException {
|
||||||
// NOT cachable
|
// NOT cachable
|
||||||
mStatus = pStatusCode;
|
status = pStatusCode;
|
||||||
super.sendError(pStatusCode, msg);
|
super.sendError(pStatusCode, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendError(int pStatusCode) throws IOException {
|
public void sendError(int pStatusCode) throws IOException {
|
||||||
// NOT cachable
|
// NOT cachable
|
||||||
mStatus = pStatusCode;
|
status = pStatusCode;
|
||||||
super.sendError(pStatusCode);
|
super.sendError(pStatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,63 +208,63 @@ class SerlvetCacheResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
public void setStatus(int pStatusCode) {
|
public void setStatus(int pStatusCode) {
|
||||||
// NOT cachable unless pStatusCode == 200 (or a FEW others?)
|
// NOT cachable unless pStatusCode == 200 (or a FEW others?)
|
||||||
if (pStatusCode != SC_OK) {
|
if (pStatusCode != SC_OK) {
|
||||||
mStatus = pStatusCode;
|
status = pStatusCode;
|
||||||
super.setStatus(pStatusCode);
|
super.setStatus(pStatusCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendRedirect(String pLocation) throws IOException {
|
public void sendRedirect(String pLocation) throws IOException {
|
||||||
// NOT cachable
|
// NOT cachable
|
||||||
mStatus = SC_MOVED_TEMPORARILY;
|
status = SC_MOVED_TEMPORARILY;
|
||||||
super.sendRedirect(pLocation);
|
super.sendRedirect(pLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDateHeader(String pName, long pValue) {
|
public void setDateHeader(String pName, long pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.setDateHeader(pName, pValue);
|
super.setDateHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCacheResponse.setHeader(pName, NetUtil.formatHTTPDate(pValue));
|
cacheResponse.setHeader(pName, NetUtil.formatHTTPDate(pValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDateHeader(String pName, long pValue) {
|
public void addDateHeader(String pName, long pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.addDateHeader(pName, pValue);
|
super.addDateHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCacheResponse.addHeader(pName, NetUtil.formatHTTPDate(pValue));
|
cacheResponse.addHeader(pName, NetUtil.formatHTTPDate(pValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeader(String pName, String pValue) {
|
public void setHeader(String pName, String pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.setHeader(pName, pValue);
|
super.setHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCacheResponse.setHeader(pName, pValue);
|
cacheResponse.setHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addHeader(String pName, String pValue) {
|
public void addHeader(String pName, String pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.addHeader(pName, pValue);
|
super.addHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCacheResponse.addHeader(pName, pValue);
|
cacheResponse.addHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIntHeader(String pName, int pValue) {
|
public void setIntHeader(String pName, int pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.setIntHeader(pName, pValue);
|
super.setIntHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCacheResponse.setHeader(pName, String.valueOf(pValue));
|
cacheResponse.setHeader(pName, String.valueOf(pValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addIntHeader(String pName, int pValue) {
|
public void addIntHeader(String pName, int pValue) {
|
||||||
// If in write-trough-mode, set headers directly
|
// If in write-trough-mode, set headers directly
|
||||||
if (Boolean.FALSE.equals(mCachable)) {
|
if (Boolean.FALSE.equals(cachable)) {
|
||||||
super.addIntHeader(pName, pValue);
|
super.addIntHeader(pName, pValue);
|
||||||
}
|
}
|
||||||
mCacheResponse.addHeader(pName, String.valueOf(pValue));
|
cacheResponse.addHeader(pName, String.valueOf(pValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setContentType(String type) {
|
public final void setContentType(String type) {
|
||||||
|
|||||||
+13
-13
@@ -15,42 +15,42 @@ import java.util.Map;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/ServletCacheRequest.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/ServletCacheRequest.java#1 $
|
||||||
*/
|
*/
|
||||||
public final class ServletCacheRequest extends AbstractCacheRequest {
|
public final class ServletCacheRequest extends AbstractCacheRequest {
|
||||||
private final HttpServletRequest mRequest;
|
private final HttpServletRequest request;
|
||||||
|
|
||||||
private Map<String, List<String>> mHeaders;
|
private Map<String, List<String>> headers;
|
||||||
private Map<String, List<String>> mParameters;
|
private Map<String, List<String>> parameters;
|
||||||
|
|
||||||
protected ServletCacheRequest(final HttpServletRequest pRequest) {
|
protected ServletCacheRequest(final HttpServletRequest pRequest) {
|
||||||
super(URI.create(pRequest.getRequestURI()), pRequest.getMethod());
|
super(URI.create(pRequest.getRequestURI()), pRequest.getMethod());
|
||||||
mRequest = pRequest;
|
request = pRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, List<String>> getHeaders() {
|
public Map<String, List<String>> getHeaders() {
|
||||||
if (mHeaders == null) {
|
if (headers == null) {
|
||||||
mHeaders = ServletUtil.headersAsMap(mRequest);
|
headers = ServletUtil.headersAsMap(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mHeaders;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, List<String>> getParameters() {
|
public Map<String, List<String>> getParameters() {
|
||||||
if (mParameters == null) {
|
if (parameters == null) {
|
||||||
mParameters = ServletUtil.parametersAsMap(mRequest);
|
parameters = ServletUtil.parametersAsMap(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mParameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServerName() {
|
public String getServerName() {
|
||||||
return mRequest.getServerName();
|
return request.getServerName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getServerPort() {
|
public int getServerPort() {
|
||||||
return mRequest.getServerPort();
|
return request.getServerPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpServletRequest getRequest() {
|
HttpServletRequest getRequest() {
|
||||||
return mRequest;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -13,22 +13,22 @@ import java.io.IOException;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/ServletResponseResolver.java#2 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/ServletResponseResolver.java#2 $
|
||||||
*/
|
*/
|
||||||
final class ServletResponseResolver implements ResponseResolver {
|
final class ServletResponseResolver implements ResponseResolver {
|
||||||
final private ServletCacheRequest mRequest;
|
final private ServletCacheRequest request;
|
||||||
final private ServletCacheResponse mResponse;
|
final private ServletCacheResponse response;
|
||||||
final private FilterChain mChain;
|
final private FilterChain chain;
|
||||||
|
|
||||||
ServletResponseResolver(final ServletCacheRequest pRequest, final ServletCacheResponse pResponse, final FilterChain pChain) {
|
ServletResponseResolver(final ServletCacheRequest pRequest, final ServletCacheResponse pResponse, final FilterChain pChain) {
|
||||||
mRequest = pRequest;
|
request = pRequest;
|
||||||
mResponse = pResponse;
|
response = pResponse;
|
||||||
mChain = pChain;
|
chain = pChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resolve(final CacheRequest pRequest, final CacheResponse pResponse) throws IOException, CacheException {
|
public void resolve(final CacheRequest pRequest, final CacheResponse pResponse) throws IOException, CacheException {
|
||||||
// Need only wrap if pResponse is not mResponse...
|
// Need only wrap if pResponse is not response...
|
||||||
HttpServletResponse response = pResponse == mResponse ? mResponse.getResponse() : new SerlvetCacheResponseWrapper(mResponse.getResponse(), pResponse);
|
HttpServletResponse response = pResponse == this.response ? this.response.getResponse() : new SerlvetCacheResponseWrapper(this.response.getResponse(), pResponse);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mChain.doFilter(mRequest.getRequest(), response);
|
chain.doFilter(request.getRequest(), response);
|
||||||
}
|
}
|
||||||
catch (ServletException e) {
|
catch (ServletException e) {
|
||||||
throw new CacheException(e);
|
throw new CacheException(e);
|
||||||
|
|||||||
+25
-25
@@ -45,19 +45,19 @@ import java.util.Map;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/WritableCachedResponseImpl.java#3 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/cache/WritableCachedResponseImpl.java#3 $
|
||||||
*/
|
*/
|
||||||
class WritableCachedResponseImpl implements WritableCachedResponse {
|
class WritableCachedResponseImpl implements WritableCachedResponse {
|
||||||
private final CachedResponseImpl mCachedResponse;
|
private final CachedResponseImpl cachedResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code WritableCachedResponseImpl}.
|
* Creates a {@code WritableCachedResponseImpl}.
|
||||||
*/
|
*/
|
||||||
protected WritableCachedResponseImpl() {
|
protected WritableCachedResponseImpl() {
|
||||||
mCachedResponse = new CachedResponseImpl();
|
cachedResponse = new CachedResponseImpl();
|
||||||
// Hmmm..
|
// Hmmm..
|
||||||
setHeader(HTTPCache.HEADER_CACHED_TIME, NetUtil.formatHTTPDate(System.currentTimeMillis()));
|
setHeader(HTTPCache.HEADER_CACHED_TIME, NetUtil.formatHTTPDate(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachedResponse getCachedResponse() {
|
public CachedResponse getCachedResponse() {
|
||||||
return mCachedResponse;
|
return cachedResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeader(String pName, String pValue) {
|
public void setHeader(String pName, String pValue) {
|
||||||
@@ -69,7 +69,7 @@ class WritableCachedResponseImpl implements WritableCachedResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, List<String>> getHeaders() {
|
public Map<String, List<String>> getHeaders() {
|
||||||
return mCachedResponse.mHeaders;
|
return cachedResponse.headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +83,7 @@ class WritableCachedResponseImpl implements WritableCachedResponse {
|
|||||||
// If adding, get list and append, otherwise replace list
|
// If adding, get list and append, otherwise replace list
|
||||||
List<String> values = null;
|
List<String> values = null;
|
||||||
if (pAdd) {
|
if (pAdd) {
|
||||||
values = mCachedResponse.mHeaders.get(pName);
|
values = cachedResponse.headers.get(pName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values == null) {
|
if (values == null) {
|
||||||
@@ -91,18 +91,18 @@ class WritableCachedResponseImpl implements WritableCachedResponse {
|
|||||||
|
|
||||||
if (pAdd) {
|
if (pAdd) {
|
||||||
// Add length of pName
|
// Add length of pName
|
||||||
mCachedResponse.mHeadersSize += (pName != null ? pName.length() : 0);
|
cachedResponse.headersSize += (pName != null ? pName.length() : 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Remove length of potential replaced old values + pName
|
// Remove length of potential replaced old values + pName
|
||||||
String[] oldValues = getHeaderValues(pName);
|
String[] oldValues = getHeaderValues(pName);
|
||||||
if (oldValues != null) {
|
if (oldValues != null) {
|
||||||
for (String oldValue : oldValues) {
|
for (String oldValue : oldValues) {
|
||||||
mCachedResponse.mHeadersSize -= oldValue.length();
|
cachedResponse.headersSize -= oldValue.length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mCachedResponse.mHeadersSize += (pName != null ? pName.length() : 0);
|
cachedResponse.headersSize += (pName != null ? pName.length() : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,31 +112,31 @@ class WritableCachedResponseImpl implements WritableCachedResponse {
|
|||||||
values.add(pValue);
|
values.add(pValue);
|
||||||
|
|
||||||
// Add length of pValue
|
// Add length of pValue
|
||||||
mCachedResponse.mHeadersSize += pValue.length();
|
cachedResponse.headersSize += pValue.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always add to headers
|
// Always add to headers
|
||||||
mCachedResponse.mHeaders.put(pName, values);
|
cachedResponse.headers.put(pName, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputStream getOutputStream() {
|
public OutputStream getOutputStream() {
|
||||||
// TODO: Hmm.. Smells like DCL..?
|
// TODO: Hmm.. Smells like DCL..?
|
||||||
if (mCachedResponse.mContent == null) {
|
if (cachedResponse.content == null) {
|
||||||
createOutputStream();
|
createOutputStream();
|
||||||
}
|
}
|
||||||
return mCachedResponse.mContent;
|
return cachedResponse.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStatus(int pStatusCode) {
|
public void setStatus(int pStatusCode) {
|
||||||
mCachedResponse.mStatus = pStatusCode;
|
cachedResponse.status = pStatusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStatus() {
|
public int getStatus() {
|
||||||
return mCachedResponse.getStatus();
|
return cachedResponse.getStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void createOutputStream() {
|
private synchronized void createOutputStream() {
|
||||||
ByteArrayOutputStream cache = mCachedResponse.mContent;
|
ByteArrayOutputStream cache = cachedResponse.content;
|
||||||
if (cache == null) {
|
if (cache == null) {
|
||||||
String contentLengthStr = getHeaderValue("Content-Length");
|
String contentLengthStr = getHeaderValue("Content-Length");
|
||||||
if (contentLengthStr != null) {
|
if (contentLengthStr != null) {
|
||||||
@@ -146,43 +146,43 @@ class WritableCachedResponseImpl implements WritableCachedResponse {
|
|||||||
else {
|
else {
|
||||||
cache = new FastByteArrayOutputStream(1024);
|
cache = new FastByteArrayOutputStream(1024);
|
||||||
}
|
}
|
||||||
mCachedResponse.mContent = cache;
|
cachedResponse.content = cache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeHeadersTo(CacheResponse pResponse) {
|
public void writeHeadersTo(CacheResponse pResponse) {
|
||||||
mCachedResponse.writeHeadersTo(pResponse);
|
cachedResponse.writeHeadersTo(pResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeContentsTo(OutputStream pStream) throws IOException {
|
public void writeContentsTo(OutputStream pStream) throws IOException {
|
||||||
mCachedResponse.writeContentsTo(pStream);
|
cachedResponse.writeContentsTo(pStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getHeaderNames() {
|
public String[] getHeaderNames() {
|
||||||
return mCachedResponse.getHeaderNames();
|
return cachedResponse.getHeaderNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getHeaderValues(String pHeaderName) {
|
public String[] getHeaderValues(String pHeaderName) {
|
||||||
return mCachedResponse.getHeaderValues(pHeaderName);
|
return cachedResponse.getHeaderValues(pHeaderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHeaderValue(String pHeaderName) {
|
public String getHeaderValue(String pHeaderName) {
|
||||||
return mCachedResponse.getHeaderValue(pHeaderName);
|
return cachedResponse.getHeaderValue(pHeaderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return mCachedResponse.size();
|
return cachedResponse.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Object pOther) {
|
public boolean equals(Object pOther) {
|
||||||
if (pOther instanceof WritableCachedResponse) {
|
if (pOther instanceof WritableCachedResponse) {
|
||||||
// Take advantage of faster implementation
|
// Take advantage of faster implementation
|
||||||
return mCachedResponse.equals(((WritableCachedResponse) pOther).getCachedResponse());
|
return cachedResponse.equals(((WritableCachedResponse) pOther).getCachedResponse());
|
||||||
}
|
}
|
||||||
return mCachedResponse.equals(pOther);
|
return cachedResponse.equals(pOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return mCachedResponse.hashCode();
|
return cachedResponse.hashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,8 +54,8 @@ import java.net.MalformedURLException;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/fileupload/FileUploadFilter.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/fileupload/FileUploadFilter.java#1 $
|
||||||
*/
|
*/
|
||||||
public class FileUploadFilter extends GenericFilter {
|
public class FileUploadFilter extends GenericFilter {
|
||||||
private File mUploadDir;
|
private File uploadDir;
|
||||||
private long mMaxFileSize = 1024 * 1024; // 1 MByte
|
private long maxFileSize = 1024 * 1024; // 1 MByte
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called by the server before the filter goes into service,
|
* This method is called by the server before the filter goes into service,
|
||||||
@@ -66,17 +66,19 @@ public class FileUploadFilter extends GenericFilter {
|
|||||||
public void init() throws ServletException {
|
public void init() throws ServletException {
|
||||||
// Get the name of the upload directory.
|
// Get the name of the upload directory.
|
||||||
String uploadDirParam = getInitParameter("uploadDir");
|
String uploadDirParam = getInitParameter("uploadDir");
|
||||||
|
|
||||||
if (!StringUtil.isEmpty(uploadDirParam)) {
|
if (!StringUtil.isEmpty(uploadDirParam)) {
|
||||||
try {
|
try {
|
||||||
URL uploadDirURL = getServletContext().getResource(uploadDirParam);
|
URL uploadDirURL = getServletContext().getResource(uploadDirParam);
|
||||||
mUploadDir = FileUtil.toFile(uploadDirURL);
|
uploadDir = FileUtil.toFile(uploadDirURL);
|
||||||
}
|
}
|
||||||
catch (MalformedURLException e) {
|
catch (MalformedURLException e) {
|
||||||
throw new ServletException(e.getMessage(), e);
|
throw new ServletException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mUploadDir == null) {
|
|
||||||
mUploadDir = ServletUtil.getTempDir(getServletContext());
|
if (uploadDir == null) {
|
||||||
|
uploadDir = ServletUtil.getTempDir(getServletContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,23 +88,9 @@ public class FileUploadFilter extends GenericFilter {
|
|||||||
*
|
*
|
||||||
* @param pMaxSize
|
* @param pMaxSize
|
||||||
*/
|
*/
|
||||||
// public void setMaxFileSize(String pMaxSize) {
|
|
||||||
// try {
|
|
||||||
// setMaxFileSize(Long.parseLong(pMaxSize));
|
|
||||||
// }
|
|
||||||
// catch (NumberFormatException e) {
|
|
||||||
// log("Error setting maxFileSize, using default: " + mMaxFileSize, e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets max filesize allowed for upload.
|
|
||||||
*
|
|
||||||
* @param pMaxSize
|
|
||||||
*/
|
|
||||||
public void setMaxFileSize(long pMaxSize) {
|
public void setMaxFileSize(long pMaxSize) {
|
||||||
log("maxFileSize=" + pMaxSize);
|
log("maxFileSize=" + pMaxSize);
|
||||||
mMaxFileSize = pMaxSize;
|
maxFileSize = pMaxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -125,7 +113,7 @@ public class FileUploadFilter extends GenericFilter {
|
|||||||
|
|
||||||
// If the content type is multipart, wrap
|
// If the content type is multipart, wrap
|
||||||
if (isMultipartFileUpload(contentType)) {
|
if (isMultipartFileUpload(contentType)) {
|
||||||
pRequest = new HttpFileUploadRequestWrapper(request, mUploadDir, mMaxFileSize);
|
pRequest = new HttpFileUploadRequestWrapper(request, uploadDir, maxFileSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
pChain.doFilter(pRequest, pResponse);
|
pChain.doFilter(pRequest, pResponse);
|
||||||
|
|||||||
+10
-10
@@ -47,8 +47,8 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
class HttpFileUploadRequestWrapper extends HttpServletRequestWrapper implements HttpFileUploadRequest {
|
class HttpFileUploadRequestWrapper extends HttpServletRequestWrapper implements HttpFileUploadRequest {
|
||||||
|
|
||||||
private final Map<String, String[]> mParameters = new HashMap<String, String[]>();
|
private final Map<String, String[]> parameters = new HashMap<String, String[]>();
|
||||||
private final Map<String, UploadedFile[]> mFiles = new HashMap<String, UploadedFile[]>();
|
private final Map<String, UploadedFile[]> files = new HashMap<String, UploadedFile[]>();
|
||||||
|
|
||||||
public HttpFileUploadRequestWrapper(HttpServletRequest pRequest, File pUploadDir, long pMaxSize) throws ServletException {
|
public HttpFileUploadRequestWrapper(HttpServletRequest pRequest, File pUploadDir, long pMaxSize) throws ServletException {
|
||||||
super(pRequest);
|
super(pRequest);
|
||||||
@@ -86,7 +86,7 @@ class HttpFileUploadRequestWrapper extends HttpServletRequestWrapper implements
|
|||||||
String name = pItem.getFieldName();
|
String name = pItem.getFieldName();
|
||||||
|
|
||||||
UploadedFile[] values;
|
UploadedFile[] values;
|
||||||
UploadedFile[] oldValues = mFiles.get(name);
|
UploadedFile[] oldValues = files.get(name);
|
||||||
|
|
||||||
if (oldValues != null) {
|
if (oldValues != null) {
|
||||||
values = new UploadedFile[oldValues.length + 1];
|
values = new UploadedFile[oldValues.length + 1];
|
||||||
@@ -97,7 +97,7 @@ class HttpFileUploadRequestWrapper extends HttpServletRequestWrapper implements
|
|||||||
values = new UploadedFile[] {value};
|
values = new UploadedFile[] {value};
|
||||||
}
|
}
|
||||||
|
|
||||||
mFiles.put(name, values);
|
files.put(name, values);
|
||||||
|
|
||||||
// Also add to normal fields
|
// Also add to normal fields
|
||||||
processFormField(name, value.getName());
|
processFormField(name, value.getName());
|
||||||
@@ -108,7 +108,7 @@ class HttpFileUploadRequestWrapper extends HttpServletRequestWrapper implements
|
|||||||
// probably faster to just use arrays...
|
// probably faster to just use arrays...
|
||||||
// TODO: Research and document...
|
// TODO: Research and document...
|
||||||
String[] values;
|
String[] values;
|
||||||
String[] oldValues = mParameters.get(pName);
|
String[] oldValues = parameters.get(pName);
|
||||||
|
|
||||||
if (oldValues != null) {
|
if (oldValues != null) {
|
||||||
values = new String[oldValues.length + 1];
|
values = new String[oldValues.length + 1];
|
||||||
@@ -119,17 +119,17 @@ class HttpFileUploadRequestWrapper extends HttpServletRequestWrapper implements
|
|||||||
values = new String[] {pValue};
|
values = new String[] {pValue};
|
||||||
}
|
}
|
||||||
|
|
||||||
mParameters.put(pName, values);
|
parameters.put(pName, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map getParameterMap() {
|
public Map getParameterMap() {
|
||||||
// TODO: The spec dicates immutable map, but what about the value arrays?!
|
// TODO: The spec dicates immutable map, but what about the value arrays?!
|
||||||
// Probably just leave as-is, for performance
|
// Probably just leave as-is, for performance
|
||||||
return Collections.unmodifiableMap(mParameters);
|
return Collections.unmodifiableMap(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumeration getParameterNames() {
|
public Enumeration getParameterNames() {
|
||||||
return Collections.enumeration(mParameters.keySet());
|
return Collections.enumeration(parameters.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getParameter(String pString) {
|
public String getParameter(String pString) {
|
||||||
@@ -139,7 +139,7 @@ class HttpFileUploadRequestWrapper extends HttpServletRequestWrapper implements
|
|||||||
|
|
||||||
public String[] getParameterValues(String pString) {
|
public String[] getParameterValues(String pString) {
|
||||||
// TODO: Optimize?
|
// TODO: Optimize?
|
||||||
return mParameters.get(pString).clone();
|
return parameters.get(pString).clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public UploadedFile getUploadedFile(String pName) {
|
public UploadedFile getUploadedFile(String pName) {
|
||||||
@@ -149,6 +149,6 @@ class HttpFileUploadRequestWrapper extends HttpServletRequestWrapper implements
|
|||||||
|
|
||||||
public UploadedFile[] getUploadedFiles(String pName) {
|
public UploadedFile[] getUploadedFiles(String pName) {
|
||||||
// TODO: Optimize?
|
// TODO: Optimize?
|
||||||
return mFiles.get(pName).clone();
|
return files.get(pName).clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,35 +43,35 @@ import java.io.File;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/fileupload/UploadedFileImpl.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/fileupload/UploadedFileImpl.java#1 $
|
||||||
*/
|
*/
|
||||||
class UploadedFileImpl implements UploadedFile {
|
class UploadedFileImpl implements UploadedFile {
|
||||||
private final FileItem mItem;
|
private final FileItem item;
|
||||||
|
|
||||||
public UploadedFileImpl(FileItem pItem) {
|
public UploadedFileImpl(FileItem pItem) {
|
||||||
if (pItem == null) {
|
if (pItem == null) {
|
||||||
throw new IllegalArgumentException("fileitem == null");
|
throw new IllegalArgumentException("fileitem == null");
|
||||||
}
|
}
|
||||||
|
|
||||||
mItem = pItem;
|
item = pItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContentType() {
|
public String getContentType() {
|
||||||
return mItem.getContentType();
|
return item.getContentType();
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getInputStream() throws IOException {
|
public InputStream getInputStream() throws IOException {
|
||||||
return mItem.getInputStream();
|
return item.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return mItem.getName();
|
return item.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long length() {
|
public long length() {
|
||||||
return mItem.getSize();
|
return item.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeTo(File pFile) throws IOException {
|
public void writeTo(File pFile) throws IOException {
|
||||||
try {
|
try {
|
||||||
mItem.write(pFile);
|
item.write(pFile);
|
||||||
}
|
}
|
||||||
catch(RuntimeException e) {
|
catch(RuntimeException e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ import java.io.IOException;
|
|||||||
public class GZIPFilter extends GenericFilter {
|
public class GZIPFilter extends GenericFilter {
|
||||||
|
|
||||||
{
|
{
|
||||||
mOncePerRequest = true;
|
oncePerRequest = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException, ServletException {
|
protected void doFilterImpl(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException, ServletException {
|
||||||
|
|||||||
@@ -51,12 +51,12 @@ import java.util.zip.GZIPOutputStream;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/gzip/GZIPResponseWrapper.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/gzip/GZIPResponseWrapper.java#1 $
|
||||||
*/
|
*/
|
||||||
public class GZIPResponseWrapper extends HttpServletResponseWrapper {
|
public class GZIPResponseWrapper extends HttpServletResponseWrapper {
|
||||||
protected ServletOutputStream mOut = null;
|
protected ServletOutputStream out;
|
||||||
protected PrintWriter mWriter = null;
|
protected PrintWriter writer;
|
||||||
protected GZIPOutputStream mGZIPOut = null;
|
protected GZIPOutputStream gzipOut;
|
||||||
protected int mContentLength = -1;
|
protected int contentLength = -1;
|
||||||
|
|
||||||
public GZIPResponseWrapper(HttpServletResponse response) {
|
public GZIPResponseWrapper(final HttpServletResponse response) {
|
||||||
super(response);
|
super(response);
|
||||||
response.addHeader("Content-Encoding", "gzip");
|
response.addHeader("Content-Encoding", "gzip");
|
||||||
}
|
}
|
||||||
@@ -64,15 +64,15 @@ public class GZIPResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
public ServletOutputStream createOutputStream() throws IOException {
|
public ServletOutputStream createOutputStream() throws IOException {
|
||||||
// FIX: Write directly to servlet output stream, for faster responses.
|
// FIX: Write directly to servlet output stream, for faster responses.
|
||||||
// Relies on chunked streams, or buffering in the servlet engine.
|
// Relies on chunked streams, or buffering in the servlet engine.
|
||||||
if (mContentLength >= 0) {
|
if (contentLength >= 0) {
|
||||||
mGZIPOut = new GZIPOutputStream(getResponse().getOutputStream(), mContentLength);
|
gzipOut = new GZIPOutputStream(getResponse().getOutputStream(), contentLength);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mGZIPOut = new GZIPOutputStream(getResponse().getOutputStream());
|
gzipOut = new GZIPOutputStream(getResponse().getOutputStream());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap in ServletOutputStream and return
|
// Wrap in ServletOutputStream and return
|
||||||
return new OutputStreamAdapter(mGZIPOut);
|
return new OutputStreamAdapter(gzipOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this to flushbuffer or something? Hmmm..
|
// TODO: Move this to flushbuffer or something? Hmmm..
|
||||||
@@ -80,20 +80,20 @@ public class GZIPResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
// Finish GZIP encodig
|
// Finish GZIP encodig
|
||||||
if (mGZIPOut != null) {
|
if (gzipOut != null) {
|
||||||
mGZIPOut.finish();
|
gzipOut.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
flushBuffer();
|
flushBuffer();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
// Close stream
|
// Close stream
|
||||||
if (mWriter != null) {
|
if (writer != null) {
|
||||||
mWriter.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (mOut != null) {
|
if (out != null) {
|
||||||
mOut.close();
|
out.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,42 +105,42 @@ public class GZIPResponseWrapper extends HttpServletResponseWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void flushBuffer() throws IOException {
|
public void flushBuffer() throws IOException {
|
||||||
if (mWriter != null) {
|
if (writer != null) {
|
||||||
mWriter.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
else if (mOut != null) {
|
else if (out != null) {
|
||||||
mOut.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServletOutputStream getOutputStream() throws IOException {
|
public ServletOutputStream getOutputStream() throws IOException {
|
||||||
if (mWriter != null) {
|
if (writer != null) {
|
||||||
throw new IllegalStateException("getWriter() has already been called!");
|
throw new IllegalStateException("getWriter() has already been called!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mOut == null) {
|
if (out == null) {
|
||||||
mOut = createOutputStream();
|
out = createOutputStream();
|
||||||
}
|
}
|
||||||
return (mOut);
|
return (out);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrintWriter getWriter() throws IOException {
|
public PrintWriter getWriter() throws IOException {
|
||||||
if (mWriter != null) {
|
if (writer != null) {
|
||||||
return (mWriter);
|
return (writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mOut != null) {
|
if (out != null) {
|
||||||
throw new IllegalStateException("getOutputStream() has already been called!");
|
throw new IllegalStateException("getOutputStream() has already been called!");
|
||||||
}
|
}
|
||||||
|
|
||||||
mOut = createOutputStream();
|
out = createOutputStream();
|
||||||
// TODO: This is wrong. Should use getCharacterEncoding() or "ISO-8859-1" if gCE returns null.
|
// TODO: This is wrong. Should use getCharacterEncoding() or "ISO-8859-1" if gCE returns null.
|
||||||
mWriter = new PrintWriter(new OutputStreamWriter(mOut, "UTF-8"));
|
writer = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
|
||||||
return (mWriter);
|
return (writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentLength(int pLength) {
|
public void setContentLength(int pLength) {
|
||||||
// NOTE: Do not call super, as we will shrink the size.
|
// NOTE: Do not call super, as we will shrink the size.
|
||||||
mContentLength = pLength;
|
contentLength = pLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,12 +44,12 @@ import java.awt.image.RenderedImage;
|
|||||||
*/
|
*/
|
||||||
public class AWTImageFilterAdapter extends ImageFilter {
|
public class AWTImageFilterAdapter extends ImageFilter {
|
||||||
|
|
||||||
private java.awt.image.ImageFilter mFilter = null;
|
private java.awt.image.ImageFilter imageFilter = null;
|
||||||
|
|
||||||
public void setImageFilter(String pFilterClass) {
|
public void setImageFilter(String pFilterClass) {
|
||||||
try {
|
try {
|
||||||
Class filterClass = Class.forName(pFilterClass);
|
Class filterClass = Class.forName(pFilterClass);
|
||||||
mFilter = (java.awt.image.ImageFilter) filterClass.newInstance();
|
imageFilter = (java.awt.image.ImageFilter) filterClass.newInstance();
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException e) {
|
catch (ClassNotFoundException e) {
|
||||||
log("Could not load filter class.", e);
|
log("Could not load filter class.", e);
|
||||||
@@ -64,7 +64,7 @@ public class AWTImageFilterAdapter extends ImageFilter {
|
|||||||
|
|
||||||
protected RenderedImage doFilter(BufferedImage pImage, ServletRequest pRequest, ImageServletResponse pResponse) {
|
protected RenderedImage doFilter(BufferedImage pImage, ServletRequest pRequest, ImageServletResponse pResponse) {
|
||||||
// Filter
|
// Filter
|
||||||
Image img = ImageUtil.filter(pImage, mFilter);
|
Image img = ImageUtil.filter(pImage, imageFilter);
|
||||||
|
|
||||||
// Create BufferedImage & return
|
// Create BufferedImage & return
|
||||||
return ImageUtil.toBuffered(img, BufferedImage.TYPE_INT_RGB); // TODO: This is for JPEG only...
|
return ImageUtil.toBuffered(img, BufferedImage.TYPE_INT_RGB); // TODO: This is for JPEG only...
|
||||||
|
|||||||
@@ -42,12 +42,12 @@ import java.awt.image.RenderedImage;
|
|||||||
*/
|
*/
|
||||||
public class BufferedImageOpAdapter extends ImageFilter {
|
public class BufferedImageOpAdapter extends ImageFilter {
|
||||||
|
|
||||||
private BufferedImageOp mFilter = null;
|
private BufferedImageOp filter = null;
|
||||||
|
|
||||||
public void setImageFilter(String pFilterClass) {
|
public void setImageFilter(String pFilterClass) {
|
||||||
try {
|
try {
|
||||||
Class filterClass = Class.forName(pFilterClass);
|
Class filterClass = Class.forName(pFilterClass);
|
||||||
mFilter = (BufferedImageOp) filterClass.newInstance();
|
filter = (BufferedImageOp) filterClass.newInstance();
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException e) {
|
catch (ClassNotFoundException e) {
|
||||||
log("Could not instantiate filter class.", e);
|
log("Could not instantiate filter class.", e);
|
||||||
@@ -62,6 +62,6 @@ public class BufferedImageOpAdapter extends ImageFilter {
|
|||||||
|
|
||||||
protected RenderedImage doFilter(BufferedImage pImage, ServletRequest pRequest, ImageServletResponse pResponse) {
|
protected RenderedImage doFilter(BufferedImage pImage, ServletRequest pRequest, ImageServletResponse pResponse) {
|
||||||
// Filter & return
|
// Filter & return
|
||||||
return mFilter.filter(pImage, null);
|
return filter.filter(pImage, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public class ColorServlet extends GenericServlet {
|
|||||||
private final static int GREEN_IDX = RED_IDX + 1;
|
private final static int GREEN_IDX = RED_IDX + 1;
|
||||||
private final static int BLUE_IDX = GREEN_IDX + 1;
|
private final static int BLUE_IDX = GREEN_IDX + 1;
|
||||||
|
|
||||||
private final CRC32 mCRC = new CRC32();
|
private final CRC32 crc = new CRC32();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a ColorDroplet.
|
* Creates a ColorDroplet.
|
||||||
@@ -108,7 +108,6 @@ public class ColorServlet extends GenericServlet {
|
|||||||
* @throws ServletException
|
* @throws ServletException
|
||||||
*/
|
*/
|
||||||
public void service(ServletRequest pRequest, ServletResponse pResponse) throws IOException, ServletException {
|
public void service(ServletRequest pRequest, ServletResponse pResponse) throws IOException, ServletException {
|
||||||
|
|
||||||
int red = 0;
|
int red = 0;
|
||||||
int green = 0;
|
int green = 0;
|
||||||
int blue = 0;
|
int blue = 0;
|
||||||
@@ -172,10 +171,10 @@ public class ColorServlet extends GenericServlet {
|
|||||||
private void updateCRC(byte[] pBytes, int pOff, int pLen) {
|
private void updateCRC(byte[] pBytes, int pOff, int pLen) {
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
synchronized (mCRC) {
|
synchronized (crc) {
|
||||||
mCRC.reset();
|
crc.reset();
|
||||||
mCRC.update(pBytes, pOff, pLen);
|
crc.update(pBytes, pOff, pLen);
|
||||||
value = (int) mCRC.getValue();
|
value = (int) crc.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
pBytes[pOff + pLen ] = (byte) ((value >> 24) & 0xff);
|
pBytes[pOff + pLen ] = (byte) ((value >> 24) & 0xff);
|
||||||
|
|||||||
+10
-10
@@ -72,12 +72,12 @@ public class ContentNegotiationFilter extends ImageFilter {
|
|||||||
private final static String[] sKnownFormats = new String[] {
|
private final static String[] sKnownFormats = new String[] {
|
||||||
FORMAT_JPEG, FORMAT_PNG, FORMAT_GIF, FORMAT_WBMP
|
FORMAT_JPEG, FORMAT_PNG, FORMAT_GIF, FORMAT_WBMP
|
||||||
};
|
};
|
||||||
private float[] mKnownFormatQuality = new float[] {
|
private float[] knownFormatQuality = new float[] {
|
||||||
1f, 1f, 0.99f, 0.5f
|
1f, 1f, 0.99f, 0.5f
|
||||||
};
|
};
|
||||||
|
|
||||||
private HashMap<String, Float> mFormatQuality; // HashMap, as I need to clone this for each request
|
private HashMap<String, Float> formatQuality; // HashMap, as I need to clone this for each request
|
||||||
private final Object mLock = new Object();
|
private final Object lock = new Object();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
private Pattern[] mKnownAgentPatterns;
|
private Pattern[] mKnownAgentPatterns;
|
||||||
@@ -86,7 +86,7 @@ public class ContentNegotiationFilter extends ImageFilter {
|
|||||||
{
|
{
|
||||||
// Hack: Make sure the filter don't trigger all the time
|
// Hack: Make sure the filter don't trigger all the time
|
||||||
// See: super.trigger(ServletRequest)
|
// See: super.trigger(ServletRequest)
|
||||||
mTriggerParams = new String[] {};
|
triggerParams = new String[] {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -242,9 +242,9 @@ public class ContentNegotiationFilter extends ImageFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Float> getFormatQualityMapping() {
|
private Map<String, Float> getFormatQualityMapping() {
|
||||||
synchronized(mLock) {
|
synchronized(lock) {
|
||||||
if (mFormatQuality == null) {
|
if (formatQuality == null) {
|
||||||
mFormatQuality = new HashMap<String, Float>();
|
formatQuality = new HashMap<String, Float>();
|
||||||
|
|
||||||
// Use ImageIO to find formats we can actually write
|
// Use ImageIO to find formats we can actually write
|
||||||
String[] formats = ImageIO.getWriterMIMETypes();
|
String[] formats = ImageIO.getWriterMIMETypes();
|
||||||
@@ -252,12 +252,12 @@ public class ContentNegotiationFilter extends ImageFilter {
|
|||||||
// All known formats qs are initially 1.0
|
// All known formats qs are initially 1.0
|
||||||
// Others should be 0.1 or something like that...
|
// Others should be 0.1 or something like that...
|
||||||
for (String format : formats) {
|
for (String format : formats) {
|
||||||
mFormatQuality.put(format, getKnownFormatQuality(format));
|
formatQuality.put(format, getKnownFormatQuality(format));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (Map<String, Float>) mFormatQuality.clone();
|
return (Map<String, Float>) formatQuality.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -428,7 +428,7 @@ public class ContentNegotiationFilter extends ImageFilter {
|
|||||||
private float getKnownFormatQuality(String pFormat) {
|
private float getKnownFormatQuality(String pFormat) {
|
||||||
for (int i = 0; i < sKnownFormats.length; i++) {
|
for (int i = 0; i < sKnownFormats.length; i++) {
|
||||||
if (pFormat.equals(sKnownFormats[i])) {
|
if (pFormat.equals(sKnownFormats[i])) {
|
||||||
return mKnownFormatQuality[i];
|
return knownFormatQuality[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0.1f;
|
return 0.1f;
|
||||||
|
|||||||
@@ -49,15 +49,19 @@ import java.io.IOException;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class ImageFilter extends GenericFilter {
|
public abstract class ImageFilter extends GenericFilter {
|
||||||
|
// TODO: Take the design back to the drawing board (see ImageServletResponseImpl)
|
||||||
|
// - Allow multiple filters to set size attribute
|
||||||
|
// - Allow a later filter to reset, to get pass-through given certain criteria...
|
||||||
|
// - Or better yet, allow a filter to decide if it wants to decode, based on image metadata on the original image (ie: width/height)
|
||||||
|
|
||||||
protected String[] mTriggerParams = null;
|
protected String[] triggerParams = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code doFilterImpl} method is called once, or each time a
|
* The {@code doFilterImpl} method is called once, or each time a
|
||||||
* request/response pair is passed through the chain, depending on the
|
* request/response pair is passed through the chain, depending on the
|
||||||
* {@link #mOncePerRequest} member variable.
|
* {@link #oncePerRequest} member variable.
|
||||||
*
|
*
|
||||||
* @see #mOncePerRequest
|
* @see #oncePerRequest
|
||||||
* @see com.twelvemonkeys.servlet.GenericFilter#doFilterImpl doFilter
|
* @see com.twelvemonkeys.servlet.GenericFilter#doFilterImpl doFilter
|
||||||
* @see Filter#doFilter Filter.doFilter
|
* @see Filter#doFilter Filter.doFilter
|
||||||
*
|
*
|
||||||
@@ -107,8 +111,7 @@ public abstract class ImageFilter extends GenericFilter {
|
|||||||
//System.out.println("Done filtering.");
|
//System.out.println("Done filtering.");
|
||||||
|
|
||||||
//System.out.println("Making image available...");
|
//System.out.println("Making image available...");
|
||||||
// Make image available to other filters (avoid unnecessary
|
// Make image available to other filters (avoid unnecessary serializing/deserializing)
|
||||||
// serializing/deserializing)
|
|
||||||
imageResponse.setImage(image);
|
imageResponse.setImage(image);
|
||||||
//System.out.println("Done.");
|
//System.out.println("Done.");
|
||||||
|
|
||||||
@@ -156,7 +159,7 @@ public abstract class ImageFilter extends GenericFilter {
|
|||||||
/**
|
/**
|
||||||
* Tests if the filter should do image filtering/processing.
|
* Tests if the filter should do image filtering/processing.
|
||||||
* <P/>
|
* <P/>
|
||||||
* This default implementation uses {@link #mTriggerParams} to test if:
|
* This default implementation uses {@link #triggerParams} to test if:
|
||||||
* <dl>
|
* <dl>
|
||||||
* <dt>{@code mTriggerParams == null}</dt>
|
* <dt>{@code mTriggerParams == null}</dt>
|
||||||
* <dd>{@code return true}</dd>
|
* <dd>{@code return true}</dd>
|
||||||
@@ -173,12 +176,12 @@ public abstract class ImageFilter extends GenericFilter {
|
|||||||
*/
|
*/
|
||||||
protected boolean trigger(final ServletRequest pRequest) {
|
protected boolean trigger(final ServletRequest pRequest) {
|
||||||
// If triggerParams not set, assume always trigger
|
// If triggerParams not set, assume always trigger
|
||||||
if (mTriggerParams == null) {
|
if (triggerParams == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger only for certain request parameters
|
// Trigger only for certain request parameters
|
||||||
for (String triggerParam : mTriggerParams) {
|
for (String triggerParam : triggerParams) {
|
||||||
if (pRequest.getParameter(triggerParam) != null) {
|
if (pRequest.getParameter(triggerParam) != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -195,8 +198,9 @@ public abstract class ImageFilter extends GenericFilter {
|
|||||||
*
|
*
|
||||||
* @param pTriggerParams a comma-separated string of parameter names.
|
* @param pTriggerParams a comma-separated string of parameter names.
|
||||||
*/
|
*/
|
||||||
public void setTriggerParams(String pTriggerParams) {
|
// TODO: Make it an @InitParam, and make sure we may set String[]/Collection<String> as parameter?
|
||||||
mTriggerParams = StringUtil.toStringArray(pTriggerParams);
|
public void setTriggerParams(final String pTriggerParams) {
|
||||||
|
triggerParams = StringUtil.toStringArray(pTriggerParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+92
-88
@@ -60,7 +60,7 @@ import java.util.Iterator;
|
|||||||
* This {@link ImageServletResponse} implementation can be used with image
|
* This {@link ImageServletResponse} implementation can be used with image
|
||||||
* requests, to have the image immediately decoded to a {@code BufferedImage}.
|
* requests, to have the image immediately decoded to a {@code BufferedImage}.
|
||||||
* The image may be optionally subsampled, scaled and/or cropped.
|
* The image may be optionally subsampled, scaled and/or cropped.
|
||||||
* The response also automtically handles writing the image back to the underlying response stream
|
* The response also automatically handles writing the image back to the underlying response stream
|
||||||
* in the preferred format, when the response is flushed.
|
* in the preferred format, when the response is flushed.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
@@ -68,22 +68,23 @@ import java.util.Iterator;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletResponseImpl.java#10 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/image/ImageServletResponseImpl.java#10 $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
// TODO: Refactor out HTTP specifcs (if possible).
|
// TODO: Refactor out HTTP specifics (if possible).
|
||||||
// TODO: Is it a good ide to throw IIOException?
|
// TODO: Is it a good ide to throw IIOException?
|
||||||
// TODO: This implementation has a problem if two filters does scaling, as the second will overwrite the SIZE attribute
|
// 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)
|
||||||
class ImageServletResponseImpl extends HttpServletResponseWrapper implements ImageServletResponse {
|
class ImageServletResponseImpl extends HttpServletResponseWrapper implements ImageServletResponse {
|
||||||
|
|
||||||
private ServletRequest mOriginalRequest;
|
private ServletRequest originalRequest;
|
||||||
private final ServletContext mContext;
|
private final ServletContext context;
|
||||||
private final ServletResponseStreamDelegate mStreamDelegate;
|
private final ServletResponseStreamDelegate streamDelegate;
|
||||||
|
|
||||||
private FastByteArrayOutputStream mBufferedOut;
|
private FastByteArrayOutputStream bufferedOut;
|
||||||
|
|
||||||
private RenderedImage mImage;
|
private RenderedImage image;
|
||||||
private String mOutputContentType;
|
private String outputContentType;
|
||||||
|
|
||||||
private String mOriginalContentType;
|
private String originalContentType;
|
||||||
private int mOriginalContentLength = -1;
|
private int originalContentLength = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@code ImageServletResponseImpl}.
|
* Creates an {@code ImageServletResponseImpl}.
|
||||||
@@ -94,21 +95,21 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
*/
|
*/
|
||||||
public ImageServletResponseImpl(final HttpServletRequest pRequest, final HttpServletResponse pResponse, final ServletContext pContext) {
|
public ImageServletResponseImpl(final HttpServletRequest pRequest, final HttpServletResponse pResponse, final ServletContext pContext) {
|
||||||
super(pResponse);
|
super(pResponse);
|
||||||
mOriginalRequest = pRequest;
|
originalRequest = pRequest;
|
||||||
mStreamDelegate = new ServletResponseStreamDelegate(pResponse) {
|
streamDelegate = new ServletResponseStreamDelegate(pResponse) {
|
||||||
@Override
|
@Override
|
||||||
protected OutputStream createOutputStream() throws IOException {
|
protected OutputStream createOutputStream() throws IOException {
|
||||||
if (mOriginalContentLength >= 0) {
|
if (originalContentLength >= 0) {
|
||||||
mBufferedOut = new FastByteArrayOutputStream(mOriginalContentLength);
|
bufferedOut = new FastByteArrayOutputStream(originalContentLength);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mBufferedOut = new FastByteArrayOutputStream(0);
|
bufferedOut = new FastByteArrayOutputStream(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mBufferedOut;
|
return bufferedOut;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mContext = pContext;
|
context = pContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,7 +128,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setRequest(ServletRequest pRequest) {
|
public void setRequest(ServletRequest pRequest) {
|
||||||
mOriginalRequest = pRequest;
|
originalRequest = pRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -137,11 +138,11 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
*/
|
*/
|
||||||
public void setContentType(final String pMimeType) {
|
public void setContentType(final String pMimeType) {
|
||||||
// Throw exception is already set
|
// Throw exception is already set
|
||||||
if (mOriginalContentType != null) {
|
if (originalContentType != null) {
|
||||||
throw new IllegalStateException("ContentType already set.");
|
throw new IllegalStateException("ContentType already set.");
|
||||||
}
|
}
|
||||||
|
|
||||||
mOriginalContentType = pMimeType;
|
originalContentType = pMimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -151,7 +152,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public ServletOutputStream getOutputStream() throws IOException {
|
public ServletOutputStream getOutputStream() throws IOException {
|
||||||
return mStreamDelegate.getOutputStream();
|
return streamDelegate.getOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -161,7 +162,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public PrintWriter getWriter() throws IOException {
|
public PrintWriter getWriter() throws IOException {
|
||||||
return mStreamDelegate.getWriter();
|
return streamDelegate.getWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -170,11 +171,11 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
* @param pLength the content length
|
* @param pLength the content length
|
||||||
*/
|
*/
|
||||||
public void setContentLength(final int pLength) {
|
public void setContentLength(final int pLength) {
|
||||||
if (mOriginalContentLength != -1) {
|
if (originalContentLength != -1) {
|
||||||
throw new IllegalStateException("ContentLength already set.");
|
throw new IllegalStateException("ContentLength already set.");
|
||||||
}
|
}
|
||||||
|
|
||||||
mOriginalContentLength = pLength;
|
originalContentLength = pLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,59 +189,62 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
String outputType = getOutputContentType();
|
String outputType = getOutputContentType();
|
||||||
|
|
||||||
// Force transcoding, if no other filtering is done
|
// Force transcoding, if no other filtering is done
|
||||||
if (!outputType.equals(mOriginalContentType)) {
|
if (!outputType.equals(originalContentType)) {
|
||||||
getImage();
|
getImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mImage != null) {
|
if (image != null) {
|
||||||
Iterator writers = ImageIO.getImageWritersByMIMEType(outputType);
|
Iterator writers = ImageIO.getImageWritersByMIMEType(outputType);
|
||||||
if (writers.hasNext()) {
|
if (writers.hasNext()) {
|
||||||
super.setContentType(outputType);
|
super.setContentType(outputType);
|
||||||
OutputStream out = super.getOutputStream();
|
OutputStream out = super.getOutputStream();
|
||||||
|
|
||||||
ImageWriter writer = (ImageWriter) writers.next();
|
|
||||||
try {
|
try {
|
||||||
ImageWriteParam param = writer.getDefaultWriteParam();
|
ImageWriter writer = (ImageWriter) writers.next();
|
||||||
///////////////////
|
|
||||||
// POST-PROCESS
|
|
||||||
// For known formats that don't support transparency, convert to opaque
|
|
||||||
if (isNonAlphaFormat(outputType) && mImage.getColorModel().getTransparency() != Transparency.OPAQUE) {
|
|
||||||
mImage = ImageUtil.toBuffered(mImage, BufferedImage.TYPE_INT_RGB);
|
|
||||||
}
|
|
||||||
|
|
||||||
Float requestQuality = (Float) mOriginalRequest.getAttribute(ImageServletResponse.ATTRIB_OUTPUT_QUALITY);
|
|
||||||
|
|
||||||
// The default JPEG quality is not good enough, so always apply compression
|
|
||||||
if ((requestQuality != null || "jpeg".equalsIgnoreCase(getFormatNameSafe(writer))) && param.canWriteCompressed()) {
|
|
||||||
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
|
||||||
param.setCompressionQuality(requestQuality != null ? requestQuality : 0.8f);
|
|
||||||
}
|
|
||||||
//////////////////
|
|
||||||
ImageOutputStream stream = ImageIO.createImageOutputStream(out);
|
|
||||||
|
|
||||||
writer.setOutput(stream);
|
|
||||||
try {
|
try {
|
||||||
writer.write(null, new IIOImage(mImage, null, null), param);
|
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 apply compression
|
||||||
|
if ((requestQuality != null || "jpeg".equalsIgnoreCase(getFormatNameSafe(writer))) && param.canWriteCompressed()) {
|
||||||
|
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||||
|
param.setCompressionQuality(requestQuality != null ? requestQuality : 0.8f);
|
||||||
|
}
|
||||||
|
//////////////////
|
||||||
|
ImageOutputStream stream = ImageIO.createImageOutputStream(out);
|
||||||
|
|
||||||
|
writer.setOutput(stream);
|
||||||
|
try {
|
||||||
|
writer.write(null, new IIOImage(image, null, null), param);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
stream.close();
|
writer.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
writer.dispose();
|
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mContext.log("ERROR: No writer for content-type: " + outputType);
|
context.log("ERROR: No writer for content-type: " + outputType);
|
||||||
throw new IIOException("Unable to transcode image: No suitable image writer found (content-type: " + outputType + ").");
|
throw new IIOException("Unable to transcode image: No suitable image writer found (content-type: " + outputType + ").");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
super.setContentType(mOriginalContentType);
|
super.setContentType(originalContentType);
|
||||||
ServletOutputStream out = super.getOutputStream();
|
ServletOutputStream out = super.getOutputStream();
|
||||||
try {
|
try {
|
||||||
mBufferedOut.writeTo(out);
|
bufferedOut.writeTo(out);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
out.flush();
|
out.flush();
|
||||||
@@ -264,11 +268,11 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getOutputContentType() {
|
public String getOutputContentType() {
|
||||||
return mOutputContentType != null ? mOutputContentType : mOriginalContentType;
|
return outputContentType != null ? outputContentType : originalContentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOutputContentType(final String pImageFormat) {
|
public void setOutputContentType(final String pImageFormat) {
|
||||||
mOutputContentType = pImageFormat;
|
outputContentType = pImageFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -278,7 +282,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
* response stream
|
* response stream
|
||||||
*/
|
*/
|
||||||
public void setImage(final RenderedImage pImage) {
|
public void setImage(final RenderedImage pImage) {
|
||||||
mImage = pImage;
|
image = pImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -290,14 +294,14 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
* @throws java.io.IOException if an I/O exception occurs during reading
|
* @throws java.io.IOException if an I/O exception occurs during reading
|
||||||
*/
|
*/
|
||||||
public BufferedImage getImage() throws IOException {
|
public BufferedImage getImage() throws IOException {
|
||||||
if (mImage == null) {
|
if (image == null) {
|
||||||
// No content, no image
|
// No content, no image
|
||||||
if (mBufferedOut == null) {
|
if (bufferedOut == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read from the byte buffer
|
// Read from the byte buffer
|
||||||
InputStream byteStream = mBufferedOut.createInputStream();
|
InputStream byteStream = bufferedOut.createInputStream();
|
||||||
ImageInputStream input = null;
|
ImageInputStream input = null;
|
||||||
try {
|
try {
|
||||||
input = ImageIO.createImageInputStream(byteStream);
|
input = ImageIO.createImageInputStream(byteStream);
|
||||||
@@ -317,7 +321,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
// PRE-PROCESS (prepare): param, size, format?, request, response?
|
// PRE-PROCESS (prepare): param, size, format?, request, response?
|
||||||
// TODO: AOI strategy?
|
// TODO: AOI strategy?
|
||||||
// Extract AOI from request
|
// Extract AOI from request
|
||||||
Rectangle aoi = extractAOIFromRequest(originalWidth, originalHeight, mOriginalRequest);
|
Rectangle aoi = extractAOIFromRequest(originalWidth, originalHeight, originalRequest);
|
||||||
if (aoi != null) {
|
if (aoi != null) {
|
||||||
param.setSourceRegion(aoi);
|
param.setSourceRegion(aoi);
|
||||||
originalWidth = aoi.width;
|
originalWidth = aoi.width;
|
||||||
@@ -326,8 +330,8 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
|
|
||||||
// TODO: Size and subsampling strategy?
|
// TODO: Size and subsampling strategy?
|
||||||
// If possible, extract size from request
|
// If possible, extract size from request
|
||||||
Dimension size = extractSizeFromRequest(originalWidth, originalHeight, mOriginalRequest);
|
Dimension size = extractSizeFromRequest(originalWidth, originalHeight, originalRequest);
|
||||||
double readSubSamplingFactor = getReadSubsampleFactorFromRequest(mOriginalRequest);
|
double readSubSamplingFactor = getReadSubsampleFactorFromRequest(originalRequest);
|
||||||
if (size != null) {
|
if (size != null) {
|
||||||
//System.out.println("Size: " + size);
|
//System.out.println("Size: " + size);
|
||||||
if (param.canSetSourceRenderSize()) {
|
if (param.canSetSourceRenderSize()) {
|
||||||
@@ -358,21 +362,21 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
extractAndSetBackgroundColor(image); // TODO: Move to flush/POST-PROCESS
|
extractAndSetBackgroundColor(image); // TODO: Move to flush/POST-PROCESS
|
||||||
|
|
||||||
// Set image
|
// Set image
|
||||||
mImage = image;
|
this.image = image;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
reader.dispose();
|
reader.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mContext.log("ERROR: No suitable image reader found (content-type: " + mOriginalContentType + ").");
|
context.log("ERROR: No suitable image reader found (content-type: " + originalContentType + ").");
|
||||||
mContext.log("ERROR: Available formats: " + getFormatsString());
|
context.log("ERROR: Available formats: " + getFormatsString());
|
||||||
|
|
||||||
throw new IIOException("Unable to transcode image: No suitable image reader found (content-type: " + mOriginalContentType + ").");
|
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
|
// Free resources, as the image is now either read, or unreadable
|
||||||
mBufferedOut = null;
|
bufferedOut = null;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (input != null) {
|
if (input != null) {
|
||||||
@@ -382,7 +386,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Image is usually a BufferedImage, but may also be a RenderedImage
|
// Image is usually a BufferedImage, but may also be a RenderedImage
|
||||||
return mImage != null ? ImageUtil.toBuffered(mImage) : null;
|
return image != null ? ImageUtil.toBuffered(image) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BufferedImage resampleImage(final BufferedImage image, final Dimension size) {
|
private BufferedImage resampleImage(final BufferedImage image, final Dimension size) {
|
||||||
@@ -401,13 +405,13 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getResampleAlgorithmFromRequest() {
|
private int getResampleAlgorithmFromRequest() {
|
||||||
Object algorithm = mOriginalRequest.getAttribute(ATTRIB_IMAGE_RESAMPLE_ALGORITHM);
|
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)) {
|
if (algorithm instanceof Integer && ((Integer) algorithm == Image.SCALE_SMOOTH || (Integer) algorithm == Image.SCALE_FAST || (Integer) algorithm == Image.SCALE_DEFAULT)) {
|
||||||
return (Integer) algorithm;
|
return (Integer) algorithm;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (algorithm != null) {
|
if (algorithm != null) {
|
||||||
mContext.log("WARN: Illegal image resampling algorithm: " + algorithm);
|
context.log("WARN: Illegal image resampling algorithm: " + algorithm);
|
||||||
}
|
}
|
||||||
return BufferedImage.SCALE_DEFAULT;
|
return BufferedImage.SCALE_DEFAULT;
|
||||||
}
|
}
|
||||||
@@ -422,7 +426,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (factor != null) {
|
if (factor != null) {
|
||||||
mContext.log("WARN: Illegal read subsampling factor: " + factor);
|
context.log("WARN: Illegal read subsampling factor: " + factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
subsampleFactor = 2.0;
|
subsampleFactor = 2.0;
|
||||||
@@ -434,7 +438,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
private void extractAndSetBackgroundColor(final BufferedImage pImage) {
|
private void extractAndSetBackgroundColor(final BufferedImage pImage) {
|
||||||
// TODO: bgColor request attribute instead of parameter?
|
// TODO: bgColor request attribute instead of parameter?
|
||||||
if (pImage.getColorModel().hasAlpha()) {
|
if (pImage.getColorModel().hasAlpha()) {
|
||||||
String bgColor = mOriginalRequest.getParameter("bg.color");
|
String bgColor = originalRequest.getParameter("bg.color");
|
||||||
if (bgColor != null) {
|
if (bgColor != null) {
|
||||||
Color color = StringUtil.toColor(bgColor);
|
Color color = StringUtil.toColor(bgColor);
|
||||||
|
|
||||||
@@ -465,7 +469,7 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void maybeSetBaseURIFromRequest(final ImageReadParam pParam) {
|
private void maybeSetBaseURIFromRequest(final ImageReadParam pParam) {
|
||||||
if (mOriginalRequest instanceof HttpServletRequest) {
|
if (originalRequest instanceof HttpServletRequest) {
|
||||||
try {
|
try {
|
||||||
// If there's a setBaseURI method, we'll try to use that (uses reflection, to avoid dependency on plugins)
|
// If there's a setBaseURI method, we'll try to use that (uses reflection, to avoid dependency on plugins)
|
||||||
Method setBaseURI;
|
Method setBaseURI;
|
||||||
@@ -477,22 +481,22 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get URL for resource and set as base
|
// Get URL for resource and set as base
|
||||||
String baseURI = ServletUtil.getContextRelativeURI((HttpServletRequest) mOriginalRequest);
|
String baseURI = ServletUtil.getContextRelativeURI((HttpServletRequest) originalRequest);
|
||||||
|
|
||||||
URL resourceURL = mContext.getResource(baseURI);
|
URL resourceURL = context.getResource(baseURI);
|
||||||
if (resourceURL == null) {
|
if (resourceURL == null) {
|
||||||
resourceURL = ServletUtil.getRealURL(mContext, baseURI);
|
resourceURL = ServletUtil.getRealURL(context, baseURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resourceURL != null) {
|
if (resourceURL != null) {
|
||||||
setBaseURI.invoke(pParam, resourceURL.toExternalForm());
|
setBaseURI.invoke(pParam, resourceURL.toExternalForm());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mContext.log("WARN: Resource URL not found for URI: " + baseURI);
|
context.log("WARN: Resource URL not found for URI: " + baseURI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
mContext.log("WARN: Could not set base URI: ", e);
|
context.log("WARN: Could not set base URI: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -500,10 +504,10 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
private Dimension extractSizeFromRequest(final int pDefaultWidth, final int pDefaultHeight, final ServletRequest pOriginalRequest) {
|
private Dimension extractSizeFromRequest(final int pDefaultWidth, final int pDefaultHeight, final ServletRequest pOriginalRequest) {
|
||||||
// TODO: Allow extraction from request parameters
|
// TODO: Allow extraction from request parameters
|
||||||
/*
|
/*
|
||||||
int sizeW = ServletUtil.getIntParameter(mOriginalRequest, "size.w", -1);
|
int sizeW = ServletUtil.getIntParameter(originalRequest, "size.w", -1);
|
||||||
int sizeH = ServletUtil.getIntParameter(mOriginalRequest, "size.h", -1);
|
int sizeH = ServletUtil.getIntParameter(originalRequest, "size.h", -1);
|
||||||
boolean sizePercent = ServletUtil.getBooleanParameter(mOriginalRequest, "size.percent", false);
|
boolean sizePercent = ServletUtil.getBooleanParameter(originalRequest, "size.percent", false);
|
||||||
boolean sizeUniform = ServletUtil.getBooleanParameter(mOriginalRequest, "size.uniform", true);
|
boolean sizeUniform = ServletUtil.getBooleanParameter(originalRequest, "size.uniform", true);
|
||||||
*/
|
*/
|
||||||
Dimension size = (Dimension) pOriginalRequest.getAttribute(ATTRIB_SIZE);
|
Dimension size = (Dimension) pOriginalRequest.getAttribute(ATTRIB_SIZE);
|
||||||
int sizeW = size != null ? size.width : -1;
|
int sizeW = size != null ? size.width : -1;
|
||||||
@@ -525,12 +529,12 @@ class ImageServletResponseImpl extends HttpServletResponseWrapper implements Ima
|
|||||||
private Rectangle extractAOIFromRequest(final int pDefaultWidth, final int pDefaultHeight, final ServletRequest pOriginalRequest) {
|
private Rectangle extractAOIFromRequest(final int pDefaultWidth, final int pDefaultHeight, final ServletRequest pOriginalRequest) {
|
||||||
// TODO: Allow extraction from request parameters
|
// TODO: Allow extraction from request parameters
|
||||||
/*
|
/*
|
||||||
int aoiX = ServletUtil.getIntParameter(mOriginalRequest, "aoi.x", -1);
|
int aoiX = ServletUtil.getIntParameter(originalRequest, "aoi.x", -1);
|
||||||
int aoiY = ServletUtil.getIntParameter(mOriginalRequest, "aoi.y", -1);
|
int aoiY = ServletUtil.getIntParameter(originalRequest, "aoi.y", -1);
|
||||||
int aoiW = ServletUtil.getIntParameter(mOriginalRequest, "aoi.w", -1);
|
int aoiW = ServletUtil.getIntParameter(originalRequest, "aoi.w", -1);
|
||||||
int aoiH = ServletUtil.getIntParameter(mOriginalRequest, "aoi.h", -1);
|
int aoiH = ServletUtil.getIntParameter(originalRequest, "aoi.h", -1);
|
||||||
boolean aoiPercent = ServletUtil.getBooleanParameter(mOriginalRequest, "aoi.percent", false);
|
boolean aoiPercent = ServletUtil.getBooleanParameter(originalRequest, "aoi.percent", false);
|
||||||
boolean aoiUniform = ServletUtil.getBooleanParameter(mOriginalRequest, "aoi.uniform", false);
|
boolean aoiUniform = ServletUtil.getBooleanParameter(originalRequest, "aoi.uniform", false);
|
||||||
*/
|
*/
|
||||||
Rectangle aoi = (Rectangle) pOriginalRequest.getAttribute(ATTRIB_AOI);
|
Rectangle aoi = (Rectangle) pOriginalRequest.getAttribute(ATTRIB_AOI);
|
||||||
int aoiX = aoi != null ? aoi.x : -1;
|
int aoiX = aoi != null ? aoi.x : -1;
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ public class ScaleFilter extends ImageFilter {
|
|||||||
protected final static String PARAM_IMAGE = "image";
|
protected final static String PARAM_IMAGE = "image";
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
protected int mDefaultScaleQuality = Image.SCALE_DEFAULT;
|
protected int defaultScaleQuality = Image.SCALE_DEFAULT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the image from the requested URL, scales it, and returns it in the
|
* Reads the image from the requested URL, scales it, and returns it in the
|
||||||
@@ -188,11 +188,11 @@ public class ScaleFilter extends ImageFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mDefaultScaleQuality;
|
return defaultScaleQuality;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultScaleQuality(String pDefaultScaleQuality) {
|
public void setDefaultScaleQuality(String pDefaultScaleQuality) {
|
||||||
mDefaultScaleQuality = getQuality(pDefaultScaleQuality);
|
defaultScaleQuality = getQuality(pDefaultScaleQuality);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -77,9 +77,9 @@ public class SourceRenderFilter extends ImageFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void init() throws ServletException {
|
public void init() throws ServletException {
|
||||||
if (mTriggerParams == null) {
|
if (triggerParams == null) {
|
||||||
// Add all params as triggers
|
// Add all params as triggers
|
||||||
mTriggerParams = new String[]{mSizeWidthParam, mSizeHeightParam,
|
triggerParams = new String[]{mSizeWidthParam, mSizeHeightParam,
|
||||||
mSizeUniformParam, mSizePercentParam,
|
mSizeUniformParam, mSizePercentParam,
|
||||||
mRegionLeftParam, mRegionTopParam,
|
mRegionLeftParam, mRegionTopParam,
|
||||||
mRegionWidthParam, mRegionHeightParam,
|
mRegionWidthParam, mRegionHeightParam,
|
||||||
|
|||||||
@@ -17,13 +17,14 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet.jsp.droplet;
|
package com.twelvemonkeys.servlet.jsp.droplet;
|
||||||
|
|
||||||
import java.io.*;
|
import com.twelvemonkeys.servlet.jsp.droplet.taglib.IncludeTag;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.*;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.jsp.*;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import com.twelvemonkeys.servlet.jsp.droplet.taglib.*;
|
import javax.servlet.jsp.PageContext;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dynamo Droplet like Servlet.
|
* Dynamo Droplet like Servlet.
|
||||||
@@ -44,8 +45,7 @@ public abstract class Droplet extends HttpServlet implements JspFragment {
|
|||||||
* Services a parameter. Programatically equivalent to the
|
* Services a parameter. Programatically equivalent to the
|
||||||
* <d:valueof param="pParameter"/> JSP tag.
|
* <d:valueof param="pParameter"/> JSP tag.
|
||||||
*/
|
*/
|
||||||
public void serviceParameter(String pParameter, PageContext pPageContext)
|
public void serviceParameter(String pParameter, PageContext pPageContext) throws ServletException, IOException {
|
||||||
throws ServletException, IOException {
|
|
||||||
Object param = pPageContext.getRequest().getAttribute(pParameter);
|
Object param = pPageContext.getRequest().getAttribute(pParameter);
|
||||||
|
|
||||||
if (param != null) {
|
if (param != null) {
|
||||||
@@ -68,11 +68,8 @@ public abstract class Droplet extends HttpServlet implements JspFragment {
|
|||||||
/**
|
/**
|
||||||
* "There's no need to override this method." :-)
|
* "There's no need to override this method." :-)
|
||||||
*/
|
*/
|
||||||
final public void service(HttpServletRequest pRequest,
|
final public void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException {
|
||||||
HttpServletResponse pResponse)
|
PageContext pageContext = (PageContext) pRequest.getAttribute(IncludeTag.PAGE_CONTEXT);
|
||||||
throws ServletException, IOException {
|
|
||||||
PageContext pageContext =
|
|
||||||
(PageContext) pRequest.getAttribute(IncludeTag.PAGE_CONTEXT);
|
|
||||||
|
|
||||||
// TODO: What if pageContext == null
|
// TODO: What if pageContext == null
|
||||||
service(pageContext);
|
service(pageContext);
|
||||||
|
|||||||
@@ -14,10 +14,9 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet.jsp.droplet;
|
package com.twelvemonkeys.servlet.jsp.droplet;
|
||||||
|
|
||||||
import java.io.*;
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.jsp.PageContext;
|
||||||
import javax.servlet.*;
|
import java.io.IOException;
|
||||||
import javax.servlet.jsp.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for JSP sub pages or page fragments to implement.
|
* Interface for JSP sub pages or page fragments to implement.
|
||||||
@@ -39,6 +38,5 @@ public interface JspFragment {
|
|||||||
* subpage's normal operation
|
* subpage's normal operation
|
||||||
* @throws IOException if an input or output exception occurs
|
* @throws IOException if an input or output exception occurs
|
||||||
*/
|
*/
|
||||||
public void service(PageContext pContext)
|
public void service(PageContext pContext) throws ServletException, IOException;
|
||||||
throws ServletException, IOException;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,10 @@ public class Oparam extends Param implements JspFragment {
|
|||||||
super(pValue);
|
super(pValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void service(PageContext pContext)
|
public void service(PageContext pContext) throws ServletException, IOException {
|
||||||
throws ServletException, IOException {
|
pContext.getServletContext().log("Service subpage " + pContext.getServletContext().getRealPath(value));
|
||||||
pContext.getServletContext().log("Service subpage " + pContext.getServletContext().getRealPath(mValue));
|
|
||||||
|
|
||||||
pContext.include(mValue);
|
pContext.include(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet.jsp.droplet;
|
package com.twelvemonkeys.servlet.jsp.droplet;
|
||||||
|
|
||||||
import java.io.*;
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.jsp.JspWriter;
|
||||||
import javax.servlet.*;
|
import javax.servlet.jsp.PageContext;
|
||||||
import javax.servlet.jsp.*;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Param
|
* Param
|
||||||
@@ -12,7 +12,7 @@ import javax.servlet.jsp.*;
|
|||||||
public class Param implements JspFragment {
|
public class Param implements JspFragment {
|
||||||
|
|
||||||
/** The value member field. */
|
/** The value member field. */
|
||||||
protected String mValue = null;
|
protected String value = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Param.
|
* Creates a Param.
|
||||||
@@ -20,14 +20,14 @@ public class Param implements JspFragment {
|
|||||||
* @param pValue the value of the parameter
|
* @param pValue the value of the parameter
|
||||||
*/
|
*/
|
||||||
public Param(String pValue) {
|
public Param(String pValue) {
|
||||||
mValue = pValue;
|
value = pValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value of the parameter.
|
* Gets the value of the parameter.
|
||||||
*/
|
*/
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return mValue;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,6 +37,6 @@ public class Param implements JspFragment {
|
|||||||
public void service(PageContext pContext)
|
public void service(PageContext pContext)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
JspWriter writer = pContext.getOut();
|
JspWriter writer = pContext.getOut();
|
||||||
writer.print(mValue);
|
writer.print(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-21
@@ -41,20 +41,20 @@ public class IncludeTag extends ExTagSupport {
|
|||||||
* This will contain the names of all the parameters that have been
|
* This will contain the names of all the parameters that have been
|
||||||
* added to the PageContext.REQUEST_SCOPE scope by this tag.
|
* added to the PageContext.REQUEST_SCOPE scope by this tag.
|
||||||
*/
|
*/
|
||||||
private ArrayList mParameterNames = null;
|
private ArrayList<String> parameterNames = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If any of the parameters we insert for this tag already exist, then
|
* If any of the parameters we insert for this tag already exist, then
|
||||||
* we back up the older parameter in this {@code HashMap} and
|
* we back up the older parameter in this {@code HashMap} and
|
||||||
* restore them when the tag is finished.
|
* restore them when the tag is finished.
|
||||||
*/
|
*/
|
||||||
private HashMap mOldParameters = null;
|
private HashMap<String, Object> oldParameters = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the URL for the JSP page that the parameters contained in this
|
* This is the URL for the JSP page that the parameters contained in this
|
||||||
* tag are to be inserted into.
|
* tag are to be inserted into.
|
||||||
*/
|
*/
|
||||||
private String mPage;
|
private String page;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the PageContext attribute
|
* The name of the PageContext attribute
|
||||||
@@ -68,7 +68,7 @@ public class IncludeTag extends ExTagSupport {
|
|||||||
* @param pPage The URL for the JSP page to insert parameters into.
|
* @param pPage The URL for the JSP page to insert parameters into.
|
||||||
*/
|
*/
|
||||||
public void setPage(String pPage) {
|
public void setPage(String pPage) {
|
||||||
mPage = pPage;
|
page = pPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,13 +85,13 @@ public class IncludeTag extends ExTagSupport {
|
|||||||
*/
|
*/
|
||||||
public void addParameter(String pName, Object pValue) {
|
public void addParameter(String pName, Object pValue) {
|
||||||
// Check that we haven't already saved this parameter
|
// Check that we haven't already saved this parameter
|
||||||
if (!mParameterNames.contains(pName)) {
|
if (!parameterNames.contains(pName)) {
|
||||||
mParameterNames.add(pName);
|
parameterNames.add(pName);
|
||||||
|
|
||||||
// Now check if this parameter already exists in the page.
|
// Now check if this parameter already exists in the page.
|
||||||
Object obj = getRequest().getAttribute(pName);
|
Object obj = getRequest().getAttribute(pName);
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
mOldParameters.put(pName, obj);
|
oldParameters.put(pName, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,8 +110,8 @@ public class IncludeTag extends ExTagSupport {
|
|||||||
* @exception JspException
|
* @exception JspException
|
||||||
*/
|
*/
|
||||||
public int doStartTag() throws JspException {
|
public int doStartTag() throws JspException {
|
||||||
mOldParameters = new HashMap();
|
oldParameters = new HashMap<String, Object>();
|
||||||
mParameterNames = new ArrayList();
|
parameterNames = new ArrayList<String>();
|
||||||
|
|
||||||
return EVAL_BODY_INCLUDE;
|
return EVAL_BODY_INCLUDE;
|
||||||
}
|
}
|
||||||
@@ -129,44 +129,44 @@ public class IncludeTag extends ExTagSupport {
|
|||||||
String msg;
|
String msg;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Iterator iterator;
|
Iterator<String> iterator;
|
||||||
String parameterName;
|
String parameterName;
|
||||||
|
|
||||||
// -- Harald K 20020726
|
// -- Harald K 20020726
|
||||||
// Include the page, in place
|
// Include the page, in place
|
||||||
//getDispatcher().include(getRequest(), getResponse());
|
//getDispatcher().include(getRequest(), getResponse());
|
||||||
addParameter(PAGE_CONTEXT, pageContext); // Will be cleared later
|
addParameter(PAGE_CONTEXT, pageContext); // Will be cleared later
|
||||||
pageContext.include(mPage);
|
pageContext.include(page);
|
||||||
|
|
||||||
// Remove all the parameters that were added to the request scope
|
// Remove all the parameters that were added to the request scope
|
||||||
// for this insert tag.
|
// for this insert tag.
|
||||||
iterator = mParameterNames.iterator();
|
iterator = parameterNames.iterator();
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
parameterName = (String) iterator.next();
|
parameterName = iterator.next();
|
||||||
|
|
||||||
getRequest().removeAttribute(parameterName);
|
getRequest().removeAttribute(parameterName);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator = mOldParameters.keySet().iterator();
|
iterator = oldParameters.keySet().iterator();
|
||||||
|
|
||||||
// Restore the parameters we temporarily replaced (if any).
|
// Restore the parameters we temporarily replaced (if any).
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
parameterName = (String) iterator.next();
|
parameterName = iterator.next();
|
||||||
|
|
||||||
getRequest().setAttribute(parameterName, mOldParameters.get(parameterName));
|
getRequest().setAttribute(parameterName, oldParameters.get(parameterName));
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.doEndTag();
|
return super.doEndTag();
|
||||||
}
|
}
|
||||||
catch (IOException ioe) {
|
catch (IOException ioe) {
|
||||||
msg = "Caught an IOException while including " + mPage
|
msg = "Caught an IOException while including " + page
|
||||||
+ "\n" + ioe.toString();
|
+ "\n" + ioe.toString();
|
||||||
log(msg, ioe);
|
log(msg, ioe);
|
||||||
throw new JspException(msg);
|
throw new JspException(msg);
|
||||||
}
|
}
|
||||||
catch (ServletException se) {
|
catch (ServletException se) {
|
||||||
msg = "Caught a ServletException while including " + mPage
|
msg = "Caught a ServletException while including " + page
|
||||||
+ "\n" + se.toString();
|
+ "\n" + se.toString();
|
||||||
log(msg, se);
|
log(msg, se);
|
||||||
throw new JspException(msg);
|
throw new JspException(msg);
|
||||||
@@ -177,8 +177,8 @@ public class IncludeTag extends ExTagSupport {
|
|||||||
* Free up the member variables that we've used throughout this tag.
|
* Free up the member variables that we've used throughout this tag.
|
||||||
*/
|
*/
|
||||||
protected void clearServiceState() {
|
protected void clearServiceState() {
|
||||||
mOldParameters = null;
|
oldParameters = null;
|
||||||
mParameterNames = null;
|
parameterNames = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -190,7 +190,7 @@ public class IncludeTag extends ExTagSupport {
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
private RequestDispatcher getDispatcher() {
|
private RequestDispatcher getDispatcher() {
|
||||||
return getRequest().getRequestDispatcher(mPage);
|
return getRequest().getRequestDispatcher(page);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
+52
-53
@@ -41,27 +41,26 @@ import org.xml.sax.helpers.DefaultHandler;
|
|||||||
*
|
*
|
||||||
* @version $Revision: #1 $, ($Date: 2008/05/05 $)
|
* @version $Revision: #1 $, ($Date: 2008/05/05 $)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class NestingHandler extends DefaultHandler {
|
public class NestingHandler extends DefaultHandler {
|
||||||
private String mIncludeTagName = "include";
|
private String includeTagName = "include";
|
||||||
private String mParamTagName = "param";
|
private String paramTagName = "param";
|
||||||
private String mOpenParamTagName = "oparam";
|
private String openParamTagName = "oparam";
|
||||||
|
|
||||||
//private Stack mParents = new Stack();
|
//private Stack mParents = new Stack();
|
||||||
|
|
||||||
private boolean mInIncludeTag = false;
|
private boolean inIncludeTag = false;
|
||||||
|
|
||||||
private String mNamespacePrefix = null;
|
private String namespacePrefix = null;
|
||||||
private String mNamespaceURI = null;
|
private String namespaceURI = null;
|
||||||
|
|
||||||
private NestingValidator mValidator = null;
|
private NestingValidator validator = null;
|
||||||
|
|
||||||
public NestingHandler(String pNamespacePrefix, String pNameSpaceURI,
|
public NestingHandler(String pNamespacePrefix, String pNameSpaceURI,
|
||||||
NestingValidator pValidator) {
|
NestingValidator pValidator) {
|
||||||
mNamespacePrefix = pNamespacePrefix;
|
namespacePrefix = pNamespacePrefix;
|
||||||
mNamespaceURI = pNameSpaceURI;
|
namespaceURI = pNameSpaceURI;
|
||||||
|
|
||||||
mValidator = pValidator;
|
validator = pValidator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startElement(String pNamespaceURI, String pLocalName,
|
public void startElement(String pNamespaceURI, String pLocalName,
|
||||||
@@ -74,7 +73,7 @@ public class NestingHandler extends DefaultHandler {
|
|||||||
String localName = !StringUtil.isEmpty(pLocalName)
|
String localName = !StringUtil.isEmpty(pLocalName)
|
||||||
? pLocalName : getLocalName(pQualifiedName);
|
? pLocalName : getLocalName(pQualifiedName);
|
||||||
/*
|
/*
|
||||||
if (namespacePrefix.equals(mNamespacePrefix)) {
|
if (namespacePrefix.equals(namespacePrefix)) {
|
||||||
System.out.println("startElement:\nnamespaceURI=" + pNamespaceURI
|
System.out.println("startElement:\nnamespaceURI=" + pNamespaceURI
|
||||||
+ " namespacePrefix=" + namespacePrefix
|
+ " namespacePrefix=" + namespacePrefix
|
||||||
+ " localName=" + localName
|
+ " localName=" + localName
|
||||||
@@ -82,48 +81,48 @@ public class NestingHandler extends DefaultHandler {
|
|||||||
+ " attributes=" + pAttributes);
|
+ " attributes=" + pAttributes);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (localName.equals(mIncludeTagName)) {
|
if (localName.equals(includeTagName)) {
|
||||||
// include
|
// include
|
||||||
//System.out.println("<" + mNamespacePrefix + ":"
|
//System.out.println("<" + namespacePrefix + ":"
|
||||||
// + mIncludeTagName + ">");
|
// + includeTagName + ">");
|
||||||
if (mInIncludeTag) {
|
if (inIncludeTag) {
|
||||||
mValidator.reportError("Cannot nest " + namespacePrefix + ":"
|
validator.reportError("Cannot nest " + namespacePrefix + ":"
|
||||||
+ mIncludeTagName);
|
+ includeTagName);
|
||||||
}
|
}
|
||||||
mInIncludeTag = true;
|
inIncludeTag = true;
|
||||||
}
|
}
|
||||||
else if (localName.equals(mParamTagName)) {
|
else if (localName.equals(paramTagName)) {
|
||||||
// param
|
// param
|
||||||
//System.out.println("<" + mNamespacePrefix + ":"
|
//System.out.println("<" + namespacePrefix + ":"
|
||||||
// + mParamTagName + "/>");
|
// + paramTagName + "/>");
|
||||||
if (!mInIncludeTag) {
|
if (!inIncludeTag) {
|
||||||
mValidator.reportError(mNamespacePrefix + ":"
|
validator.reportError(this.namespacePrefix + ":"
|
||||||
+ mParamTagName
|
+ paramTagName
|
||||||
+ " can only appear within "
|
+ " can only appear within "
|
||||||
+ mNamespacePrefix + ":"
|
+ this.namespacePrefix + ":"
|
||||||
+ mIncludeTagName);
|
+ includeTagName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (localName.equals(mOpenParamTagName)) {
|
else if (localName.equals(openParamTagName)) {
|
||||||
// oparam
|
// oparam
|
||||||
//System.out.println("<" + mNamespacePrefix + ":"
|
//System.out.println("<" + namespacePrefix + ":"
|
||||||
// + mOpenParamTagName + ">");
|
// + openParamTagName + ">");
|
||||||
if (!mInIncludeTag) {
|
if (!inIncludeTag) {
|
||||||
mValidator.reportError(mNamespacePrefix + ":"
|
validator.reportError(this.namespacePrefix + ":"
|
||||||
+ mOpenParamTagName
|
+ openParamTagName
|
||||||
+ " can only appear within "
|
+ " can only appear within "
|
||||||
+ mNamespacePrefix + ":"
|
+ this.namespacePrefix + ":"
|
||||||
+ mIncludeTagName);
|
+ includeTagName);
|
||||||
}
|
}
|
||||||
mInIncludeTag = false;
|
inIncludeTag = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Only jsp:text allowed inside include!
|
// Only jsp:text allowed inside include!
|
||||||
if (mInIncludeTag && !localName.equals("text")) {
|
if (inIncludeTag && !localName.equals("text")) {
|
||||||
mValidator.reportError(namespacePrefix + ":" + localName
|
validator.reportError(namespacePrefix + ":" + localName
|
||||||
+ " can not appear within "
|
+ " can not appear within "
|
||||||
+ mNamespacePrefix + ":"
|
+ this.namespacePrefix + ":"
|
||||||
+ mIncludeTagName);
|
+ includeTagName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,28 +138,28 @@ public class NestingHandler extends DefaultHandler {
|
|||||||
String localName = !StringUtil.isEmpty(pLocalName)
|
String localName = !StringUtil.isEmpty(pLocalName)
|
||||||
? pLocalName : getLocalName(pQualifiedName);
|
? pLocalName : getLocalName(pQualifiedName);
|
||||||
/*
|
/*
|
||||||
if (namespacePrefix.equals(mNamespacePrefix)) {
|
if (namespacePrefix.equals(namespacePrefix)) {
|
||||||
System.out.println("endElement:\nnamespaceURI=" + pNamespaceURI
|
System.out.println("endElement:\nnamespaceURI=" + pNamespaceURI
|
||||||
+ " namespacePrefix=" + namespacePrefix
|
+ " namespacePrefix=" + namespacePrefix
|
||||||
+ " localName=" + localName
|
+ " localName=" + localName
|
||||||
+ " qName=" + pQualifiedName);
|
+ " qName=" + pQualifiedName);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (namespacePrefix.equals(mNamespacePrefix)
|
if (namespacePrefix.equals(this.namespacePrefix)
|
||||||
&& localName.equals(mIncludeTagName)) {
|
&& localName.equals(includeTagName)) {
|
||||||
|
|
||||||
//System.out.println("</" + mNamespacePrefix + ":"
|
//System.out.println("</" + namespacePrefix + ":"
|
||||||
// + mIncludeTagName + ">");
|
// + includeTagName + ">");
|
||||||
|
|
||||||
mInIncludeTag = false;
|
inIncludeTag = false;
|
||||||
}
|
}
|
||||||
else if (namespacePrefix.equals(mNamespacePrefix)
|
else if (namespacePrefix.equals(this.namespacePrefix)
|
||||||
&& localName.equals(mOpenParamTagName)) {
|
&& localName.equals(openParamTagName)) {
|
||||||
|
|
||||||
//System.out.println("</" + mNamespacePrefix + ":"
|
//System.out.println("</" + namespacePrefix + ":"
|
||||||
// + mOpenParamTagName + ">");
|
// + openParamTagName + ">");
|
||||||
|
|
||||||
mInIncludeTag = true; // assuming no errors before this...
|
inIncludeTag = true; // assuming no errors before this...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,8 +168,8 @@ public class NestingHandler extends DefaultHandler {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private String getNSPrefixFromURI(String pNamespaceURI) {
|
private String getNSPrefixFromURI(String pNamespaceURI) {
|
||||||
return (pNamespaceURI.equals(mNamespaceURI)
|
return (pNamespaceURI.equals(namespaceURI)
|
||||||
? mNamespacePrefix : "");
|
? namespacePrefix : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getNamespacePrefix(String pQualifiedName) {
|
private String getNamespacePrefix(String pQualifiedName) {
|
||||||
|
|||||||
+12
-18
@@ -20,16 +20,16 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet.jsp.droplet.taglib;
|
package com.twelvemonkeys.servlet.jsp.droplet.taglib;
|
||||||
|
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
import java.util.*;
|
import javax.servlet.jsp.tagext.PageData;
|
||||||
|
import javax.servlet.jsp.tagext.TagLibraryValidator;
|
||||||
import javax.servlet.jsp.tagext.*;
|
import javax.servlet.jsp.tagext.ValidationMessage;
|
||||||
import javax.xml.parsers.*;
|
import javax.xml.parsers.SAXParser;
|
||||||
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
import org.xml.sax.*;
|
import java.util.ArrayList;
|
||||||
import org.xml.sax.helpers.*;
|
import java.util.List;
|
||||||
|
|
||||||
import com.twelvemonkeys.util.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A validator that verifies that tags follow
|
* A validator that verifies that tags follow
|
||||||
@@ -47,18 +47,14 @@ import com.twelvemonkeys.util.*;
|
|||||||
* @version $Revision: #1 $, ($Date: 2008/05/05 $)
|
* @version $Revision: #1 $, ($Date: 2008/05/05 $)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class NestingValidator extends TagLibraryValidator {
|
public class NestingValidator extends TagLibraryValidator {
|
||||||
|
|
||||||
private Vector errors = new Vector();
|
private List<ValidationMessage> errors = new ArrayList<ValidationMessage>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
public ValidationMessage[] validate(String pPrefix, String pURI, PageData pPage) {
|
||||||
public ValidationMessage[] validate(String pPrefix,
|
|
||||||
String pURI,
|
|
||||||
PageData pPage) {
|
|
||||||
|
|
||||||
//System.out.println("Validating " + pPrefix + " (" + pURI + ") for "
|
//System.out.println("Validating " + pPrefix + " (" + pURI + ") for "
|
||||||
// + pPage + ".");
|
// + pPage + ".");
|
||||||
@@ -88,14 +84,12 @@ public class NestingValidator extends TagLibraryValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return any errors and exceptions, empty array means okay
|
// Return any errors and exceptions, empty array means okay
|
||||||
return (ValidationMessage[])
|
return errors.toArray(new ValidationMessage[errors.size()]);
|
||||||
errors.toArray(new ValidationMessage[errors.size()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback method for the handler to report errors
|
* Callback method for the handler to report errors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void reportError(String pMessage) {
|
public void reportError(String pMessage) {
|
||||||
// The first argument to the ValidationMessage
|
// The first argument to the ValidationMessage
|
||||||
// constructor can be a tag ID. Since tag IDs
|
// constructor can be a tag ID. Since tag IDs
|
||||||
|
|||||||
@@ -32,55 +32,49 @@ import javax.servlet.jsp.tagext.Tag;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open parameter tag that emulates ATG Dynamo JHTML behaviour for JSP.
|
* Open parameter tag that emulates ATG Dynamo JHTML behaviour for JSP.
|
||||||
*
|
*
|
||||||
* @author Thomas Purcell (CSC Australia)
|
* @author Thomas Purcell (CSC Australia)
|
||||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||||
* @author last modified by $Author: haku $
|
* @author last modified by $Author: haku $
|
||||||
*
|
|
||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/OparamTag.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/OparamTag.java#1 $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class OparamTag extends BodyReaderTag {
|
public class OparamTag extends BodyReaderTag {
|
||||||
|
|
||||||
protected final static String COUNTER = "com.twelvemonkeys.servlet.jsp.taglib.OparamTag.counter";
|
protected final static String COUNTER = "com.twelvemonkeys.servlet.jsp.taglib.OparamTag.counter";
|
||||||
|
|
||||||
|
private File subpage = null;
|
||||||
private File mSubpage = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the name of the parameter to be inserted into the {@code
|
* This is the name of the parameter to be inserted into the {@code
|
||||||
* PageContext.REQUEST_SCOPE} scope.
|
* PageContext.REQUEST_SCOPE} scope.
|
||||||
*/
|
*/
|
||||||
|
private String parameterName = null;
|
||||||
|
|
||||||
private String mParameterName = null;
|
private String language = null;
|
||||||
|
|
||||||
private String mLanguage = null;
|
private String prefix = null;
|
||||||
|
|
||||||
private String mPrefix = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method allows the JSP page to set the name for the parameter by
|
* This method allows the JSP page to set the name for the parameter by
|
||||||
* using the {@code name} tag attribute.
|
* using the {@code name} tag attribute.
|
||||||
*
|
*
|
||||||
* @param pName The name for the parameter to insert into the {@code
|
* @param pName The name for the parameter to insert into the {@code
|
||||||
* PageContext.REQUEST_SCOPE} scope.
|
* PageContext.REQUEST_SCOPE} scope.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setName(String pName) {
|
public void setName(String pName) {
|
||||||
mParameterName = pName;
|
parameterName = pName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLanguage(String pLanguage) {
|
public void setLanguage(String pLanguage) {
|
||||||
//System.out.println("setLanguage:"+pLanguage);
|
//System.out.println("setLanguage:"+pLanguage);
|
||||||
mLanguage = pLanguage;
|
language = pLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrefix(String pPrefix) {
|
public void setPrefix(String pPrefix) {
|
||||||
//System.out.println("setPrefix:"+pPrefix);
|
//System.out.println("setPrefix:"+pPrefix);
|
||||||
mPrefix = pPrefix;
|
prefix = pPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,11 +83,11 @@ public class OparamTag extends BodyReaderTag {
|
|||||||
* {@code IncludeTag} then a {@code JspException} is thrown.
|
* {@code IncludeTag} then a {@code JspException} is thrown.
|
||||||
*
|
*
|
||||||
* @return If this tag is enclosed within an {@code IncludeTag}, then
|
* @return If this tag is enclosed within an {@code IncludeTag}, then
|
||||||
* the default return value from this method is the {@code
|
* the default return value from this method is the {@code
|
||||||
* TagSupport.EVAL_BODY_TAG} value.
|
* TagSupport.EVAL_BODY_TAG} value.
|
||||||
* @exception JspException
|
*
|
||||||
|
* @throws JspException
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public int doStartTag() throws JspException {
|
public int doStartTag() throws JspException {
|
||||||
//checkEnclosedInIncludeTag(); // Moved to TagLibValidator
|
//checkEnclosedInIncludeTag(); // Moved to TagLibValidator
|
||||||
|
|
||||||
@@ -101,17 +95,17 @@ public class OparamTag extends BodyReaderTag {
|
|||||||
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
|
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
|
||||||
|
|
||||||
// Get filename
|
// Get filename
|
||||||
mSubpage = createFileNameFromRequest(request);
|
subpage = createFileNameFromRequest(request);
|
||||||
|
|
||||||
// Get include tag, and add to parameters
|
// Get include tag, and add to parameters
|
||||||
IncludeTag includeTag = (IncludeTag) getParent();
|
IncludeTag includeTag = (IncludeTag) getParent();
|
||||||
includeTag.addParameter(mParameterName, new Oparam(mSubpage.getName()));
|
includeTag.addParameter(parameterName, new Oparam(subpage.getName()));
|
||||||
|
|
||||||
// if ! subpage.exist || jsp newer than subpage, write new
|
// if ! subpage.exist || jsp newer than subpage, write new
|
||||||
File jsp = new File(pageContext.getServletContext()
|
File jsp = new File(pageContext.getServletContext()
|
||||||
.getRealPath(request.getServletPath()));
|
.getRealPath(request.getServletPath()));
|
||||||
|
|
||||||
if (!mSubpage.exists() || jsp.lastModified() > mSubpage.lastModified()) {
|
if (!subpage.exists() || jsp.lastModified() > subpage.lastModified()) {
|
||||||
return BodyTag.EVAL_BODY_BUFFERED;
|
return BodyTag.EVAL_BODY_BUFFERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,9 +142,8 @@ public class OparamTag extends BodyReaderTag {
|
|||||||
* life cycle just in case a JspException was thrown during the tag
|
* life cycle just in case a JspException was thrown during the tag
|
||||||
* execution.
|
* execution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected void clearServiceState() {
|
protected void clearServiceState() {
|
||||||
mParameterName = null;
|
parameterName = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -160,36 +153,31 @@ public class OparamTag extends BodyReaderTag {
|
|||||||
* into the session scope then a {@code JspException} will be thrown.
|
* into the session scope then a {@code JspException} will be thrown.
|
||||||
*
|
*
|
||||||
* @param pContent The body of the tag as a String.
|
* @param pContent The body of the tag as a String.
|
||||||
*
|
* @throws JspException
|
||||||
* @exception JspException
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected void processBody(String pContent) throws JspException {
|
protected void processBody(String pContent) throws JspException {
|
||||||
// Okay, we have the content, we need to write it to disk somewhere
|
// Okay, we have the content, we need to write it to disk somewhere
|
||||||
String content = pContent;
|
String content = pContent;
|
||||||
|
|
||||||
if (!StringUtil.isEmpty(mLanguage)) {
|
if (!StringUtil.isEmpty(language)) {
|
||||||
content = "<%@page language=\"" + mLanguage + "\" %>" + content;
|
content = "<%@page language=\"" + language + "\" %>" + content;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StringUtil.isEmpty(mPrefix)) {
|
if (!StringUtil.isEmpty(prefix)) {
|
||||||
content = "<%@taglib uri=\"/twelvemonkeys-common\" prefix=\"" + mPrefix + "\" %>" + content;
|
content = "<%@taglib uri=\"/twelvemonkeys-common\" prefix=\"" + prefix + "\" %>" + content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the content of the oparam to disk
|
// Write the content of the oparam to disk
|
||||||
try {
|
try {
|
||||||
log("Processing subpage " + mSubpage.getPath());
|
log("Processing subpage " + subpage.getPath());
|
||||||
FileUtil.write(mSubpage, content.getBytes());
|
FileUtil.write(subpage, content.getBytes());
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException ioe) {
|
catch (IOException ioe) {
|
||||||
throw new JspException(ioe);
|
throw new JspException(ioe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Creates a unique filename for each (nested) oparam */
|
||||||
* Creates a unique filename for each (nested) oparam
|
|
||||||
*/
|
|
||||||
private File createFileNameFromRequest(HttpServletRequest pRequest) {
|
private File createFileNameFromRequest(HttpServletRequest pRequest) {
|
||||||
//System.out.println("ServletPath" + pRequest.getServletPath());
|
//System.out.println("ServletPath" + pRequest.getServletPath());
|
||||||
String path = pRequest.getServletPath();
|
String path = pRequest.getServletPath();
|
||||||
@@ -203,7 +191,7 @@ public class OparamTag extends BodyReaderTag {
|
|||||||
|
|
||||||
// Replace special chars in name with '_'
|
// Replace special chars in name with '_'
|
||||||
name = name.replace('.', '_');
|
name = name.replace('.', '_');
|
||||||
String param = mParameterName.replace('.', '_');
|
String param = parameterName.replace('.', '_');
|
||||||
param = param.replace('/', '_');
|
param = param.replace('/', '_');
|
||||||
param = param.replace('\\', '_');
|
param = param.replace('\\', '_');
|
||||||
param = param.replace(':', '_');
|
param = param.replace(':', '_');
|
||||||
@@ -218,21 +206,20 @@ public class OparamTag extends BodyReaderTag {
|
|||||||
return new File(new File(pageContext.getServletContext().getRealPath(path)), name + "_oparam_" + count + "_" + param + ".jsp");
|
return new File(new File(pageContext.getServletContext().getRealPath(path)), name + "_oparam_" + count + "_" + param + ".jsp");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Gets the current oparam count for this request */
|
||||||
* Gets the current oparam count for this request
|
|
||||||
*/
|
|
||||||
private int getOparamCountFromRequest(HttpServletRequest pRequest) {
|
private int getOparamCountFromRequest(HttpServletRequest pRequest) {
|
||||||
// Use request.attribute for incrementing oparam counter
|
// Use request.attribute for incrementing oparam counter
|
||||||
Integer count = (Integer) pRequest.getAttribute(COUNTER);
|
Integer count = (Integer) pRequest.getAttribute(COUNTER);
|
||||||
if (count == null)
|
if (count == null) {
|
||||||
count = new Integer(0);
|
count = new Integer(0);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
count = new Integer(count.intValue() + 1);
|
count = new Integer(count.intValue() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
// ... and set it back
|
// ... and set it back
|
||||||
pRequest.setAttribute(COUNTER, count);
|
pRequest.setAttribute(COUNTER, count);
|
||||||
|
|
||||||
return count.intValue();
|
return count.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,10 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet.jsp.droplet.taglib;
|
package com.twelvemonkeys.servlet.jsp.droplet.taglib;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.twelvemonkeys.servlet.jsp.droplet.Param;
|
||||||
|
import com.twelvemonkeys.servlet.jsp.taglib.ExTagSupport;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.*;
|
|
||||||
import javax.servlet.jsp.tagext.*;
|
|
||||||
|
|
||||||
import com.twelvemonkeys.servlet.jsp.droplet.*;
|
|
||||||
import com.twelvemonkeys.servlet.jsp.taglib.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameter tag that emulates ATG Dynamo JHTML behaviour for JSP.
|
* Parameter tag that emulates ATG Dynamo JHTML behaviour for JSP.
|
||||||
@@ -33,22 +29,19 @@ import com.twelvemonkeys.servlet.jsp.taglib.*;
|
|||||||
* @version $Revision: #1 $, ($Date: 2008/05/05 $)
|
* @version $Revision: #1 $, ($Date: 2008/05/05 $)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ParamTag extends ExTagSupport {
|
public class ParamTag extends ExTagSupport {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the name of the parameter to be inserted into the {@code
|
* This is the name of the parameter to be inserted into the {@code
|
||||||
* PageContext.REQUEST_SCOPE} scope.
|
* PageContext.REQUEST_SCOPE} scope.
|
||||||
*/
|
*/
|
||||||
|
private String parameterName;
|
||||||
private String mParameterName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the value for the parameter to be inserted into the {@code
|
* This is the value for the parameter to be inserted into the {@code
|
||||||
* PageContext.REQUEST_SCOPE} scope.
|
* PageContext.REQUEST_SCOPE} scope.
|
||||||
*/
|
*/
|
||||||
|
private Object parameterValue;
|
||||||
private Object mParameterValue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method allows the JSP page to set the name for the parameter by
|
* This method allows the JSP page to set the name for the parameter by
|
||||||
@@ -57,9 +50,8 @@ public class ParamTag extends ExTagSupport {
|
|||||||
* @param pName The name for the parameter to insert into the {@code
|
* @param pName The name for the parameter to insert into the {@code
|
||||||
* PageContext.REQUEST_SCOPE} scope.
|
* PageContext.REQUEST_SCOPE} scope.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setName(String pName) {
|
public void setName(String pName) {
|
||||||
mParameterName = pName;
|
parameterName = pName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,9 +61,8 @@ public class ParamTag extends ExTagSupport {
|
|||||||
* @param pValue The value for the parameter to insert into the <code>
|
* @param pValue The value for the parameter to insert into the <code>
|
||||||
* PageContext.REQUEST_SCOPE</page> scope.
|
* PageContext.REQUEST_SCOPE</page> scope.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setValue(String pValue) {
|
public void setValue(String pValue) {
|
||||||
mParameterValue = new Param(pValue);
|
parameterValue = new Param(pValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +75,6 @@ public class ParamTag extends ExTagSupport {
|
|||||||
* TagSupport.SKIP_BODY} value.
|
* TagSupport.SKIP_BODY} value.
|
||||||
* @exception JspException
|
* @exception JspException
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public int doStartTag() throws JspException {
|
public int doStartTag() throws JspException {
|
||||||
//checkEnclosedInIncludeTag();
|
//checkEnclosedInIncludeTag();
|
||||||
|
|
||||||
@@ -118,11 +108,10 @@ public class ParamTag extends ExTagSupport {
|
|||||||
* This method adds the parameter whose name and value were passed to this
|
* This method adds the parameter whose name and value were passed to this
|
||||||
* object via the tag attributes to the parent {@code Include} tag.
|
* object via the tag attributes to the parent {@code Include} tag.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void addParameter() {
|
private void addParameter() {
|
||||||
IncludeTag includeTag = (IncludeTag) getParent();
|
IncludeTag includeTag = (IncludeTag) getParent();
|
||||||
|
|
||||||
includeTag.addParameter(mParameterName, mParameterValue);
|
includeTag.addParameter(parameterName, parameterValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,9 +122,8 @@ public class ParamTag extends ExTagSupport {
|
|||||||
* life cycle just in case a JspException was thrown during the tag
|
* life cycle just in case a JspException was thrown during the tag
|
||||||
* execution.
|
* execution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected void clearServiceState() {
|
protected void clearServiceState() {
|
||||||
mParameterName = null;
|
parameterName = null;
|
||||||
mParameterValue = null;
|
parameterValue = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ public class ValueOfTEI extends TagExtraInfo {
|
|||||||
Object nameAttr = pTagData.getAttribute("name");
|
Object nameAttr = pTagData.getAttribute("name");
|
||||||
Object paramAttr = pTagData.getAttribute("param");
|
Object paramAttr = pTagData.getAttribute("param");
|
||||||
|
|
||||||
if ((nameAttr != null && paramAttr == null) ||
|
if ((nameAttr != null && paramAttr == null) || (nameAttr == null && paramAttr != null)) {
|
||||||
(nameAttr == null && paramAttr != null)) {
|
|
||||||
return true; // Exactly one of name or param set
|
return true; // Exactly one of name or param set
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-19
@@ -14,13 +14,14 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet.jsp.droplet.taglib;
|
package com.twelvemonkeys.servlet.jsp.droplet.taglib;
|
||||||
|
|
||||||
import java.io.*;
|
import com.twelvemonkeys.servlet.jsp.droplet.JspFragment;
|
||||||
|
import com.twelvemonkeys.servlet.jsp.taglib.ExTagSupport;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.jsp.*;
|
import javax.servlet.jsp.JspException;
|
||||||
|
import javax.servlet.jsp.JspWriter;
|
||||||
import com.twelvemonkeys.servlet.jsp.droplet.*;
|
import javax.servlet.jsp.PageContext;
|
||||||
import com.twelvemonkeys.servlet.jsp.taglib.*;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ValueOf tag that emulates ATG Dynamo JHTML behaviour for JSP.
|
* ValueOf tag that emulates ATG Dynamo JHTML behaviour for JSP.
|
||||||
@@ -38,14 +39,14 @@ public class ValueOfTag extends ExTagSupport {
|
|||||||
* the current JSP page. This value will be set via the {@code name}
|
* the current JSP page. This value will be set via the {@code name}
|
||||||
* attribute.
|
* attribute.
|
||||||
*/
|
*/
|
||||||
private String mParameterName;
|
private String parameterName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the value of the parameter read from the {@code
|
* This is the value of the parameter read from the {@code
|
||||||
* PageContext.REQUEST_SCOPE} scope. If the parameter doesn't exist,
|
* PageContext.REQUEST_SCOPE} scope. If the parameter doesn't exist,
|
||||||
* then this will be null.
|
* then this will be null.
|
||||||
*/
|
*/
|
||||||
private Object mParameterValue;
|
private Object parameterValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called as part of the initialisation phase of the tag
|
* This method is called as part of the initialisation phase of the tag
|
||||||
@@ -56,7 +57,7 @@ public class ValueOfTag extends ExTagSupport {
|
|||||||
* PageContext.REQUEST_SCOPE} scope.
|
* PageContext.REQUEST_SCOPE} scope.
|
||||||
*/
|
*/
|
||||||
public void setName(String pName) {
|
public void setName(String pName) {
|
||||||
mParameterName = pName;
|
parameterName = pName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,7 +70,7 @@ public class ValueOfTag extends ExTagSupport {
|
|||||||
* PageContext.REQUEST_SCOPE} scope.
|
* PageContext.REQUEST_SCOPE} scope.
|
||||||
*/
|
*/
|
||||||
public void setParam(String pName) {
|
public void setParam(String pName) {
|
||||||
mParameterName = pName;
|
parameterName = pName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,19 +89,19 @@ public class ValueOfTag extends ExTagSupport {
|
|||||||
public int doStartTag() throws JspException {
|
public int doStartTag() throws JspException {
|
||||||
try {
|
try {
|
||||||
if (parameterExists()) {
|
if (parameterExists()) {
|
||||||
if (mParameterValue instanceof JspFragment) {
|
if (parameterValue instanceof JspFragment) {
|
||||||
// OPARAM or PARAM
|
// OPARAM or PARAM
|
||||||
((JspFragment) mParameterValue).service(pageContext);
|
((JspFragment) parameterValue).service(pageContext);
|
||||||
/*
|
/*
|
||||||
log("Service subpage " + pageContext.getServletContext().getRealPath(((Oparam) mParameterValue).getName()));
|
log("Service subpage " + pageContext.getServletContext().getRealPath(((Oparam) parameterValue).getName()));
|
||||||
|
|
||||||
pageContext.include(((Oparam) mParameterValue).getName());
|
pageContext.include(((Oparam) parameterValue).getName());
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Normal JSP parameter value
|
// Normal JSP parameter value
|
||||||
JspWriter writer = pageContext.getOut();
|
JspWriter writer = pageContext.getOut();
|
||||||
writer.print(mParameterValue);
|
writer.print(parameterValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SKIP_BODY;
|
return SKIP_BODY;
|
||||||
@@ -135,13 +136,13 @@ public class ValueOfTag extends ExTagSupport {
|
|||||||
* } scope, {@code false} otherwise.
|
* } scope, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
private boolean parameterExists() {
|
private boolean parameterExists() {
|
||||||
mParameterValue = pageContext.getAttribute(mParameterName, PageContext.REQUEST_SCOPE);
|
parameterValue = pageContext.getAttribute(parameterName, PageContext.REQUEST_SCOPE);
|
||||||
|
|
||||||
// -- Harald K 20020726
|
// -- Harald K 20020726
|
||||||
if (mParameterValue == null) {
|
if (parameterValue == null) {
|
||||||
mParameterValue = pageContext.getRequest().getParameter(mParameterName);
|
parameterValue = pageContext.getRequest().getParameter(parameterName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (mParameterValue != null);
|
return (parameterValue != null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import javax.servlet.jsp.JspException;
|
|||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class BodyReaderTag extends ExBodyTagSupport {
|
public abstract class BodyReaderTag extends ExBodyTagSupport {
|
||||||
/**
|
/**
|
||||||
* This is the method called by the JSP engine when the body for a tag
|
* This is the method called by the JSP engine when the body for a tag
|
||||||
@@ -23,7 +22,6 @@ public abstract class BodyReaderTag extends ExBodyTagSupport {
|
|||||||
* processed the one time.
|
* processed the one time.
|
||||||
* @exception JspException
|
* @exception JspException
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public int doAfterBody() throws JspException {
|
public int doAfterBody() throws JspException {
|
||||||
processBody(bodyContent.getString());
|
processBody(bodyContent.getString());
|
||||||
return SKIP_BODY;
|
return SKIP_BODY;
|
||||||
@@ -36,8 +34,7 @@ public abstract class BodyReaderTag extends ExBodyTagSupport {
|
|||||||
* this method is called.
|
* this method is called.
|
||||||
*
|
*
|
||||||
* @param pContent The body for the custom tag converted to a String.
|
* @param pContent The body for the custom tag converted to a String.
|
||||||
* @exception JscException
|
* @exception JspException
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected abstract void processBody(String pContent) throws JspException;
|
protected abstract void processBody(String pContent) throws JspException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,16 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet.jsp.taglib;
|
package com.twelvemonkeys.servlet.jsp.taglib;
|
||||||
|
|
||||||
import java.util.*;
|
import javax.servlet.jsp.JspException;
|
||||||
import java.io.*;
|
import javax.servlet.jsp.JspWriter;
|
||||||
|
import javax.servlet.jsp.tagext.BodyContent;
|
||||||
import javax.servlet.jsp.*;
|
import java.io.BufferedReader;
|
||||||
import javax.servlet.jsp.tagext.*;
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a table from a string of "comma-separated values" (CSV).
|
* Creates a table from a string of "comma-separated values" (CSV).
|
||||||
@@ -67,29 +72,27 @@ import javax.servlet.jsp.tagext.*;
|
|||||||
*
|
*
|
||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/CSVToTableTag.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/CSVToTableTag.java#1 $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class CSVToTableTag extends ExBodyTagSupport {
|
public class CSVToTableTag extends ExBodyTagSupport {
|
||||||
|
|
||||||
public final static String TAB = "\t";
|
public final static String TAB = "\t";
|
||||||
|
|
||||||
protected String mDelimiter = null;
|
protected String delimiter = null;
|
||||||
protected boolean mFirstRowIsHeader = false;
|
protected boolean firstRowIsHeader = false;
|
||||||
protected boolean mFirstColIsHeader = false;
|
protected boolean firstColIsHeader = false;
|
||||||
|
|
||||||
public void setDelimiter(String pDelimiter) {
|
public void setDelimiter(String pDelimiter) {
|
||||||
mDelimiter = pDelimiter;
|
delimiter = pDelimiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDelimiter() {
|
public String getDelimiter() {
|
||||||
return mDelimiter != null ? mDelimiter : TAB;
|
return delimiter != null ? delimiter : TAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFirstRowIsHeader(String pBoolean) {
|
public void setFirstRowIsHeader(String pBoolean) {
|
||||||
mFirstRowIsHeader = Boolean.valueOf(pBoolean).booleanValue();
|
firstRowIsHeader = Boolean.valueOf(pBoolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFirstColIsHeader(String pBoolean) {
|
public void setFirstColIsHeader(String pBoolean) {
|
||||||
mFirstColIsHeader = Boolean.valueOf(pBoolean).booleanValue();
|
firstColIsHeader = Boolean.valueOf(pBoolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -114,14 +117,11 @@ public class CSVToTableTag extends ExBodyTagSupport {
|
|||||||
// Loop over cells in each row
|
// Loop over cells in each row
|
||||||
for (int col = 0; col < table.getCols(); col++) {
|
for (int col = 0; col < table.getCols(); col++) {
|
||||||
// Test if we are using headers, else normal cell
|
// Test if we are using headers, else normal cell
|
||||||
if (mFirstRowIsHeader && row == 0
|
if (firstRowIsHeader && row == 0 || firstColIsHeader && col == 0) {
|
||||||
|| mFirstColIsHeader && col == 0) {
|
out.println("<TH>" + table.get(row, col) + " </TH>");
|
||||||
out.println("<TH>" + table.get(row, col)
|
|
||||||
+ " </TH>");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
out.println("<TD>" + table.get(row, col)
|
out.println("<TD>" + table.get(row, col) + " </TD>");
|
||||||
+ " </TD>");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,29 +139,29 @@ public class CSVToTableTag extends ExBodyTagSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class Table {
|
static class Table {
|
||||||
List mRows = null;
|
List rows = null;
|
||||||
int mCols = 0;
|
int cols = 0;
|
||||||
|
|
||||||
private Table(List pRows, int pCols) {
|
private Table(List pRows, int pCols) {
|
||||||
mRows = pRows;
|
rows = pRows;
|
||||||
mCols = pCols;
|
cols = pCols;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getRows() {
|
int getRows() {
|
||||||
return mRows != null ? mRows.size() : 0;
|
return rows != null ? rows.size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getCols() {
|
int getCols() {
|
||||||
return mCols;
|
return cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
List getTableRows() {
|
List getTableRows() {
|
||||||
return mRows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
List getTableRow(int pRow) {
|
List getTableRow(int pRow) {
|
||||||
return mRows != null
|
return rows != null
|
||||||
? (List) mRows.get(pRow)
|
? (List) rows.get(pRow)
|
||||||
: Collections.EMPTY_LIST;
|
: Collections.EMPTY_LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,25 +175,22 @@ public class CSVToTableTag extends ExBodyTagSupport {
|
|||||||
* Parses a BodyContent to a table.
|
* Parses a BodyContent to a table.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
static Table parseContent(Reader pContent, String pDelim) throws IOException {
|
||||||
static Table parseContent(Reader pContent, String pDelim)
|
List<List<String>> tableRows = new ArrayList<List<String>>();
|
||||||
throws IOException {
|
|
||||||
ArrayList tableRows = new ArrayList();
|
|
||||||
int tdsPerTR = 0;
|
int tdsPerTR = 0;
|
||||||
|
|
||||||
// Loop through TRs
|
// Loop through TRs
|
||||||
BufferedReader reader = new BufferedReader(pContent);
|
BufferedReader reader = new BufferedReader(pContent);
|
||||||
String tr = null;
|
String tr;
|
||||||
while ((tr = reader.readLine()) != null) {
|
while ((tr = reader.readLine()) != null) {
|
||||||
// Discard blank lines
|
// Discard blank lines
|
||||||
if (tr != null
|
if (tr.trim().length() <= 0 && tr.indexOf(pDelim) < 0) {
|
||||||
&& tr.trim().length() <= 0 && tr.indexOf(pDelim) < 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//System.out.println("CSVToTable: read LINE=\"" + tr + "\"");
|
//System.out.println("CSVToTable: read LINE=\"" + tr + "\"");
|
||||||
|
|
||||||
ArrayList tableDatas = new ArrayList();
|
List<String> tableDatas = new ArrayList<String>();
|
||||||
StringTokenizer tableRow = new StringTokenizer(tr, pDelim,
|
StringTokenizer tableRow = new StringTokenizer(tr, pDelim,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
@@ -235,6 +232,4 @@ public class CSVToTableTag extends ExBodyTagSupport {
|
|||||||
return new Table(tableRows, tdsPerTR);
|
return new Table(tableRows, tdsPerTR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,49 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet.jsp.taglib;
|
package com.twelvemonkeys.servlet.jsp.taglib;
|
||||||
|
|
||||||
|
import com.twelvemonkeys.util.convert.Converter;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.jsp.JspException;
|
||||||
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
import javax.servlet.jsp.tagext.TagSupport;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import javax.servlet.http.*;
|
|
||||||
import javax.servlet.jsp.*;
|
|
||||||
import javax.servlet.jsp.tagext.*;
|
|
||||||
|
|
||||||
import com.twelvemonkeys.util.convert.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints the last modified
|
* Prints the last modified
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class LastModifiedTag extends TagSupport {
|
public class LastModifiedTag extends TagSupport {
|
||||||
private String mFileName = null;
|
private String fileName = null;
|
||||||
private String mFormat = null;
|
private String format = null;
|
||||||
|
|
||||||
public void setFile(String pFileName) {
|
public void setFile(String pFileName) {
|
||||||
mFileName = pFileName;
|
fileName = pFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFormat(String pFormat) {
|
public void setFormat(String pFormat) {
|
||||||
mFormat = pFormat;
|
format = pFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int doStartTag() throws JspException {
|
public int doStartTag() throws JspException {
|
||||||
File file = null;
|
File file;
|
||||||
|
|
||||||
if (mFileName != null) {
|
if (fileName != null) {
|
||||||
file = new File(pageContext.getServletContext()
|
file = new File(pageContext.getServletContext().getRealPath(fileName));
|
||||||
.getRealPath(mFileName));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
HttpServletRequest request =
|
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
|
||||||
(HttpServletRequest) pageContext.getRequest();
|
|
||||||
|
|
||||||
// Get the file containing the servlet
|
// Get the file containing the servlet
|
||||||
file = new File(pageContext.getServletContext()
|
file = new File(pageContext.getServletContext().getRealPath(request.getServletPath()));
|
||||||
.getRealPath(request.getServletPath()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Date lastModified = new Date(file.lastModified());
|
Date lastModified = new Date(file.lastModified());
|
||||||
Converter conv = Converter.getInstance();
|
Converter conv = Converter.getInstance();
|
||||||
|
|
||||||
// Set the last modified value back
|
// Set the last modified value back
|
||||||
pageContext.setAttribute("lastModified",
|
pageContext.setAttribute("lastModified", conv.toString(lastModified, format));
|
||||||
conv.toString(lastModified, mFormat));
|
|
||||||
|
|
||||||
return Tag.EVAL_BODY_INCLUDE;
|
return Tag.EVAL_BODY_INCLUDE;
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-10
@@ -23,8 +23,6 @@
|
|||||||
package com.twelvemonkeys.servlet.jsp.taglib.logic;
|
package com.twelvemonkeys.servlet.jsp.taglib.logic;
|
||||||
|
|
||||||
|
|
||||||
import java.lang.*;
|
|
||||||
|
|
||||||
import javax.servlet.jsp.JspException;
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.TagSupport;
|
import javax.servlet.jsp.tagext.TagSupport;
|
||||||
|
|
||||||
@@ -38,8 +36,8 @@ import javax.servlet.jsp.tagext.TagSupport;
|
|||||||
public abstract class ConditionalTagBase extends TagSupport {
|
public abstract class ConditionalTagBase extends TagSupport {
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
protected String mObjectName;
|
protected String objectName;
|
||||||
protected String mObjectValue;
|
protected String objectValue;
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
|
|
||||||
@@ -51,7 +49,7 @@ public abstract class ConditionalTagBase extends TagSupport {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return mObjectName;
|
return objectName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,7 +60,7 @@ public abstract class ConditionalTagBase extends TagSupport {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void setName(String pObjectName) {
|
public void setName(String pObjectName) {
|
||||||
this.mObjectName = pObjectName;
|
this.objectName = pObjectName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,7 +71,7 @@ public abstract class ConditionalTagBase extends TagSupport {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return mObjectValue;
|
return objectValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +82,7 @@ public abstract class ConditionalTagBase extends TagSupport {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void setValue(String pObjectValue) {
|
public void setValue(String pObjectValue) {
|
||||||
this.mObjectValue = pObjectValue;
|
this.objectValue = pObjectValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,8 +118,8 @@ public abstract class ConditionalTagBase extends TagSupport {
|
|||||||
public void release() {
|
public void release() {
|
||||||
|
|
||||||
super.release();
|
super.release();
|
||||||
mObjectName = null;
|
objectName = null;
|
||||||
mObjectValue = null;
|
objectValue = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,13 +8,11 @@
|
|||||||
package com.twelvemonkeys.servlet.jsp.taglib.logic;
|
package com.twelvemonkeys.servlet.jsp.taglib.logic;
|
||||||
|
|
||||||
|
|
||||||
import java.lang.*;
|
import com.twelvemonkeys.lang.StringUtil;
|
||||||
|
|
||||||
import javax.servlet.http.Cookie;
|
import javax.servlet.http.Cookie;
|
||||||
import javax.servlet.jsp.JspException;
|
import javax.servlet.jsp.JspException;
|
||||||
|
|
||||||
import com.twelvemonkeys.lang.StringUtil;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -134,15 +132,15 @@ public class EqualTag extends ConditionalTagBase {
|
|||||||
*/
|
*/
|
||||||
protected boolean condition() throws JspException {
|
protected boolean condition() throws JspException {
|
||||||
|
|
||||||
if (StringUtil.isEmpty(mObjectName)) {
|
if (StringUtil.isEmpty(objectName)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtil.isEmpty(mObjectValue)) {
|
if (StringUtil.isEmpty(objectValue)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object pageScopedAttribute = pageContext.getAttribute(mObjectName);
|
Object pageScopedAttribute = pageContext.getAttribute(objectName);
|
||||||
if (pageScopedAttribute == null) {
|
if (pageScopedAttribute == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -164,7 +162,7 @@ public class EqualTag extends ConditionalTagBase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (pageScopedStringAttribute.equals(mObjectValue));
|
return (pageScopedStringAttribute.equals(objectValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.servlet.jsp.taglib.logic;
|
package com.twelvemonkeys.servlet.jsp.taglib.logic;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import javax.servlet.jsp.JspException;
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.*;
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
import javax.servlet.jsp.tagext.TagSupport;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for adding iterators to a page.
|
* Abstract base class for adding iterators to a page.
|
||||||
@@ -24,7 +24,7 @@ public abstract class IteratorProviderTag extends TagSupport {
|
|||||||
public final static String ATTRIBUTE_TYPE = "type";
|
public final static String ATTRIBUTE_TYPE = "type";
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
private String mType = null;
|
private String type = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type.
|
* Gets the type.
|
||||||
@@ -32,7 +32,7 @@ public abstract class IteratorProviderTag extends TagSupport {
|
|||||||
* @return the type (class name)
|
* @return the type (class name)
|
||||||
*/
|
*/
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return mType;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +42,7 @@ public abstract class IteratorProviderTag extends TagSupport {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public void setType(String pType) {
|
public void setType(String pType) {
|
||||||
mType = pType;
|
type = pType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -132,15 +132,15 @@ public class NotEqualTag extends ConditionalTagBase {
|
|||||||
*/
|
*/
|
||||||
protected boolean condition() throws JspException {
|
protected boolean condition() throws JspException {
|
||||||
|
|
||||||
if (StringUtil.isEmpty(mObjectName)) {
|
if (StringUtil.isEmpty(objectName)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtil.isEmpty(mObjectValue)) {
|
if (StringUtil.isEmpty(objectValue)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object pageScopedAttribute = pageContext.getAttribute(mObjectName);
|
Object pageScopedAttribute = pageContext.getAttribute(objectName);
|
||||||
if (pageScopedAttribute == null) {
|
if (pageScopedAttribute == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -162,7 +162,7 @@ public class NotEqualTag extends ConditionalTagBase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (!(pageScopedStringAttribute.equals(mObjectValue)));
|
return (!(pageScopedStringAttribute.equals(objectValue)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,15 +57,15 @@ final class Log4JContextWrapper implements ServletContext {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ServletContext mContext;
|
private final ServletContext context;
|
||||||
|
|
||||||
private final Logger mLogger;
|
private final Logger logger;
|
||||||
|
|
||||||
Log4JContextWrapper(ServletContext pContext) {
|
Log4JContextWrapper(ServletContext pContext) {
|
||||||
mContext = pContext;
|
context = pContext;
|
||||||
|
|
||||||
// TODO: We want a logger per servlet, not per servlet context, right?
|
// TODO: We want a logger per servlet, not per servlet context, right?
|
||||||
mLogger = Logger.getLogger(pContext.getServletContextName());
|
logger = Logger.getLogger(pContext.getServletContextName());
|
||||||
|
|
||||||
// TODO: Automatic init/config of Log4J using context parameter for log4j.xml?
|
// TODO: Automatic init/config of Log4J using context parameter for log4j.xml?
|
||||||
// See Log4JInit.java
|
// See Log4JInit.java
|
||||||
@@ -85,99 +85,99 @@ final class Log4JContextWrapper implements ServletContext {
|
|||||||
// Should be possible using some stack peek hack, but that's slow...
|
// Should be possible using some stack peek hack, but that's slow...
|
||||||
// Find a good way...
|
// Find a good way...
|
||||||
// Maybe just pass it into the constuctor, and have one wrapper per servlet
|
// Maybe just pass it into the constuctor, and have one wrapper per servlet
|
||||||
mLogger.info(pMessage);
|
logger.info(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void log(String pMessage, Throwable pCause) {
|
public void log(String pMessage, Throwable pCause) {
|
||||||
// TODO: Get logger for caller..
|
// TODO: Get logger for caller..
|
||||||
|
|
||||||
mLogger.error(pMessage, pCause);
|
logger.error(pMessage, pCause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getAttribute(String pMessage) {
|
public Object getAttribute(String pMessage) {
|
||||||
return mContext.getAttribute(pMessage);
|
return context.getAttribute(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumeration getAttributeNames() {
|
public Enumeration getAttributeNames() {
|
||||||
return mContext.getAttributeNames();
|
return context.getAttributeNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServletContext getContext(String pMessage) {
|
public ServletContext getContext(String pMessage) {
|
||||||
return mContext.getContext(pMessage);
|
return context.getContext(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getInitParameter(String pMessage) {
|
public String getInitParameter(String pMessage) {
|
||||||
return mContext.getInitParameter(pMessage);
|
return context.getInitParameter(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumeration getInitParameterNames() {
|
public Enumeration getInitParameterNames() {
|
||||||
return mContext.getInitParameterNames();
|
return context.getInitParameterNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMajorVersion() {
|
public int getMajorVersion() {
|
||||||
return mContext.getMajorVersion();
|
return context.getMajorVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMimeType(String pMessage) {
|
public String getMimeType(String pMessage) {
|
||||||
return mContext.getMimeType(pMessage);
|
return context.getMimeType(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinorVersion() {
|
public int getMinorVersion() {
|
||||||
return mContext.getMinorVersion();
|
return context.getMinorVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestDispatcher getNamedDispatcher(String pMessage) {
|
public RequestDispatcher getNamedDispatcher(String pMessage) {
|
||||||
return mContext.getNamedDispatcher(pMessage);
|
return context.getNamedDispatcher(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealPath(String pMessage) {
|
public String getRealPath(String pMessage) {
|
||||||
return mContext.getRealPath(pMessage);
|
return context.getRealPath(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestDispatcher getRequestDispatcher(String pMessage) {
|
public RequestDispatcher getRequestDispatcher(String pMessage) {
|
||||||
return mContext.getRequestDispatcher(pMessage);
|
return context.getRequestDispatcher(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public URL getResource(String pMessage) throws MalformedURLException {
|
public URL getResource(String pMessage) throws MalformedURLException {
|
||||||
return mContext.getResource(pMessage);
|
return context.getResource(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getResourceAsStream(String pMessage) {
|
public InputStream getResourceAsStream(String pMessage) {
|
||||||
return mContext.getResourceAsStream(pMessage);
|
return context.getResourceAsStream(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set getResourcePaths(String pMessage) {
|
public Set getResourcePaths(String pMessage) {
|
||||||
return mContext.getResourcePaths(pMessage);
|
return context.getResourcePaths(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServerInfo() {
|
public String getServerInfo() {
|
||||||
return mContext.getServerInfo();
|
return context.getServerInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Servlet getServlet(String pMessage) throws ServletException {
|
public Servlet getServlet(String pMessage) throws ServletException {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
return mContext.getServlet(pMessage);
|
return context.getServlet(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServletContextName() {
|
public String getServletContextName() {
|
||||||
return mContext.getServletContextName();
|
return context.getServletContextName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumeration getServletNames() {
|
public Enumeration getServletNames() {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
return mContext.getServletNames();
|
return context.getServletNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumeration getServlets() {
|
public Enumeration getServlets() {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
return mContext.getServlets();
|
return context.getServlets();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAttribute(String pMessage) {
|
public void removeAttribute(String pMessage) {
|
||||||
mContext.removeAttribute(pMessage);
|
context.removeAttribute(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAttribute(String pMessage, Object pExtension) {
|
public void setAttribute(String pMessage, Object pExtension) {
|
||||||
mContext.setAttribute(pMessage, pExtension);
|
context.setAttribute(pMessage, pExtension);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package com.twelvemonkeys.servlet;
|
package com.twelvemonkeys.servlet;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GenericFilterTestCase
|
* GenericFilterTestCase
|
||||||
@@ -30,12 +29,12 @@ public final class GenericFilterTestCase extends FilterAbstractTestCase {
|
|||||||
fail(e.getMessage());
|
fail(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
assertFalse("OncePerRequest should default to false", filter.mOncePerRequest);
|
assertFalse("OncePerRequest should default to false", filter.oncePerRequest);
|
||||||
filter.destroy();
|
filter.destroy();
|
||||||
|
|
||||||
// TRUE
|
// TRUE
|
||||||
filter = new GenericFilterImpl();
|
filter = new GenericFilterImpl();
|
||||||
Map params = new HashMap();
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
params.put("once-per-request", "true");
|
params.put("once-per-request", "true");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -45,12 +44,12 @@ public final class GenericFilterTestCase extends FilterAbstractTestCase {
|
|||||||
fail(e.getMessage());
|
fail(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue("oncePerRequest should be true", filter.mOncePerRequest);
|
assertTrue("oncePerRequest should be true", filter.oncePerRequest);
|
||||||
filter.destroy();
|
filter.destroy();
|
||||||
|
|
||||||
// TRUE
|
// TRUE
|
||||||
filter = new GenericFilterImpl();
|
filter = new GenericFilterImpl();
|
||||||
params = new HashMap();
|
params = new HashMap<String, String>();
|
||||||
params.put("oncePerRequest", "true");
|
params.put("oncePerRequest", "true");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -60,7 +59,7 @@ public final class GenericFilterTestCase extends FilterAbstractTestCase {
|
|||||||
fail(e.getMessage());
|
fail(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue("oncePerRequest should be true", filter.mOncePerRequest);
|
assertTrue("oncePerRequest should be true", filter.oncePerRequest);
|
||||||
filter.destroy();
|
filter.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -35,7 +35,7 @@ public abstract class ServletConfigMapAdapterTestCase extends MapAbstractTestCas
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class TestConfig implements ServletConfig, FilterConfig, ServletContext, Serializable, Cloneable {
|
private static class TestConfig implements ServletConfig, FilterConfig, ServletContext, Serializable, Cloneable {
|
||||||
Map mMap = new HashMap();
|
Map map = new HashMap();
|
||||||
|
|
||||||
public String getServletName() {
|
public String getServletName() {
|
||||||
return "dummy"; // Not needed for this test
|
return "dummy"; // Not needed for this test
|
||||||
@@ -55,12 +55,12 @@ public abstract class ServletConfigMapAdapterTestCase extends MapAbstractTestCas
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getInitParameter(String s) {
|
public String getInitParameter(String s) {
|
||||||
return (String) mMap.get(s);
|
return (String) map.get(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumeration getInitParameterNames() {
|
public Enumeration getInitParameterNames() {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return Collections.enumeration(mMap.keySet());
|
return Collections.enumeration(map.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServletContext getContext(String uripath) {
|
public ServletContext getContext(String uripath) {
|
||||||
@@ -157,7 +157,7 @@ public abstract class ServletConfigMapAdapterTestCase extends MapAbstractTestCas
|
|||||||
|
|
||||||
public Map makeFullMap() {
|
public Map makeFullMap() {
|
||||||
ServletConfig config = new TestConfig();
|
ServletConfig config = new TestConfig();
|
||||||
addSampleMappings(((TestConfig) config).mMap);
|
addSampleMappings(((TestConfig) config).map);
|
||||||
return new ServletConfigMapAdapter(config);
|
return new ServletConfigMapAdapter(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ public abstract class ServletConfigMapAdapterTestCase extends MapAbstractTestCas
|
|||||||
|
|
||||||
public Map makeFullMap() {
|
public Map makeFullMap() {
|
||||||
FilterConfig config = new TestConfig();
|
FilterConfig config = new TestConfig();
|
||||||
addSampleMappings(((TestConfig) config).mMap);
|
addSampleMappings(((TestConfig) config).map);
|
||||||
return new ServletConfigMapAdapter(config);
|
return new ServletConfigMapAdapter(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ public abstract class ServletConfigMapAdapterTestCase extends MapAbstractTestCas
|
|||||||
|
|
||||||
public Map makeFullMap() {
|
public Map makeFullMap() {
|
||||||
FilterConfig config = new TestConfig();
|
FilterConfig config = new TestConfig();
|
||||||
addSampleMappings(((TestConfig) config).mMap);
|
addSampleMappings(((TestConfig) config).map);
|
||||||
return new ServletConfigMapAdapter(config);
|
return new ServletConfigMapAdapter(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user