package org.openntf.domino.rest.resources.frames;
import com.ibm.commons.util.io.json.JsonException;
import com.ibm.commons.util.io.json.JsonJavaObject;
import com.ibm.commons.util.io.json.JsonParser;
import com.tinkerpop.frames.VertexFrame;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriInfo;
import org.openntf.domino.graph2.annotations.FramedEdgeList;
import org.openntf.domino.graph2.annotations.FramedVertexList;
import org.openntf.domino.graph2.impl.DFramedTransactionalGraph;
import org.openntf.domino.rest.json.JsonGraphFactory;
import org.openntf.domino.rest.json.JsonGraphWriter;
import org.openntf.domino.rest.resources.AbstractCollectionResource;
import org.openntf.domino.rest.service.ODAGraphService;
import org.openntf.domino.rest.service.Parameters;
import org.openntf.domino.rest.service.Parameters.ParamMap;
import org.openntf.domino.rest.service.Routes;
import org.openntf.domino.types.CaseInsensitiveString;
@Path(Routes.ROOT + "/" + Routes.FRAMES + "/" + Routes.NAMESPACE_PATH_PARAM)
public class FramedCollectionResource extends AbstractCollectionResource {
public FramedCollectionResource(ODAGraphService service) {
super(service);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getFramedObject(@Context final UriInfo uriInfo, @PathParam(Routes.NAMESPACE) final String namespace)
throws JsonException, IOException {
@SuppressWarnings("rawtypes")
DFramedTransactionalGraph graph = this.getGraph(namespace);
String jsonEntity = null;
ResponseBuilder builder = Response.ok();
ParamMap pm = Parameters.toParamMap(uriInfo);
StringWriter sw = new StringWriter();
JsonGraphWriter writer = new JsonGraphWriter(sw, graph, pm, false, true);
if (pm.getTypes() != null) {
List<CharSequence> types = pm.getTypes();
List<CharSequence> filterkeys = pm.getFilterKeys();
List<CharSequence> filtervalues = pm.getFilterValues();
List<CharSequence> partialkeys = pm.getPartialKeys();
List<CharSequence> partialvalues = pm.getPartialValues();
List<CharSequence> startskeys = pm.getStartsKeys();
List<CharSequence> startsvalues = pm.getStartsValues();
if (types.size() == 0) {
writer.outNull();
} else if (types.size() == 1) {
CharSequence typename = types.get(0);
Iterable<?> elements = null;
if (filterkeys != null) {
elements = graph.getFilteredElements(typename.toString(), filterkeys, filtervalues);
} else if (partialkeys != null) {
elements = graph.getFilteredElementsPartial(typename.toString(), partialkeys, partialvalues);
} else if (startskeys != null) {
elements = graph.getFilteredElementsStarts(typename.toString(), startskeys, startsvalues);
} else {
// System.out.println("TEMP DEBUG Getting elements for type "
// + typename);
elements = graph.getElements(typename.toString());
}
if (elements instanceof FramedEdgeList) {
FramedEdgeList<?> result = (FramedEdgeList<?>) elements;
if (pm.getOrderBys() != null) {
result = result.sortBy(pm.getOrderBys(), pm.getDescending());
}
if (pm.getStart() > 0) {
if (pm.getCount() > 0) {
result = (FramedEdgeList<?>) result.subList(pm.getStart(), pm.getStart() + pm.getCount());
} else {
result = (FramedEdgeList<?>) result.subList(pm.getStart(), result.size());
}
}
writer.outArrayLiteral(result);
} else if (elements instanceof FramedVertexList) {
FramedVertexList<?> result = (FramedVertexList<?>) elements;
if (pm.getOrderBys() != null) {
result = result.sortBy(pm.getOrderBys(), pm.getDescending());
}
if (pm.getStart() > 0) {
if (pm.getCount() > 0) {
result = (FramedVertexList<?>) result.subList(pm.getStart(), pm.getStart() + pm.getCount());
} else {
result = (FramedVertexList<?>) result.subList(pm.getStart(), result.size());
}
}
writer.outArrayLiteral(result);
} else {
List<Object> maps = new ArrayList<Object>();
for (Object element : elements) {
maps.add(element);
}
writer.outArrayLiteral(maps);
}
} else {
FramedVertexList vresult = null;
FramedEdgeList eresult = null;
for (CharSequence typename : types) {
Iterable<?> elements = null;
if (filterkeys != null) {
elements = graph.getFilteredElements(typename.toString(), filterkeys, filtervalues);
} else if (partialkeys != null) {
elements = graph.getFilteredElementsPartial(typename.toString(), partialkeys, partialvalues);
} else if (startskeys != null) {
elements = graph.getFilteredElementsStarts(typename.toString(), startskeys, startsvalues);
} else {
elements = graph.getElements(typename.toString());
}
if (elements instanceof FramedVertexList) {
if (vresult == null) {
vresult = (FramedVertexList) elements;
} else {
vresult.addAll((FramedVertexList) elements);
}
} else if (elements instanceof FramedEdgeList) {
if (eresult == null) {
eresult = (FramedEdgeList) elements;
} else {
eresult.addAll((FramedEdgeList) elements);
}
}
}
if (vresult != null) {
if (pm.getOrderBys() != null) {
vresult = vresult.sortBy(pm.getOrderBys(), pm.getDescending());
}
if (pm.getStart() > 0) {
if (pm.getCount() > 0) {
vresult = (FramedVertexList<?>) vresult.subList(pm.getStart(),
pm.getStart() + pm.getCount());
} else {
vresult = (FramedVertexList<?>) vresult.subList(pm.getStart(), vresult.size());
}
}
writer.outArrayLiteral(vresult);
}
if (eresult != null) {
if (pm.getOrderBys() != null) {
eresult = eresult.sortBy(pm.getOrderBys(), pm.getDescending());
}
if (pm.getStart() > 0) {
if (pm.getCount() > 0) {
eresult = (FramedEdgeList<?>) eresult.subList(pm.getStart(), pm.getStart() + pm.getCount());
} else {
eresult = (FramedEdgeList<?>) eresult.subList(pm.getStart(), eresult.size());
}
}
writer.outArrayLiteral(eresult);
}
}
jsonEntity = sw.toString();
} else {
// System.out.println("TEMP DEBUG: ID was null therefore we can't report...");
MultivaluedMap<String, String> mvm = uriInfo.getQueryParameters();
for (String key : mvm.keySet()) {
// System.out.println("TEMP DEBUG: " + key + ": " +
// mvm.getFirst(key));
}
Map<String, Object> jsonMap = new LinkedHashMap<String, Object>();
jsonMap.put("namespace", namespace);
jsonMap.put("status", "active");
writer.outObject(jsonMap);
jsonEntity = sw.toString();
}
builder.type(MediaType.APPLICATION_JSON_TYPE).entity(jsonEntity);
Response response = builder.build();
return response;
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createFramedObject(String requestEntity, @Context final UriInfo uriInfo,
@PathParam(Routes.NAMESPACE) final String namespace) throws JsonException, IOException {
org.apache.wink.common.internal.registry.metadata.ResourceMetadataCollector rc;
@SuppressWarnings("rawtypes")
DFramedTransactionalGraph graph = this.getGraph(namespace);
String jsonEntity = null;
ResponseBuilder builder = Response.ok();
ParamMap pm = Parameters.toParamMap(uriInfo);
StringWriter sw = new StringWriter();
JsonGraphWriter writer = new JsonGraphWriter(sw, graph, pm, false, true);
// System.out.println("TEMP DEBUG Starting new POST...");
JsonJavaObject jsonItems = null;
JsonGraphFactory factory = JsonGraphFactory.instance;
try {
StringReader reader = new StringReader(requestEntity);
try {
jsonItems = (JsonJavaObject) JsonParser.fromJson(factory, reader);
} finally {
reader.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
if (jsonItems != null) {
Map<CaseInsensitiveString, Object> cisMap = new HashMap<CaseInsensitiveString, Object>();
for (String jsonKey : jsonItems.keySet()) {
CaseInsensitiveString cis = new CaseInsensitiveString(jsonKey);
cisMap.put(cis, jsonItems.get(jsonKey));
}
String rawType = jsonItems.getAsString("@type").trim();
if (rawType != null && rawType.length() > 0) {
try {
Class<?> type = graph.getTypeRegistry().findClassByName(rawType);
if (VertexFrame.class.isAssignableFrom(type)) {
VertexFrame parVertex = (VertexFrame) graph.addVertex(null, type);
try {
JsonFrameAdapter adapter = new JsonFrameAdapter(graph, parVertex, null);
Iterator<String> frameProperties = adapter.getJsonProperties();
while (frameProperties.hasNext()) {
CaseInsensitiveString key = new CaseInsensitiveString(frameProperties.next());
if (!key.startsWith("@")) {
Object value = cisMap.get(key);
if (value != null) {
adapter.putJsonProperty(key.toString(), value);
cisMap.remove(key);
}
} else {
// System.out.println("TEMP DEBUG Skipping property "
// + key);
}
}
if (!cisMap.isEmpty()) {
for (CaseInsensitiveString cis : cisMap.keySet()) {
if (!cis.startsWith("@")) {
Object value = cisMap.get(cis);
if (value != null) {
adapter.putJsonProperty(cis.toString(), value);
}
} else {
// System.out.println("TEMP DEBUG Skipping property "
// + cis);
}
}
}
writer.outObject(parVertex);
} catch (Exception e) {
e.printStackTrace();
}
} else {
// System.out.print("TYPE is not a Vertex and therefore we can't create it through a POST yet.");
}
graph.commit();
} catch (IllegalArgumentException iae) {
throw new RuntimeException(iae);
}
} else {
System.err.println("Cannot POST without an @type in the JSON");
}
} else {
// System.out.println("TEMP DEBUG Nothing to POST. No JSON items found.");
}
jsonEntity = sw.toString();
builder.type(MediaType.APPLICATION_JSON_TYPE).entity(jsonEntity);
Response response = builder.build();
return response;
}
}