Subversion Repositories general

Compare Revisions

No changes between revisions

Ignore whitespace Rev 959 → Rev 960

/backpath/trunk/tld/ak-backpath.tld
0,0 → 1,535
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>backpath</shortname>
<uri>http://26th.net/backpath</uri>
 
<tag>
<name>backlink</name>
<tagclass>ak.backpath.taglib.BackwardLinkTag</tagclass>
<attribute>
<name>accesskey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>anchor</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>indexId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>linkName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onblur</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onclick</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>ondblclick</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onfocus</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeydown</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeypress</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeyup</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmousedown</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmousemove</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseout</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseover</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseup</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>property</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>scope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>style</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleClass</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>tabindex</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>target</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>title</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>link</name>
<tagclass>ak.backpath.taglib.ForwardLinkTag</tagclass>
<attribute>
<name>accesskey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>action</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>anchor</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>forward</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>href</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>indexed</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>indexId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>linkName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onblur</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onclick</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>ondblclick</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onfocus</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeydown</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeypress</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeyup</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmousedown</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmousemove</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseout</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseover</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseup</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>page</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramProperty</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramScope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>property</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>scope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>style</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleClass</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>tabindex</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>target</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>title</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>titleKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>transaction</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>empty</name>
<tagclass>ak.backpath.taglib.EmptyTag</tagclass>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>notEmpty</name>
<tagclass>ak.backpath.taglib.NotEmptyTag</tagclass>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>current</name>
<tagclass>ak.backpath.taglib.CurrentTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>forward</name>
<tagclass>ak.backpath.taglib.ForwardTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>forwardStack</name>
<tagclass>ak.backpath.taglib.ForwardStackTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>currentStack</name>
<tagclass>ak.backpath.taglib.CurrentStackTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>backwardStack</name>
<tagclass>ak.backpath.taglib.BackwardStackTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
/backpath/trunk/lib/commons-logging.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/backpath/trunk/lib/struts-1.1.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/backpath/trunk/lib/servlet.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/backpath/trunk/src/ak/backpath/BackPath.java
0,0 → 1,394
package ak.backpath;
 
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Iterator;
import java.util.Map;
import java.util.ArrayList;
import java.util.Set;
import java.util.TreeSet;
import java.util.Collections;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
import java.net.URL;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
public class BackPath
{
private static Log log = LogFactory.getLog(BackPath.class);
 
public static final String DEFAULT_KEY = BackPath.class.getName();
public static final String DEFAULT_PARAM = "backpath";
public static final String OUT_CHARSET = "UTF-8";
public static final String URL_CHARSET = "UTF-8";
public static final String IGNORES_DELIMITER = "\\s*;\\s*";
public static final boolean DEFAULT_ZIP = true;
public static final String[] METHODS_TO_SAVE_PARAMS = {"GET"};
public static final char URL_PARAM_START = '?';
public static final char URL_PARAM_SEPARATOR = '&';
public static final char URL_PARAM_VALUE = '=';
public static final char URL_PARAM_VALUE_SEP = ',';
 
protected static final byte URL_DELIMITER = 0;
protected static final int BUFFER_SIZE = 1024;
protected static final int INIT_STREAM_SIZE_COEF = 100;
protected static final String URL_PARAM_START_STR = "" + URL_PARAM_START;
 
protected static Set methodsToSaveParams;
 
// List(String)
protected List stack = new ArrayList();
protected String param = DEFAULT_PARAM;
protected String[] ignoreParams = null;
 
/** zip the stack */
protected boolean zip = DEFAULT_ZIP;
 
// string cache
protected String forwardParams;
protected boolean forwardParamsFormed = false;
protected String currentParams;
protected boolean currentParamsFormed = false;
protected String backwardParams;
protected boolean backwardParamsFormed = false;
protected String backwardUrl;
protected boolean backwardUrlFormed = false;
 
static {
methodsToSaveParams = Collections.unmodifiableSet(
new TreeSet(Arrays.asList(METHODS_TO_SAVE_PARAMS)));
}
 
protected static Deflater deflater = new Deflater();
protected static Inflater inflater = new Inflater();
 
public static BackPath findBackPath(HttpServletRequest request)
throws Exception
{
return findBackPath(request, DEFAULT_KEY, DEFAULT_PARAM, (String)null, DEFAULT_ZIP);
}
 
public static BackPath findBackPath(HttpServletRequest request, String backPathKey,
String backPathParam, String backPathIgnore, boolean zip)
throws Exception
{
Object backPathObj = request.getAttribute(backPathKey);
 
if(backPathObj == null) {
BackPath backPath;
String[] ignores = null;
 
if(backPathIgnore != null)
ignores = backPathIgnore.trim().split(IGNORES_DELIMITER);
 
backPath = new BackPath(request, backPathParam, ignores, zip);
request.setAttribute(backPathKey, backPath);
return backPath;
}
else if(backPathObj instanceof BackPath) {
return (BackPath)backPathObj;
}
else {
throw new Exception("An object under key " + backPathKey
+ " is not a " + BackPath.class.getName());
}
}
 
public BackPath(HttpServletRequest request, String param, String[] ignoreParams, boolean zip)
{
this.zip = zip;
this.param = param;
this.ignoreParams = ignoreParams;
init(request);
}
 
public boolean getZip()
{
return zip;
}
 
public void setZip(boolean zip)
{
this.zip = zip;
resetCachedStrings();
}
 
public String getParam()
{
return param;
}
 
public void setParam(String param)
{
this.param = param;
resetCachedStrings();
}
 
public String[] getIgnoreParams()
{
return ignoreParams;
}
 
public void setIgnoreParams(String[] ignoreParams)
{
this.ignoreParams = ignoreParams;
resetCachedStrings();
}
 
public boolean getHasBack()
{
return (stack.size() > 1);
}
 
// List(String)
public List getStack()
{
return Collections.unmodifiableList(stack);
}
 
public String getForwardParams()
{
if(!forwardParamsFormed) {
forwardParams = formForwardParams();
forwardParamsFormed = true;
}
 
return forwardParams;
}
 
protected String formForwardParams()
{
try {
return encode(stack, zip, 0);
}
catch(IOException ex) {
log.error("Cannot form forward params", ex);
return null;
}
}
 
public String getBackwardParams()
{
if(!backwardParamsFormed) {
backwardParams = formBackwardParams();
backwardParamsFormed = true;
}
 
return backwardParams;
}
 
protected String formBackwardParams()
{
try {
if(stack.size() <= 2)
return null;
else
return encode(stack, zip, 2);
}
catch(IOException ex) {
log.error("Cannot form backward params", ex);
return null;
}
}
 
public String getBackwardUrl()
{
if(!backwardParamsFormed) {
backwardUrl = formBackwardUrl();
backwardUrlFormed = true;
}
 
return backwardUrl;
}
 
protected String formBackwardUrl()
{
if(stack.size() < 2) return null;
 
try {
StringBuffer url = new StringBuffer((String)stack.get(stack.size()-2));
if(stack.size() > 2) {
String s = encode(stack, zip, 2);
if(url.indexOf(URL_PARAM_START_STR) >= 0) url.append(URL_PARAM_SEPARATOR);
else url.append(URL_PARAM_START);
url.append(param).append(URL_PARAM_VALUE).append(s);
}
 
return url.toString();
}
catch(IOException ex) {
log.error("Cannot form backward url", ex);
return null;
}
}
 
public String getCurrentParams()
{
if(!currentParamsFormed) {
currentParams = formCurrentParams();
currentParamsFormed = true;
}
 
return currentParams;
}
 
protected String formCurrentParams()
{
try {
if(stack.size() <= 1)
return null;
else
return encode(stack, zip, 1);
}
catch(IOException ex) {
log.error("Cannot form current params", ex);
return null;
}
}
 
public void init(HttpServletRequest request)
{
try {
resetCachedStrings();
// get old
decode(stack, request.getParameter(param), zip);
 
// add new
String url = (new URL(request.getRequestURL().toString())).getPath();
if(methodsToSaveParams.contains(request.getMethod())) {
// to ignore
Set ignore = new TreeSet();
if(ignoreParams != null) {
for(int i = 0; i < ignoreParams.length; i++)
ignore.add(ignoreParams[i]);
}
ignore.add(param);
 
// form query string
StringBuffer query = new StringBuffer();
Map requestParams = request.getParameterMap();
for(Iterator i = requestParams.keySet().iterator(); i.hasNext(); ) {
String name = (String)i.next();
if(ignore.contains(name)) continue;
if(query.length() == 0)
query.append(URL_PARAM_START);
else
query.append(URL_PARAM_SEPARATOR);
 
query.append(URLEncoder.encode(name, URL_CHARSET));
query.append(URL_PARAM_VALUE);
String[] values = (String[])requestParams.get(name);
for(int j = 0; j < values.length; j++) {
if(j > 0) query.append(URL_PARAM_VALUE_SEP);
query.append(URLEncoder.encode(values[j], URL_CHARSET));
}
}
 
// form url
if(query.length() > 0) url = query.insert(0, url).toString();
}
stack.add(url);
}
catch(IOException ex) {
log.error("Cannot init", ex);
}
}
 
/**
* @param stack List(String)
*/
protected String encode(List stack, boolean zip, int suffix)
throws IOException
{
ByteArrayOutputStream buf = new ByteArrayOutputStream(stack.size()*INIT_STREAM_SIZE_COEF);
Object lock = (zip ? (Object)BackPath.class : this);
 
synchronized(lock) {
OutputStream out;
if(zip) {
deflater.reset();
out = new DeflaterOutputStream(new Base64.OutputStream(buf), deflater);
}
else {
out = new Base64.OutputStream(buf);
}
 
for(int i = 0; i < stack.size()-suffix; i++) {
String s = (String)stack.get(i);
if(i > 0) out.write(URL_DELIMITER);
out.write(s.getBytes(URL_CHARSET));
}
out.close();
}
 
return buf.toString(OUT_CHARSET);
}
 
/**
* @param stack List(String)
*/
protected void decode(List stack, String path, boolean zip)
throws IOException
{
stack.clear();
if(path == null || path.equals("")) return;
 
ByteArrayOutputStream dec = new ByteArrayOutputStream(stack.size()*INIT_STREAM_SIZE_COEF);
Object lock = (zip ? (Object)BackPath.class : this);
 
synchronized(lock) {
ByteArrayInputStream enc = new ByteArrayInputStream(path.getBytes(OUT_CHARSET));
 
InputStream in;
if(zip) {
inflater.reset();
in = new InflaterInputStream(new Base64.InputStream(enc), inflater);
}
else {
in = new Base64.InputStream(enc);
}
 
byte[] tmp = new byte[BUFFER_SIZE];
int l;
while((l = in.read(tmp, 0, tmp.length)) > 0) {
dec.write(tmp, 0, l);
}
}
 
try {
byte[] buf = dec.toByteArray();
for(int start = 0, end = 0; end <= buf.length; end++) {
if(end == buf.length || buf[end] == URL_DELIMITER) {
stack.add(new String(buf, start, end-start, URL_CHARSET));
start = end+1;
}
}
}
catch(Exception ex) { // if some mistake in stack, then ignore it completely
stack.clear();
log.info("Cannot parse stack", ex);
}
}
 
protected void resetCachedStrings()
{
forwardParams = null;
forwardParamsFormed = false;
currentParams = null;
currentParamsFormed = false;
backwardParams = null;
backwardParamsFormed = false;
backwardUrl = null;
backwardUrlFormed = false;
}
}
/backpath/trunk/src/ak/backpath/test/BackPathTest.java
0,0 → 1,87
package ak.backpath.test;
 
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import ak.backpath.BackPath;
 
