package com.onpositive.gae.baseviewer;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
import org.eclipse.text.edits.ReplaceEdit;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.Category;
import com.google.appengine.api.datastore.Email;
import com.google.appengine.api.datastore.GeoPt;
import com.google.appengine.api.datastore.IMHandle;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Link;
import com.google.appengine.api.datastore.PhoneNumber;
import com.google.appengine.api.datastore.PostalAddress;
import com.google.appengine.api.datastore.ShortBlob;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.datastore.IMHandle.Scheme;
import com.google.appengine.api.users.User;
import com.google.appengine.repackaged.com.google.common.collect.Collections2;
import com.google.apphosting.api.ApiProxy;
import com.onpositive.commons.utils.Base64;
public class StringInputOutput {
private final static String UNSUPPORTED_TYPE = "unsupported type";
public static final Class<?>[] SUPPORTED_TYPES = new Class[] {
String.class, Long.class, Double.class, Boolean.class, Date.class,
Text.class, ShortBlob.class, Blob.class, Link.class,
Category.class, Email.class, PostalAddress.class,
PhoneNumber.class, IMHandle.class, GeoPt.class, User.class,
Key.class, BlobKey.class };
public static String toString(Object obj) {
if (obj instanceof String) {
return obj.toString();
} else if (obj instanceof Long) {
return obj.toString();
} else if (obj instanceof Double) {
return obj.toString();
} else if (obj instanceof Boolean) {
return obj.toString();
} else if (obj instanceof Date) {
return DateFormat.getDateTimeInstance(DateFormat.FULL,
DateFormat.FULL,Locale.US).format((Date) obj);// DateFormat.getInstance().format((Date)
// obj);
} else if (obj instanceof Text) {
Text text = (Text) obj;
return text.getValue();
} else if (obj instanceof ShortBlob) {
ShortBlob sbl = (ShortBlob) obj;
return Base64.encodeBytes(sbl.getBytes());
} else if (obj instanceof Blob) {
Blob sbl = (Blob) obj;
return Base64.encodeBytes(sbl.getBytes());
} else if (obj instanceof Link) {
Link lnk = (Link) obj;
return lnk.getValue();
} else if (obj instanceof Category) {
Category cat = (Category) obj;
return cat.getCategory();
} else if (obj instanceof Email) {
Email mail = (Email) obj;
return mail.getEmail();
} else if (obj instanceof PostalAddress) {
PostalAddress pa = (PostalAddress) obj;
return pa.getAddress();
} else if (obj instanceof PhoneNumber) {
PhoneNumber number = (PhoneNumber) obj;
return number.getNumber();
} else if (obj instanceof IMHandle) {
IMHandle imh = (IMHandle) obj;
return imh.getProtocol().replaceAll("\\|", "\\|") + "|" // \\\\|
+ imh.getAddress().replaceAll("\\|", "\\|");// \\\\|
} else if (obj instanceof GeoPt) {
GeoPt gpt = (GeoPt) obj;
return gpt.getLatitude() + "|" + gpt.getLongitude();
} else if (obj instanceof User) {
User usr = (User) obj;
String userId = usr.getUserId();
String nickname = usr.getNickname();
String authDomain = usr.getAuthDomain();
String email = usr.getEmail();
userId = userId == null ? "" : userId.replaceAll("\\|", "\\|");// \\\\|
nickname = nickname == null ? "" : nickname
.replaceAll("\\|", "\\|");// \\\\|
authDomain = authDomain == null ? "" : authDomain.replaceAll("\\|",
"\\|");// \\\\|
email = email == null ? "" : email.replaceAll("\\|", "\\|");// \\\\|
return userId + "|" + nickname + "|" + authDomain + "|" + email;
} else if (obj instanceof Key) {
Key k = (Key) obj;
String ks = KeyFactory.keyToString(k);
return ks;
} else if (obj instanceof BlobKey) {
BlobKey k = (BlobKey) obj;
return k.getKeyString();
} else if (obj instanceof Collection) {
StringBuilder res = new StringBuilder();
res.append("|");
Collection col = (Collection) obj;
for (Iterator i = col.iterator(); i.hasNext();) {
Object next = i.next();
String tmp = toString(next);
if (tmp != null) {
tmp = tmp.replaceAll("\\|", "\\|");// \\\\|
res.append(tmp);
} else {
res.append("null");
}
res.append("|");
}
return res.toString();
}
if (obj == null) {
return null;
}
return UNSUPPORTED_TYPE;
}
public static String typeToString(Object value) {
if (value == null) {
return "null";
} else if ((value instanceof Collection)) {
StringBuilder res = new StringBuilder();
res.append(value.getClass().getCanonicalName());
res.append("|");
Collection col = (Collection) value;
for (Iterator i = col.iterator(); i.hasNext();) {
Object next = i.next();
String tmp = typeToString(next);
tmp = tmp.replaceAll("\\|", "\\|");// \\\\|
res.append(tmp);
res.append("|");
}
return res.toString();
} else {
return value.getClass().getCanonicalName();
}
}
public static Object createObject(String className, String args,
String appNamespace) {
if (className.equals(UNSUPPORTED_TYPE) || className.equals("null")) {
return null;
}
String[] types = split(className, '|');
try {
Class obj = Class.forName(types[0]);
if (obj == String.class) {
return args;
} else if (obj == Long.class) {
return Long.valueOf(args);
} else if (obj == Double.class) {
return Double.valueOf(args);
} else if (obj == Boolean.class) {
return Boolean.valueOf(args);
} else if (obj == Date.class) {
try {
return DateFormat.getDateTimeInstance(DateFormat.FULL,
DateFormat.FULL, Locale.US).parse(args);
} catch (ParseException exc) {
return parseUsingAppropriateLocale(args);
}
} else if (obj == Text.class) {
return new Text(args);
} else if (obj == ShortBlob.class) {
return new ShortBlob(Base64.decode(args));
} else if (obj == Blob.class) {
return new Blob(Base64.decode(args));
} else if (obj == Link.class) {
return new Link(args);
} else if (obj == Category.class) {
return new Category(args);
} else if (obj == Email.class) {
return new Email(args);
} else if (obj == PostalAddress.class) {
return new PostalAddress(args);
} else if (obj == PhoneNumber.class) {
return new PhoneNumber(args);
} else if (obj == IMHandle.class) {
String[] arguments = split(args, '|');
if (args.length() != 2) {
return null;
}
return new IMHandle(Scheme.valueOf(arguments[0].replaceAll(
"\\|", "|")), arguments[1].replaceAll("\\|", "|"));// "\\\\|","\\|"
} else if (obj == GeoPt.class) {
String[] arguments = args.split("\\|");
if (arguments.length != 2) {
return null;
}
return new GeoPt(Float.parseFloat(arguments[0]),
Float.parseFloat(arguments[1]));
} else if (obj == User.class) {
String[] arguments = args.split("\\|");
if (arguments.length != 4) {
return null;
}
String p1 = arguments[3].replaceAll("\\|", "|");// \\\\|", "\\|"
String p2 = arguments[2].replaceAll("\\|", "|");
String p3 = arguments[0].replaceAll("\\|", "|");
return new User(p1, p2, p3);
} else if (obj == Key.class) {
Key tmpKey = KeyFactory.stringToKey(args);
return dublicateKey(tmpKey, appNamespace);
} else if (obj == BlobKey.class) {
return new BlobKey(args);
} else if (Collection.class.isAssignableFrom(obj)) {
Collection col = (Collection) obj.newInstance();
String[] splitted = split(args, '|');
for (int i = 0; i < splitted.length; i++) {
String param = splitted[i].replaceAll("\\|", "|");// \\\\|", "\\|"
String tmpType = types[i + 1];
if (tmpType == null || tmpType.length() == 0) {
continue;
}
Object newObj = createObject(tmpType, splitted[i],
appNamespace);
col.add(newObj);
}
return col;
}
} catch (InstantiationException e) {
// e.printStackTrace();
} catch (IllegalAccessException e) {
// e.printStackTrace();
} catch (ClassNotFoundException e) {
// e.printStackTrace();
}/*
* catch (ParseException e) { // e.printStackTrace(); return null; }
*/
return null;
}
public static Key dublicateKey(Key key, String appNamespace) {
Key parent = key.getParent();
if (parent != null) {
parent = dublicateKey(parent, appNamespace);
}
long id = key.getId();
try {
if (id == 0) {
Key tmp = KeyFactory.createKey(parent, key.getKind(),
key.getName());
return tmp;
} else {
Key tmp = KeyFactory.createKey(parent, key.getKind(),
key.getId());
return tmp;
}
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static String[] split(String input, char delimiter) {
ArrayList<String> splitted = new ArrayList<String>();
int lastIndex = 0;
for (int i = 0; i < input.length(); i++) {
if (input.charAt(i) == delimiter) {
if (i != 0 && input.charAt(i - 1) != '\\') {
String tmp = input.substring(lastIndex, i);
splitted.add(tmp);
if (i != input.length() - 1) {
lastIndex = i + 1;
} else {
// int abc = 10;
splitted.add("");
break;
}
} else if (i == 0) {
if (i != input.length() - 1) {
lastIndex = 1;
} else {
break;
}
}
} else if (i == input.length() - 1) {
String tmp = input.substring(lastIndex);
splitted.add(tmp);
}
}
return splitted.toArray(new String[splitted.size()]);
}
private static Date parseUsingAppropriateLocale(String args) {
Locale[] allAvailable = Locale.getAvailableLocales();
for (Locale l : allAvailable) {
DateFormat dateTimeInstance = DateFormat.getDateTimeInstance(
DateFormat.FULL, DateFormat.FULL, l);
Date parsed = dateTimeInstance.parse(args, new ParsePosition(0));
if (parsed != null) {
return parsed;
}
}
return null;
}
}