/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 |