public class BackPathTest
{
 
public static void main(String[] args)
throws Exception
{
int n = 50000;
int m = 1;
 
TestThread[] threads = new TestThread[m];
 
for(int i = 0; i < threads.length; i++) {
threads[i] = new TestThread(n);
}
 
long t1 = System.currentTimeMillis();
for(int i = 0; i < threads.length; i++) {
threads[i].start();
}
for(int i = 0; i < threads.length; i++) {
threads[i].join();
}
long t2 = System.currentTimeMillis();
 
System.out.println(m + " threads * " + n + " iterations = " + (t2-t1) + " ms");
System.out.println((((long)m*n*1000)/(t2-t1)) + " requests/s");
}
 
private static class TestThread extends Thread
{
private int n;
 
public TestThread(int n)
{
this.n = n;
}
 
public void run() {
try {
Map params = new java.util.HashMap();
DummyRequest request;
BackPath backPath;
String pathString;
 
// index
params.clear();
request = new DummyRequest("http://localhost/testapp/index.do", params);
backPath = BackPath.findBackPath(request);
pathString = backPath.getForwardParams();
backPath.getBackwardUrl();
 
// list
params.clear();
params.put("backpath", new String[] { pathString });
params.put("show", new String[] { "true" });
request = new DummyRequest("http://localhost/testapp/some/list.do?show=true", params);
backPath = BackPath.findBackPath(request);
pathString = backPath.getForwardParams();
backPath.getBackwardUrl();
 
// details
params.clear();
params.put("backpath", new String[] { pathString });
params.put("id", new String[] { "123" });
params.put("show", new String[] { "true" });
request = new DummyRequest("http://localhost/testapp/some/details.do?id=123&show=true", params);
 
for(int i = 0; i < n; i++) {
request.clearAttributes();
backPath = BackPath.findBackPath(request);
backPath.getCurrentParams();
backPath.getForwardParams();
backPath.getBackwardUrl();
}
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
/backpath/trunk/src/ak/backpath/test/DummyRequest.java
0,0 → 1,294
package ak.backpath.test;
 
import javax.servlet.http.HttpServletRequest;
 
class DummyRequest implements HttpServletRequest
{
private StringBuffer url;
private java.util.Map params;
private java.util.Map attrs = new java.util.HashMap();
 
public DummyRequest(String url, java.util.Map params)
{
this.url = new StringBuffer(url);
this.params = params;
}
 
public void clearAttributes()
{
attrs.clear();
}
 
public Object getAttribute(String name)
{
return attrs.get(name);
}
 
public java.util.Enumeration getAttributeNames()
{
return null;
}
 
public String getCharacterEncoding()
{
return null;
}
 
public int getContentLength()
{
return 0;
}
 
public String getContentType()
{
return null;
}
 
public javax.servlet.ServletInputStream getInputStream()
{
return null;
}
 
public java.util.Locale getLocale()
{
return null;
}
 
public java.util.Enumeration getLocales()
{
return null;
}
 
public String getLocalAddr()
{
return null;
}
 
public String getLocalName()
{
return null;
}
 
public int getLocalPort()
{
return 0;
}
 
public String getParameter(String name)
{
String[] v = (String[])params.get(name);
 
if(v == null)
return null;
else
return v[0];
}
 
public java.util.Map getParameterMap()
{
return params;
}
 
public java.util.Enumeration getParameterNames()
{
return null;
}
 
public String[] getParameterValues(String name)
{
return null;
}
 
public String getProtocol()
{
return null;
}
 
public java.io.BufferedReader getReader()
{
return null;
}
 
public String getRealPath(String path)
{
return null;
}
 
public String getRemoteAddr()
{
return null;
}
 
public String getRemoteHost()
{
return null;
}
 
public int getRemotePort()
{
return 0;
}
 
public javax.servlet.RequestDispatcher getRequestDispatcher(String path)
{
return null;
}
 
public String getScheme()
{
return null;
}
 
public String getServerName()
{
return null;
}
 
public int getServerPort()
{
return 0;
}
 
public boolean isSecure()
{
return false;
}
 
public void removeAttribute(String name)
{
}
 
public void setAttribute(String name, Object o)
{
attrs.put(name, o);
}
 
public void setCharacterEncoding(String env)
{
}
 
public String getAuthType()
{
return null;
}
 
public String getContextPath()
{
return null;
}
 
public javax.servlet.http.Cookie[] getCookies()
{
return null;
}
 
public long getDateHeader(String name)
{
return 0;
}
 
public String getHeader(String name)
{
return null;
}
 
public java.util.Enumeration getHeaderNames()
{
return null;
}
 
public java.util.Enumeration getHeaders(String name)
{
return null;
}
 
public int getIntHeader(String name)
{
return 0;
}
 
public String getMethod()
{
return "GET";
}
 
public String getPathInfo()
{
return null;
}
 
public String getPathTranslated()
{
return null;
}
 
public String getQueryString()
{
return null;
}
 
public String getRemoteUser()
{
return null;
}
 
public String getRequestedSessionId()
{
return null;
}
 
public String getRequestURI()
{
return null;
}
 
public StringBuffer getRequestURL()
{
return url;
}
 
public String getServletPath()
{
return null;
}
 
public javax.servlet.http.HttpSession getSession()
{
return null;
}
 
public javax.servlet.http.HttpSession getSession(boolean create)
{
return null;
}
 
public java.security.Principal getUserPrincipal()
{
return null;
}
 
public boolean isRequestedSessionIdFromCookie()
{
return false;
}
 
public boolean isRequestedSessionIdFromUrl()
{
return false;
}
 
public boolean isRequestedSessionIdFromURL()
{
return false;
}
 
public boolean isRequestedSessionIdValid()
{
return false;
}
 
public boolean isUserInRole(String role)
{
return false;
}
}
/backpath/trunk/src/ak/backpath/taglib/CurrentStackTag.java
0,0 → 1,14
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.struts.util.ResponseUtils;
import ak.backpath.BackPath;
 
public class CurrentStackTag extends StackTagBase
{
protected String getStack() throws JspException
{
return findBackPath().getCurrentParams();
}
}
/backpath/trunk/src/ak/backpath/taglib/LinkTagBase.java
0,0 → 1,72
package ak.backpath.taglib;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import org.apache.struts.taglib.html.LinkTag;
import ak.backpath.BackPath;
 
public abstract class LinkTagBase extends LinkTag
{
protected String backPathKey = BackPath.DEFAULT_KEY;
 
public String getBackPathKey()
{
return this.backPathKey;
}
 
public void setBackPathKey(String backPathKey)
{
this.backPathKey = backPathKey;
}
 
protected String backPathParam = BackPath.DEFAULT_PARAM;
 
public String getBackPathParam()
{
return this.backPathParam;
}
 
public void setBackPathParam(String backPathParam)
{
this.backPathParam = backPathParam;
}
 
protected String backPathIgnore = null;
 
public String getBackPathIgnore()
{
return this.backPathIgnore;
}
 
public void setBackPathIgnore(String backPathIgnore)
{
this.backPathIgnore = backPathIgnore;
}
 
protected boolean zip = BackPath.DEFAULT_ZIP;
 
public boolean getZip()
{
return this.zip;
}
 
public void setZip(boolean zip)
{
this.zip = zip;
}
 
public void release()
{
super.release();
backPathKey = BackPath.DEFAULT_KEY;
backPathParam = BackPath.DEFAULT_PARAM;
backPathIgnore = null;
zip = BackPath.DEFAULT_ZIP;
}
 
protected BackPath findBackPath() throws JspException
{
return TaglibUtils.findBackPath(pageContext, backPathKey,
backPathParam, backPathIgnore, zip);
}
}
/backpath/trunk/src/ak/backpath/taglib/EmptyTagBase.java
0,0 → 1,87
package ak.backpath.taglib;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import ak.backpath.BackPath;
 
public abstract class EmptyTagBase extends TagSupport
{
protected String backPathKey = BackPath.DEFAULT_KEY;
 
public String getBackPathKey()
{
return this.backPathKey;
}
 
public void setBackPathKey(String backPathKey)
{
this.backPathKey = backPathKey;
}
 
protected String backPathParam = BackPath.DEFAULT_PARAM;
 
public String getBackPathParam()
{
return this.backPathParam;
}
 
public void setBackPathParam(String backPathParam)
{
this.backPathParam = backPathParam;
}
 
protected String backPathIgnore = null;
 
public String getBackPathIgnore()
{
return this.backPathIgnore;
}
 
public void setBackPathIgnore(String backPathIgnore)
{
this.backPathIgnore = backPathIgnore;
}
 
protected boolean zip = BackPath.DEFAULT_ZIP;
 
public boolean getZip()
{
return this.zip;
}
 
public void setZip(boolean zip)
{
this.zip = zip;
}
 
public void release()
{
super.release();
backPathKey = BackPath.DEFAULT_KEY;
backPathParam = BackPath.DEFAULT_PARAM;
backPathIgnore = null;
zip = BackPath.DEFAULT_ZIP;
}
 
public int doStartTag() throws JspException
{
if (condition())
return (EVAL_BODY_INCLUDE);
else
return (SKIP_BODY);
}
 
public int doEndTag() throws JspException
{
return (EVAL_PAGE);
}
 
protected abstract boolean condition() throws JspException;
 
protected BackPath findBackPath() throws JspException
{
return TaglibUtils.findBackPath(pageContext, backPathKey,
backPathParam, backPathIgnore, zip);
}
}
/backpath/trunk/src/ak/backpath/taglib/ForwardStackTag.java
0,0 → 1,14
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.struts.util.ResponseUtils;
import ak.backpath.BackPath;
 
public class ForwardStackTag extends StackTagBase
{
protected String getStack() throws JspException
{
return findBackPath().getForwardParams();
}
}
/backpath/trunk/src/ak/backpath/taglib/BackwardLinkTag.java
0,0 → 1,14
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
import ak.backpath.BackPath;
 
public class BackwardLinkTag extends LinkTagBase
{
protected String calculateURL() throws JspException
{
String url = findBackPath().getBackwardUrl();
if(url == null) url = "/";
return url;
}
}
/backpath/trunk/src/ak/backpath/taglib/ak-backpath.tld
0,0 → 1,543
<?xml version="1.0" encoding="UTF-8"?>
 
 
 
 
 
 
 
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>backpath</shortname>
<uri>http://26th.net/backpath</uri>
 
<tag>
<name>backlink</name>
<tagclass>ak.backpath.taglib.BackwardLinkTag</tagclass>
<attribute>
<name>accesskey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>anchor</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>indexId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>linkName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onblur</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onclick</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>ondblclick</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onfocus</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeydown</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeypress</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeyup</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmousedown</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmousemove</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseout</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseover</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseup</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>property</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>scope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>style</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleClass</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>tabindex</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>target</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>title</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>link</name>
<tagclass>ak.backpath.taglib.ForwardLinkTag</tagclass>
<attribute>
<name>accesskey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>action</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>anchor</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>forward</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>href</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>indexed</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>indexId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>linkName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onblur</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onclick</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>ondblclick</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onfocus</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeydown</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeypress</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeyup</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmousedown</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmousemove</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseout</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseover</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseup</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>page</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramProperty</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramScope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>property</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>scope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>style</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleClass</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>tabindex</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>target</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>title</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>titleKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>transaction</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>empty</name>
<tagclass>ak.backpath.taglib.EmptyTag</tagclass>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>notEmpty</name>
<tagclass>ak.backpath.taglib.NotEmptyTag</tagclass>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>current</name>
<tagclass>ak.backpath.taglib.CurrentTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>forward</name>
<tagclass>ak.backpath.taglib.ForwardTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>forwardStack</name>
<tagclass>ak.backpath.taglib.ForwardStackTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>currentStack</name>
<tagclass>ak.backpath.taglib.CurrentStackTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>backwardStack</name>
<tagclass>ak.backpath.taglib.BackwardStackTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
 
/backpath/trunk/src/ak/backpath/taglib/EmptyTag.java
0,0 → 1,11
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
 
public class EmptyTag extends EmptyTagBase
{
protected boolean condition() throws JspException
{
return !findBackPath().getHasBack();
}
}
/backpath/trunk/src/ak/backpath/taglib/NotEmptyTag.java
0,0 → 1,11
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
 
public class NotEmptyTag extends EmptyTagBase
{
protected boolean condition() throws JspException
{
return findBackPath().getHasBack();
}
}
/backpath/trunk/src/ak/backpath/taglib/StackTagBase.java
0,0 → 1,82
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.struts.util.ResponseUtils;
import ak.backpath.BackPath;
 
public abstract class StackTagBase extends TagSupport
{
protected String backPathKey = BackPath.DEFAULT_KEY;
 
public String getBackPathKey()
{
return this.backPathKey;
}
 
public void setBackPathKey(String backPathKey)
{
this.backPathKey = backPathKey;
}
 
protected String backPathParam = BackPath.DEFAULT_PARAM;
 
public String getBackPathParam()
{
return this.backPathParam;
}
 
public void setBackPathParam(String backPathParam)
{
this.backPathParam = backPathParam;
}
 
protected String backPathIgnore = null;
 
public String getBackPathIgnore()
{
return this.backPathIgnore;
}
 
public void setBackPathIgnore(String backPathIgnore)
{
this.backPathIgnore = backPathIgnore;
}
 
protected boolean zip = BackPath.DEFAULT_ZIP;
 
public boolean getZip()
{
return this.zip;
}
 
public void setZip(boolean zip)
{
this.zip = zip;
}
 
public void release()
{
super.release();
backPathKey = BackPath.DEFAULT_KEY;
backPathParam = BackPath.DEFAULT_PARAM;
backPathIgnore = null;
zip = BackPath.DEFAULT_ZIP;
}
 
public int doStartTag() throws JspException
{
String stack = getStack();
if(stack == null) stack = "";
ResponseUtils.write(pageContext, stack);
return SKIP_BODY;
}
 
protected BackPath findBackPath() throws JspException
{
return TaglibUtils.findBackPath(pageContext, backPathKey,
backPathParam, backPathIgnore, zip);
}
 
protected abstract String getStack() throws JspException;
}
/backpath/trunk/src/ak/backpath/taglib/CurrentTag.java
0,0 → 1,17
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
import ak.backpath.BackPath;
 
public class CurrentTag extends HiddenTagBase
{
public int doStartTag() throws JspException
{
this.property = backPathParam;
this.value = TaglibUtils.findBackPath(pageContext, backPathKey,
backPathParam, backPathIgnore, zip).getCurrentParams();
if(this.value == null) this.value = "";
 
return super.doStartTag();
}
}
/backpath/trunk/src/ak/backpath/taglib/ForwardLinkTag.java
0,0 → 1,21
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
import ak.backpath.BackPath;
 
public class ForwardLinkTag extends LinkTagBase
{
protected String calculateURL() throws JspException
{
String url = super.calculateURL();
if(url == null) return null;
 
String params = findBackPath().getForwardParams();
if(params == null) return url;
 
if(url.indexOf("?") > 0)
return url + "&" + backPathParam + "=" + params;
else
return url + "?" + backPathParam + "=" + params;
}
}
/backpath/trunk/src/ak/backpath/taglib/BackwardStackTag.java
0,0 → 1,14
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.struts.util.ResponseUtils;
import ak.backpath.BackPath;
 
public class BackwardStackTag extends StackTagBase
{
protected String getStack() throws JspException
{
return findBackPath().getBackwardParams();
}
}
/backpath/trunk/src/ak/backpath/taglib/ForwardTag.java
0,0 → 1,17
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
import ak.backpath.BackPath;
 
public class ForwardTag extends HiddenTagBase
{
public int doStartTag() throws JspException
{
this.property = backPathParam;
this.value = TaglibUtils.findBackPath(pageContext, backPathKey,
backPathParam, backPathIgnore, zip).getForwardParams();
if(this.value == null) this.value = "";
 
return super.doStartTag();
}
}
/backpath/trunk/src/ak/backpath/taglib/HiddenTagBase.java
0,0 → 1,71
package ak.backpath.taglib;
 
import javax.servlet.jsp.JspException;
import org.apache.struts.taglib.html.BaseFieldTag;
import ak.backpath.BackPath;
 
public abstract class HiddenTagBase extends BaseFieldTag
{
protected String backPathKey = BackPath.DEFAULT_KEY;
 
public String getBackPathKey()
{
return this.backPathKey;
}
 
public void setBackPathKey(String backPathKey)
{
this.backPathKey = backPathKey;
}
 
protected String backPathParam = BackPath.DEFAULT_PARAM;
 
public String getBackPathParam()
{
return this.backPathParam;
}
 
public void setBackPathParam(String backPathParam)
{
this.backPathParam = backPathParam;
}
 
protected String backPathIgnore = null;
 
public String getBackPathIgnore()
{
return this.backPathIgnore;
}
 
public void setBackPathIgnore(String backPathIgnore)
{
this.backPathIgnore = backPathIgnore;
}
 
protected boolean zip = BackPath.DEFAULT_ZIP;
 
public boolean getZip()
{
return this.zip;
}
 
public void setZip(boolean zip)
{
this.zip = zip;
}
 
public HiddenTagBase()
{
super();
this.type = "hidden";
}
 
public void release()
{
super.release();
backPathKey = BackPath.DEFAULT_KEY;
backPathParam = BackPath.DEFAULT_PARAM;
backPathIgnore = null;
zip = BackPath.DEFAULT_ZIP;
}
}
/backpath/trunk/src/ak/backpath/taglib/TaglibUtils.java
0,0 → 1,23
package ak.backpath.taglib;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;
import ak.backpath.BackPath;
 
public abstract class TaglibUtils
{
public static BackPath findBackPath(PageContext pageContext, String backPathKey,
String backPathParam, String backPathIgnore, boolean zip)
throws JspException
{
try {
return BackPath.findBackPath((HttpServletRequest)pageContext.getRequest(),
backPathKey, backPathParam, backPathIgnore, zip);
}
catch(Exception ex) {
throw new JspException(ex);
}
}
}
/backpath/trunk/src/ak/backpath/Base64.java
0,0 → 1,243
package ak.backpath;
 
/**
* Special version for packpath (ak) -
* symbols +/ replaced with .* to produce correct URL-parts;
* no end padding, most methods are deleted.
*
* Original author Robert Harder (rob@iharder.net)
*/
class Base64
{
private final static byte[] ALPHABET =
{
(byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
(byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
(byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
(byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
(byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
(byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
(byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
(byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'.', (byte)'*'
};
 
/**
* Translates a Base64 value to either its 6-bit reconstruction value
* or a negative number indicating some other meaning.
**/
private final static byte[] DECODABET =
{
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,63,-9,-9,-9,62,-9,
52,53,54,55,56,57,58,59,60,61,-9,-9,-9,-9,-9,-9,
-9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,25,-9,-9,-9,-9,-9,
-9,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50,51,-9,-9,-9,-9,-9
};
 
private Base64(){}
 
private static byte[] encode3to4(byte[] destination, byte[] source, int numSigBytes)
{
// 1 2 3
// 01234567890123456789012345678901 Bit position
// --------000000001111111122222222 Array position from threeBytes
// --------| || || || | Six bit groups to index ALPHABET
// >>18 >>12 >> 6 >> 0 Right shift necessary
// 0x3f 0x3f 0x3f Additional AND
 
// Create buffer with zero-padding if there are only one or two
// significant bytes passed in the array.
// We have to shift left 24 in order to flush out the 1's that appear
// when Java treats a value as negative that is cast from a byte to an int.
int inBuff = ( numSigBytes > 0 ? ((source[ 0 ] << 24) >>> 8) : 0 )
| ( numSigBytes > 1 ? ((source[ 1 ] << 24) >>> 16) : 0 )
| ( numSigBytes > 2 ? ((source[ 2 ] << 24) >>> 24) : 0 );
 
switch( numSigBytes )
{
case 3:
destination[ 0 ] = ALPHABET[ (inBuff >>> 18) ];
destination[ 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
destination[ 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ];
destination[ 3 ] = ALPHABET[ (inBuff ) & 0x3f ];
return destination;
 
case 2:
destination[ 0 ] = ALPHABET[ (inBuff >>> 18) ];
destination[ 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
destination[ 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ];
return destination;
 
case 1:
destination[ 0 ] = ALPHABET[ (inBuff >>> 18) ];
destination[ 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
return destination;
 
default:
return destination;
}
}
 
private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset, int length )
{
// Example: Dk==
if( length == 2 )
{
int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 )
| ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 );
 
destination[ destOffset ] = (byte)( outBuff >>> 16 );
return 1;
}
 
// Example: DkL=
else if( length == 3 )
{
int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 )
| ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
| ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 );
 
destination[ destOffset ] = (byte)( outBuff >>> 16 );
destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 );
return 2;
}
 
// Example: DkLE
else
{
try{
int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 )
| ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
| ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6)
| ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) );
 
 
destination[ destOffset ] = (byte)( outBuff >> 16 );
destination[ destOffset + 1 ] = (byte)( outBuff >> 8 );
destination[ destOffset + 2 ] = (byte)( outBuff );
 
return 3;
}catch( Exception e){
return -1;
}
}
}
 
static class InputStream extends java.io.FilterInputStream
{
private int position = -1;
private byte[] buffer = new byte[ 3 ];
private byte[] b4 = new byte[4];
private int numSigBytes;
 
public InputStream( java.io.InputStream in)
{
super( in );
}
 
public int read() throws java.io.IOException
{
// Do we need to get data?
if( position < 0 )
{
int i = 0;
for( ; i < 4; i++ )
{
int b = in.read();
if( b < 0 ) break;
b4[i] = (byte)b;
}
 
if( i == 0 ) return -1;
 
numSigBytes = decode4to3( b4, 0, buffer, 0, i );
position = 0;
}
 
// Got data?
if( position >= 0 )
{
if( position >= numSigBytes )
return -1;
 
int b = buffer[ position++ ];
 
if( position >= 3 )
position = -1;
 
return b & 0xFF;
}
else
{
throw new java.io.IOException( "Error in Base64 code reading stream." );
}
}
 
public int read( byte[] dest, int off, int len ) throws java.io.IOException
{
int i;
int b;
for( i = 0; i < len; i++ )
{
b = read();
 
if( b >= 0 )
dest[off + i] = (byte)b;
else if( i == 0 )
return -1;
else
break;
}
return i;
}
 
}
 
static class OutputStream extends java.io.FilterOutputStream
{
private int position = 0;
private byte[] buffer = new byte[ 3 ];
private byte[] b4 = new byte[4];
 
public OutputStream( java.io.OutputStream out)
{
super( out );
}
 
public void write(int theByte) throws java.io.IOException
{
buffer[ position++ ] = (byte)theByte;
if( position >= 3 ) // Enough to encode.
{
out.write( encode3to4( b4, buffer, 3 ) );
position = 0;
}
}
 
public void write( byte[] theBytes, int off, int len ) throws java.io.IOException
{
for( int i = 0; i < len; i++ )
{
write( theBytes[ off + i ] );
}
}
 
public void close() throws java.io.IOException
{
if( position > 0 )
{
out.write( encode3to4( b4, buffer, position ), 0, position+1 );
position = 0;
}
 
super.close();
buffer = null;
out = null;
}
}
}
/backpath/trunk/build.xml
0,0 → 1,49
<project name="backpath" default="lib" basedir=".">
 
<property name="build.compiler" value="jikes" />
 
<property name="src" location="src" />
<property name="classes" location="classes" />
<property name="lib" location="lib" />
<property name="output" location="output" />
<property name="classpath" value="" />
 
<path id="classpath.general">
<pathelement path="${classpath}" />
</path>
 
<path id="classpath.compile">
<path refid="classpath.general" />
<pathelement location="${classes}" />
<fileset dir="${lib}">
<include name="**/*.jar" />
</fileset>
</path>
 
<target name="compile">
<mkdir dir="${classes}" />
 
<javac
srcdir="${src}"
destdir="${classes}"
classpathref="classpath.compile"
debug="on"
nowarn="on"
/>
</target>
 
<target name="lib" depends="compile">
<mkdir dir="${output}" />
<jar
destfile="${output}/backpath.jar"
basedir="${classes}"
/>
</target>
 
<target name="clean">
<delete dir="${classes}"/>
</target>
 
<target name="all" depends="clean,lib" />
 
</project>
/backpath/trunk/.
Property changes:
Added: svn:ignore
+classes
+output