package org.arangodb.objectmapper; ////////////////////////////////////////////////////////////////////////////////////////// // // Object mapper for ArangoDB by triAGENS GmbH Cologne. // // Copyright triAGENS GmbH Cologne. // ////////////////////////////////////////////////////////////////////////////////////////// import java.util.Iterator; import org.arangodb.objectmapper.http.ArangoDbHttpResponse; import org.arangodb.objectmapper.http.ResponseCallback; import org.arangodb.objectmapper.jackson.ArangoDbDocument; import org.apache.log4j.Logger; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; public class Cursor<T extends ArangoDbDocument> implements Iterator<T> { /** * the logger */ private static Logger LOG = Logger .getLogger(Cursor.class); /** * the cursor api path */ public final static String CURSOR_PATH = "/_api/cursor"; /** * the ArangoDB database */ private final Database database; /** * the class value type */ private final Class<T> valueType; /** * the cached results */ private ArrayNode resultNode = null; /** * has more results property */ private boolean hasNext = false; /** * cursor identifier */ private String id = ""; /** * next result */ private int index = 0; /** * count result */ private int count = 0; /** * Creates cursor * * @param database the ArangoDB database * @param query the query */ public Cursor (Database database, final ArangoDbQuery<T> query) { this.database = database; this.valueType = query.getValueType(); try { setValues(createCursor(query)); } catch (ArangoDb4JException e) { e.printStackTrace(); } } /** * returns true, if there a more results * * @return true, if there are more results */ public boolean hasNext () { if (null == resultNode) { return false; } if (index < resultNode.size()) { return true; } if (hasNext) { // get more results from the server try { setValues(updateCursor(id)); } catch (ArangoDb4JException e) { LOG.error("Cursor update failed!: " + e); e.printStackTrace(); setValues(null); } if (index < resultNode.size()) { return true; } } return false; } /** * returns the next result * * @return Object */ public T next () { if (hasNext()) { try { return database.getSerializer().toObject(resultNode.get(index++), valueType); } catch (ArangoDb4JException e) { e.printStackTrace(); } } return null; } /** * updates the state * * @param root the cursor root node * * @return true, if the state was updated successfully */ private boolean setValues (JsonNode root) { if (root == null) { hasNext = false; id = ""; index = 0; count = 0; return false; } if (root.has("result")) { JsonNode jn = root.get("result"); if (jn.isArray()) { resultNode = (ArrayNode)jn; } } if (root.has("hasMore")) { hasNext = root.get("hasMore").asBoolean(); } if (root.has("id")) { id = root.get("id").asText(); } if (root.has("count")) { count = root.get("count").asInt(); } index = 0; return true; } /** * deletes the cursor on the server */ public void remove () { if (! hasNext()) { return; } try { deleteCursor(id); } catch (ArangoDb4JException e) { } resultNode = null; hasNext = false; id = ""; index = 0; } /** * Returns the count value */ public int count() { return this.count; } private JsonNode createCursor (final ArangoDbQuery<T> query) throws ArangoDb4JException { String body = database.getSerializer().toJson(query.getAsMap()); //System.out.println(body); return database.getRestHandler().post(database.buildPath(CURSOR_PATH), body, new ResponseCallback<JsonNode>() { @Override public JsonNode success(ArangoDbHttpResponse hr) throws ArangoDb4JException { return database.getSerializer().toJsonNode(hr.getContentAsStream()); } }); } private JsonNode updateCursor (String id) throws ArangoDb4JException { return database.getRestHandler().put(database.buildPath(CURSOR_PATH) + "/" + id, "", new ResponseCallback<JsonNode>() { @Override public JsonNode success(ArangoDbHttpResponse hr) throws ArangoDb4JException { return database.getSerializer().toJsonNode(hr.getContentAsStream()); } }); } private void deleteCursor (String id) throws ArangoDb4JException { if (! id.equals("")) { database.getRestHandler().delete(database.buildPath(CURSOR_PATH) + id); } } }