package com.jcommerce.gwt.client;
//import it.sauronsoftware.base64.Base64;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.History;
public abstract class PageState implements Command{
public static PageState curState;
private ContentWidget pageInstance;
private boolean editting = false;
private Map<String, Object> map = new HashMap<String, Object>();
public String getMenuDisplayName() {
return "";
}
public abstract String getPageClassName();
// will break if the value contains =&-_
public final String EQUAL = "=";
public final String AND = "&";
public final String LEFT = "-";
public final String RIGHT = "-";
public final String EQUALCODE="%FFFFFF";
public final String ANDCODE="%EEEEEE";
public final String LEFTCODE="%CCCCC";
public final String RIGHTCODE="%DDDDDD";
public ContentWidget getPageInstance() {
return pageInstance;
}
public void setPageInstance(ContentWidget pageInstance) {
this.pageInstance = pageInstance;
}
public boolean isEditting() {
return editting;
}
public void setEditting(boolean editting) {
this.editting = editting;
}
public final void execute() {
curState = this;
System.out.println("token: "+getFullHistoryToken());
History.newItem(getFullHistoryToken());
}
public String getFullHistoryToken() {
return getPageClassName()+getHistoryToken();
}
public String getHistoryToken() {
StringBuffer uriBuf = new StringBuffer();
System.out.println("map:"+map);
// uriBuf.append(getPageName());
for(String key : map.keySet()) {
Object value = map.get(key);
uriBuf.append(AND).append(encode(key)).append(EQUAL);
if(value instanceof List) {
List<String> valueList = (List<String>)value;
// TODO leon consider if valuelist is empty??
uriBuf.append(LEFT);
for(String s:valueList) {
uriBuf.append(encode(s)).append(",");
}
uriBuf.append(RIGHT);
}
else {
uriBuf.append(encode((String)value));
}
}
return uriBuf.toString();
}
public String encode (String s){
if (s == null) {
return s;
}
String res = s;
res = res.replace(EQUAL, EQUALCODE);
res = res.replace(AND, ANDCODE);
res = res.replace(LEFT, LEFTCODE);
res = res.replace(RIGHT, RIGHTCODE);
// String res = Base64.encode(s);
// byte[] ss = Base64.encode(Util.getBytes(s));
// res = Util.toString(ss);
res = URL.encode(res);
// res = URLEncoder.encode(res, "UTF-8");
// res = res.replace('+', '*');
// res = res.replace('/', '-');
Logger.getClientLogger().log("encode: before="+s+", after="+res);
return res;
}
public String decode(String s){
String res = s;
res = URL.decode(res);
// res = res.replace('-', '/');
// res = res.replace('*', '+');
// res = URLDecoder.decode(res, "UTF-8");
res = res.replace(EQUALCODE, EQUAL);
res = res.replace(ANDCODE, AND );
res = res.replace(LEFTCODE,LEFT);
res = res.replace(RIGHTCODE, RIGHT);
// byte[] ss = Base64.decode(Util.getBytes(s));
// res = Util.toString(ss);
// res = Base64.decode(s);
Logger.getClientLogger().log("decode: before="+s+", after="+res);
return res;
}
public void fromHistoryToken(String uri) {
// TODO simple version. need improve
// &p1=abc&p2={opq,xyz}
// map.clear();
if(uri == null || "".equals(uri))
return;
String[] ss = uri.split(AND);
for(String s:ss) {
// debug
Logger.getClientLogger().log("s: "+s);
String[] pair = s.split(EQUAL);
if(pair.length==2) {
String key = decode(pair[0]);
if(pair[1].indexOf(LEFT)>=0) {
//p2={opq,xyz}
String vv = pair[1].substring(pair[1].indexOf(LEFT)+1, pair[1].lastIndexOf(RIGHT));
Logger.getClientLogger().log("vv: "+vv);
String[] values = vv.split(",");
List<String> valueList = new ArrayList<String>();
for(String value:values) {
valueList.add(decode(value));
}
map.put(key, valueList);
}
else {
String value = decode(pair[1]);
map.put(key, value);
}
}
}
}
public static String[] parseFullHistoryToken (String fullHistoryToken) {
String pageClassName = fullHistoryToken;
String stateStr = "";
int i=fullHistoryToken.indexOf("&");
if(i>=0) {
pageClassName = fullHistoryToken.substring(0, i);
stateStr = fullHistoryToken.substring(i);
}
String[] res = new String[]{pageClassName, stateStr};
return res;
}
public void setValue(String key, Object value){
if ("null".equals(value)) {
value = null;
}
if (value != null) {
map.put(key, value);
}
}
public Object getValue(String key){
if ("null".equals(map.get(key))) {
return null;
}
return map.get(key);
}
public static void main(String[] args) {
// PageState ps = new PageState() {
// public String getPageName() {
// return "test";
// }
// };
// ps.setValue("p1", "abc");
//
// List<String> p2 = new ArrayList<String>();
// p2.add("张三");
// p2.add("李四");
//
// ps.setValue("p2", p2);
//
// String token = ps.getHistoryToken();
// Logger.getClientLogger().log("token: "+token);
//
// ps.fromHistoryToken(token);
// Logger.getClientLogger().log("p1: "+ps.getValue("p1"));
// Logger.getClientLogger().log("p2: ");
// for(String value: (List<String>)(ps.getValue("p2"))) {
// Logger.getClientLogger().log(value);
// }
//
// token = ps.getHistoryToken();
// Logger.getClientLogger().log("token again: "+token);
State newState = new State();
newState.setMessage("添加商品类型成功-=&");
State choice1 = new State();
choice1.setValue("p1", "id1");
newState.addChoice("attribute", choice1.getFullHistoryToken());
String token = newState.getHistoryToken();
Logger.getClientLogger().log("token: "+token);
newState.fromHistoryToken(token);
Logger.getClientLogger().log("message: "+newState.getMessage());
Logger.getClientLogger().log("choice: ");
for(String[] value: (List<String[]>)(newState.getChoices())) {
Logger.getClientLogger().log(value[0]+","+value[1]);
}
}
public static class State extends PageState {
public static final String MESSAGE = "msg";
public static final String CHOICES = "ch";
public static final String SEPERATOR = "xxxxxx";
public String getPageClassName() {
return "mypage";
}
public void addChoice(String name, String historyToken) {
List<String> choices = (List<String>)getValue(CHOICES);
if(choices == null) {
choices = new ArrayList<String>();
setValue(CHOICES, choices);
}
choices.add(name+SEPERATOR+historyToken);
}
public List<String[]> getChoices() {
List<String> choices = (List<String>)getValue(CHOICES);
List<String[]> res = new ArrayList<String[]>();
for(String choice:choices) {
int i = choice.indexOf(SEPERATOR);
String[] ss = new String[] {choice.substring(0, i), choice.substring(i+SEPERATOR.length())};
res.add(ss);
}
return res;
}
public void setMessage(String message) {
setValue(MESSAGE, message);
}
public String getMessage() {
return (String)getValue(MESSAGE);
}
}
}