package com.onpositive.gae.baseviewer;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import org.eclipse.core.runtime.IProgressMonitor;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.onpositive.commons.ui.tableeditor.Filter;
import com.onpositive.commons.ui.tableeditor.Query;
import com.onpositive.commons.ui.tableeditor.Sort;
import com.onpositive.gae.baseviewer.BaseDataFacade.Callback;
import com.onpositive.gae.baseviewer.BaseDataFacade.GAEField;
import com.onpositive.gae.baseviewer.io.EntityAccess;
public class Request {
public static class StoreBlobPart extends RequestPart {
private String filePath;
private Entity e;
public StoreBlobPart(Entity e, String filePath, String namespace) {
super(namespace);
this.e = e;
this.filePath = filePath;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(STORE_BLOB);
EntityAccess.writeEntityToStream(e, st);
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) throws IOException {
String fName = (String) e
.getProperty(BlobStoreDataFacade.FILENAME_PROP);
// String fullfilePath = filePath + "/" + fName;
File fullFilePath = null;
if (filePath != null) {
File parent = new File(filePath);
fullFilePath = new File(parent, fName);
} else {
fullFilePath = new File(fName);
}
FileOutputStream fOS = new FileOutputStream(fullFilePath);
byte[] buff = new byte[1024];
int ch = 0;
long count = 0;
long fSiz = (Long) e.getProperty(BlobStoreDataFacade.SIZEF_PROP);
while ((ch = communicate.read(buff)) > 0) {
fOS.write(buff, 0, ch);
count += ch;
}
fOS.close();
if (count != fSiz) {
return -1;
}
return 1;
}
}
public static class AddBlobPart extends RequestPart {
public String connURL;
public AddBlobPart(Object obj, String namespace) {
super(namespace);
connURL = (String) obj;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(ADD_BLOB);
st.write(connURL.getBytes());
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) throws IOException {
int length = communicate.readInt();
if (length > 0) {
byte[] buff = new byte[length];
int ch = communicate.read(buff);
if (ch == length) {
return new String(buff);
} else {
return null;
}
} else {
return null;
}
}
}
public static class ViewBlobPart extends RequestPart {
int limit;
public ViewBlobPart(int limit, String namespace) {
super(namespace);
this.limit = limit;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(VIEW_BLOB);
st.writeInt(limit);
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) throws IOException {
if (monitor.isCanceled()) {
return new Object[0];
}
ArrayList<Entity> result = new ArrayList<Entity>();
while (true) {
if (monitor.isCanceled()) {
return result;
}
int readInt = communicate.readInt();
if (readInt == 1) {
Entity read = EntityAccess.read(communicate);
if (cb != null) {
cb.objectFetched(read);
}
result.add(read);
} else if (readInt == 0) {
long time = communicate.readLong();
if (cb != null) {
cb.objectFetched(new State(time, null, null, true));
}
break;
} else if (readInt == 3) {
long time = communicate.readLong();
if (cb != null) {
cb.objectFetched(new State(time, null, null, false));
}
break;
} else if (readInt == 2) {
String message = communicate.readUTF();
String trace = communicate.readUTF();
long time = communicate.readLong();
if (cb != null) {
cb.objectFetched(new State(time, message, trace, false));
}
break;
} else {
while (true) {
ByteArrayOutputStream s = new ByteArrayOutputStream();
int k = communicate.read();
while (k != -1) {
s.write(k);
k = communicate.read();
}
break;
}
}
}
return result;
}
}
public static class RemoveBlobPart extends RequestPart {
private Object entity;
public RemoveBlobPart(Object obj, String namespace) {
super(namespace);
entity = obj;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(REMOVE_BLOB);
EntityAccess.writeEntityToStream((Entity) entity, st);
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) throws IOException {
// TODO Auto-generated method stub
return null;
}
}
public static class GetRequestPart extends RequestPart {
private HashSet<Key> values;
private int limit;
public GetRequestPart(Collection<Key> toFetch, int i, String namespace) {
super(namespace);
this.values = new HashSet<Key>(toFetch);
this.limit = i;
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) throws IOException {
int readInt = communicate.readInt();
for (int a = 0; a < readInt; a++) {
Entity read = EntityAccess.read(communicate);
cb.objectFetched(read);
}
return readInt;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(GET_BULK);
st.writeInt(limit);
Entity e = (Entity) new Entity("Q");
e.setProperty("key", values);
EntityAccess.writeEntityToStream(e, st);
}
}
public static final int ADD = 1;
public static final int REMOVE = 2;
public static final int UPDATE = 3;
public static final int VIEW = 4;
public static final int GET_FULL = 5;
public static final int GET_BULK = 6;
public static final int ADD_BLOB = 7;
public static final int STORE_BLOB = 8;
public static final int REMOVE_BLOB = 9;
public static final int VIEW_BLOB = 10;
public static final int REMOVE_ALL = 11;
public static final int REMOVE_PROP = 12;
public static final int RENAME_PROP = 13;
public static final int CHECK_STATUS = 15;
public static final int COPY_ENT = 16;
public static final int INDEXATION = 17;
public static final int SET_PROP_VALUE = 18;
public static final int SET_PROP_VALUE_BY_DEF = 19;
public static abstract class RequestPart {
protected String namespace;
public RequestPart(String namespace) {
this.namespace = namespace;
}
public abstract void write(DataOutputStream st) throws IOException;
public abstract Object parseResult(DataInputStream communicate,
Callback cb, IProgressMonitor monitor) throws IOException;
public void preprocess(IProgressMonitor monitor) throws Exception {
}
}
public static abstract class QueueRequestPart extends RequestPart {
public QueueRequestPart(String namespace) {
super(namespace);
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) throws IOException {
int code = communicate.readInt();
if (code == 0) {
String id = communicate.readUTF();
return id;
} else if (code == 1) {
String message = communicate.readUTF();
String trace = communicate.readUTF();
throw new IOException("Message: " + message
+ "\n\rstack trace:\n\r" + trace);
}
return null;
}
}
public static class CopyEntityRequestPart extends QueueRequestPart {
private int count;
private String key;
private String kind;
public CopyEntityRequestPart(String namespace, int count, String key,
String kind) {
super(namespace);
this.count = count;
this.key = key;
this.kind = kind;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(COPY_ENT);
st.writeUTF(kind);
st.writeInt(count);
st.writeUTF(key);
}
}
public static class CheckStatusRequestPart extends RequestPart {
private String kind;
private String id;
private String prop;
public CheckStatusRequestPart(String namespace, String kind, String id) {
super(namespace);
this.kind = kind;
this.id = id;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(CHECK_STATUS);
st.writeUTF(id);
st.writeUTF(kind);
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) throws IOException {
Entity e = EntityAccess.read(communicate);
return e;
}
}
public static class RemoveAllRequestPart extends QueueRequestPart {
private String kind;
public RemoveAllRequestPart(String namespace, String kind) {
super(namespace);
this.kind = kind;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(REMOVE_ALL);
st.writeUTF(kind);
}
}
public static class RemovePropertyRequestPart extends QueueRequestPart {
private String kind;
private String property;
public RemovePropertyRequestPart(String namespace, String kind,
String oldProp) {
super(namespace);
this.kind = kind;
this.property = oldProp;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(REMOVE_PROP);
st.writeUTF(kind);
st.writeUTF(property);
}
}
public static class SetPropertyValueRequestPart extends QueueRequestPart {
private String property;
private Entity element;
private boolean setDefault;
public SetPropertyValueRequestPart(String namespace, String property,
Entity element, boolean setDefault) {
super(namespace);
this.property = property;
this.element = element;
this.setDefault = setDefault;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(SET_PROP_VALUE);
st.writeUTF(element.getKind());
st.writeUTF(property);
st.writeBoolean(setDefault);
EntityAccess.writeEntityToStream(element, st);
}
}
public static class RenamePropertyRequestPart extends QueueRequestPart {
private String kind;
private String oldProperty;
private String newProperty;
public RenamePropertyRequestPart(String namespace, String kind,
String oldP, String newP) {
super(namespace);
this.kind = kind;
this.oldProperty = oldP;
this.newProperty = newP;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(RENAME_PROP);
st.writeUTF(kind);
st.writeUTF(oldProperty);
st.writeUTF(newProperty);
}
}
public static class ChandgeIndexationRequestPart extends QueueRequestPart {
private String property;
private String kind;
private boolean isUnindexed;
public ChandgeIndexationRequestPart(String namespace, String kind,
String property, boolean makeUnindexed) {
super(namespace);
this.property = property;
this.kind = kind;
this.isUnindexed = makeUnindexed;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(INDEXATION);
st.writeUTF(kind);
st.writeUTF(property);
st.writeBoolean(isUnindexed);
}
}
public static class AddRequestPart extends RequestPart {
Object obj;
public AddRequestPart(Object object, String namespace) {
super(namespace);
this.obj = object;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(ADD);
Entity e = (Entity) obj;
EntityAccess.writeEntityToStream(e, st);
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) {
return null;
}
}
public static class ComplexFilter {
public final String value;
public ComplexFilter(String value, GAEField field) {
super();
this.value = value;
this.field = field;
}
public final GAEField field;
public String toString() {
return value;
}
}
public static class RemoveRequestPart extends RequestPart {
private Object obj;
public RemoveRequestPart(Object object, String namespace) {
super(namespace);
obj = object;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(REMOVE);
Entity e = (Entity) obj;
Entity e1 = e.clone();
for (String s : new HashSet<String>(e1.getProperties().keySet())) {
e1.removeProperty(s);
}
EntityAccess.writeEntityToStream(e1, st);
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) throws IOException {
return null;
}
}
public static class UpdateRequestPart extends RequestPart {
Object obj;
public UpdateRequestPart(Object object, String namespace) {
super(namespace);
this.obj = object;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(UPDATE);
Entity e = (Entity) obj;
EntityAccess.writeEntityToStream(e, st);
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) {
return null;
}
}
public static class GetFullRequestPart extends RequestPart {
Object obj;
public GetFullRequestPart(Object object, String namespace) {
super(namespace);
this.obj = object;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(GET_FULL);
Entity e = (Entity) obj;
EntityAccess.writeEntityToStream(e, st);
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) throws IOException {
int e = communicate.readInt();
if (e == 2) {
return "Entity does not exist more";
}
if (e == 1) {
return EntityAccess.read(communicate);
} else {
ByteArrayOutputStream bs = new ByteArrayOutputStream();
while (true) {
int k = communicate.read();
if (k == -1) {
break;
}
bs.write(k);
}
System.out.println(new String(bs.toByteArray()));
return null;
}
}
}
public static class State {
public final long time;
public final String message;
public final String trace;
public final boolean completed;
public State(long time, String meString, String trace, boolean completed) {
super();
this.time = time;
this.message = meString;
this.trace = trace;
this.completed = completed;
}
}
public static class ViewRequestPart extends RequestPart {
private String kind;
private Query query;
private String startFrom = "";
int limit;
private boolean keysOnly;
private boolean count;
private boolean isForStoring;
public ViewRequestPart(String kind, Query query, int limit,
String namespace) {
this(kind, query, limit, false, namespace);
}
public ViewRequestPart(String kind, Query query, int limit,
boolean isForStoring, String namespace) {
super(namespace);
this.kind = kind;
this.query = query;
this.limit = limit;
this.isForStoring = isForStoring;
}
public void write(DataOutputStream st) throws IOException {
st.writeInt(VIEW);
st.writeUTF(kind);
st.writeUTF(query.sort.property);
st.writeBoolean(query.sort.ascending);
Entity e = new Entity("Filters");
for (Filter f : query.filters) {
String property = f.property;
e.setProperty(property, f.value);
if (f.kind != Filter.EQUAL) {
e.setProperty("$ONPOSITIVE_FILTER_OPERATOR_" + property,
f.kind);
}
}
EntityAccess.writeEntityToStream(e, st);
st.writeInt(limit);
st.writeUTF(startFrom);
st.writeBoolean(keysOnly);
st.writeBoolean(count);
st.writeBoolean(isForStoring);
}
public void preprocess(IProgressMonitor monitor) throws Exception {
// lets determine target area;
for (Filter f : query.filters) {
if (f.kind == Filter.COMPLEX_FILTER) {
ComplexFilter cFilter = (ComplexFilter) f.value;
GAEField field = cFilter.field;
int indexOf = cFilter.value.indexOf('=');
ArrayList<Filter> filters = new ArrayList<Filter>();
// we should understand filters here
if (indexOf == -1) {
} else {
if (field.keyKindDetails != null) {
}
}
if (filters.size() > 0) {
ArrayList<Key> keys = new ArrayList<Key>();
Query c = new Query(filters.toArray(new Filter[filters
.size()]), new Sort("", false), 100, 0);
c.keysOnly = true;
BaseDataFacade createFacade = field
.createFacade(field.keyKind);
Entity[] query2 = createFacade.query(c, monitor);
for (Entity e : query2) {
keys.add(e.getKey());
}
}
}
}
super.preprocess(monitor);
}
public Object parseResult(DataInputStream communicate, Callback cb,
IProgressMonitor monitor) throws IOException {
if (monitor.isCanceled()) {
return new Object[0];
}
ArrayList<Entity> result = new ArrayList<Entity>();
while (true) {
if (monitor.isCanceled()) {
return result;
}
int readInt = communicate.readInt();
if (readInt == 1) {
Entity read = EntityAccess.read(communicate);
if (cb != null) {
cb.objectFetched(read);
}
result.add(read);
} else if (readInt == 0) {
long time = communicate.readLong();
if (cb != null) {
cb.objectFetched(new State(time, null, null, true));
}
break;
} else if (readInt == 3) {
long time = communicate.readLong();
if (cb != null) {
cb.objectFetched(new State(time, null, null, false));
}
break;
} else if (readInt == 2) {
String message = communicate.readUTF();
String trace = communicate.readUTF();
long time = communicate.readLong();
if (cb != null) {
cb.objectFetched(new State(time, message, trace, false));
}
break;
} else if (readInt == 5) {
String message = communicate.readUTF();
String trace = communicate.readUTF();
if (cb != null) {
cb.objectFetched(new State(System.currentTimeMillis(),
message, trace, false));
}
break;
} else {
while (true) {
ByteArrayOutputStream s = new ByteArrayOutputStream();
int k = communicate.read();
while (k != -1) {
s.write(k);
k = communicate.read();
}
break;
}
}
}
return result;
}
}
protected ArrayList<RequestPart> parts = new ArrayList<RequestPart>();
public void addPart(RequestPart p) {
parts.add(p);
}
public void write(DataOutputStream s) throws IOException {
s.writeInt(parts.size());
if (parts.size() == 0) {
s.writeUTF("");
} else {
if (parts.get(0).namespace.length() == 0) {
s.writeUTF(parts.get(0).namespace);
} else {
s.writeUTF(parts.get(0).namespace);
}
}
for (RequestPart p : parts) {
p.write(s);
}
}
public Object[] parse(DataInputStream ds, Callback cb,
IProgressMonitor monitor) throws IOException {
Object[] result = new Object[parts.size()];
int a = 0;
for (RequestPart p : parts) {
result[a++] = p.parseResult(ds, cb, monitor);
}
return result;
}
}