view app/models/ClaimModel.java @ 76:41b6f3788cc3 draft

TPGraph wrap graph
author one
date Fri, 08 Mar 2013 16:18:53 +0900
parents 9448734399db
children cddb5ed942a6
line wrap: on
line source

package models;

import java.util.ArrayList;
import java.util.HashSet;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.node.ObjectNode;

import play.libs.Json;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.gremlin.java.GremlinPipeline;

public class ClaimModel extends NodeModel {

	public ClaimModel(Vertex vertex) {
		super(vertex);
	}

	public void setClaimProperties(JsonNode toulmin, String type) {
		String title = toulmin.findPath(TITLE).getTextValue();
		String contents = toulmin.findPath(CONTENTS).getTextValue();
		String q = toulmin.findPath(QUALIFIER).getTextValue(); // Qualifier
		String d = toulmin.findPath(DATA).getTextValue(); // Data
		String w = toulmin.findPath(WARRANT).getTextValue(); // Warrant
		String b = toulmin.findPath(BACKING).getTextValue(); // Backing
		String r = toulmin.findPath(REBUTTLE).getTextValue(); // Rebuttle
		ObjectNode t = Json.newObject();
		t.put(TITLE, title);
		t.put(CONTENTS, contents);
		t.put(QUALIFIER, q);
		t.put(DATA, d);
		t.put(WARRANT, w);
		t.put(BACKING, b);
		t.put(REBUTTLE, r);
		if (type == null) {
			setProperty(TYPE, UNANIMOUSLY);
		} else {
			setProperty(TYPE, type);
		}
		if (getProperty(STATUS) == null) {
			setProperty(STATUS, UNKNOWN); // Default Status is unknown.
		}
		setProperty(TIMESTAMP, Long.toString(System.currentTimeMillis()));
		setProperty(TOULMIN, t);
	}

	public ObjectNode getSimpleClaimInfo() {
		ObjectNode property = Json.newObject();
		property.put(TYPE, Json.toJson(getProperty(TYPE)));
		property.put(STATUS, Json.toJson(getProperty(STATUS)));
        property.put(TIMESTAMP, Json.toJson(getProperty(TIMESTAMP)));
        property.put(TOULMIN, Json.toJson(getProperty(TOULMIN)));
		property.put(L_AUTHOR, Json.toJson(getAuthorId()));
		property.put(MENTIONS, Json.toJson(getMentionsId()));
		property.put(USERS, Json.toJson(getUsersId()));
		return property;
	}

	public ObjectNode getClaimInfoTraverse() {
		ObjectNode property = getSimpleClaimInfo();
		property.put(MENTIONS, Json.toJson(getClaimMentionsRecursive()));
		property.put(USERS, Json.toJson(getUsersIdAndStatus()));
		return property;
	}

	public Object[] getClaimMentionsRecursive() {
		GremlinPipeline<Vertex, Edge> pipe = new GremlinPipeline<Vertex, Edge>();
		pipe.start(vertex).outE(L_QUESTION, L_REFUTATION, L_SUGGESTION);
		ArrayList<Object> array = new ArrayList<Object>();
		for (Edge e : pipe) {
			String label = e.getLabel();
			ObjectNode info = Json.newObject();
			info.put(TYPE, Json.toJson(label));
			GremlinPipeline<Edge, Vertex> pipeChildVertex = new GremlinPipeline<Edge, Vertex>();
			pipeChildVertex.start(e).inV();
			ClaimModel childClaim = new ClaimModel(pipeChildVertex.next());
			info.put(CLAIM, childClaim.getClaimInfoTraverse());
			info.put(ID, Json.toJson(childClaim.getId()));
			array.add(info);
		}
		return array.toArray();
	}

	private Iterable<Vertex> getVertexIterable(Direction direction,
			String... labels) {
		GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
		if (direction.equals(Direction.IN)) {
			pipe.start(vertex).in(labels);
		} else if (direction.equals(Direction.OUT)) {
			pipe.start(vertex).out(labels);
		} else {
			pipe.start(vertex).both(labels);
		}
		ArrayList<Vertex> array = new ArrayList<Vertex>();
		for (Vertex v : pipe) {
			array.add(v);
		}
		if (array.size() == 0) {
			return null;
		}
		return array;
	}

	private Object[] getVertexArray(Direction direction, String... labels) {
		Iterable<Vertex> iter = getVertexIterable(direction, labels);
		if (iter == null) {
			return null;
		}
		ArrayList<Object> array = new ArrayList<Object>();
		for (Vertex v : iter) {
			array.add(v.getId());
		}
		return array.toArray();
	}

	public Object[] getMentionsId() {
		return getVertexArray(Direction.OUT, L_QUESTION, L_REFUTATION,
				L_SUGGESTION);
	}

	public Object[] getUsersId() {
		return getVertexArray(Direction.OUT, L_REQUEST);
	}

	private Iterable<Edge> getEdgeIterable(Direction direction,
			String... labels) {
		GremlinPipeline<Vertex, Edge> pipe = new GremlinPipeline<Vertex, Edge>();
		if (direction.equals(Direction.IN)) {
			pipe.start(vertex).inE(labels);
		} else if (direction.equals(Direction.OUT)) {
			pipe.start(vertex).outE(labels);
		} else {
			pipe.start(vertex).bothE(labels);
		}
		ArrayList<Edge> array = new ArrayList<Edge>();
		for (Edge v : pipe) {
			array.add(v);
		}
		if (array.size() == 0) {
			return null;
		}
		return array;
	}

	public Object[] getEdgeArray(Direction direction, String... labels) {
		Iterable<Edge> iter = getEdgeIterable(direction, labels);
		/*
		 * GremlinPipeline<Vertex,Edge> pipe = new
		 * GremlinPipeline<Vertex,Edge>(); pipe.start(vertex).outE(labels);
		 */
		ArrayList<Object> array = new ArrayList<Object>();
		for (Edge e : iter) {
			array.add(e.getId());
		}
		if (array.size() == 0) {
			return null;
		}
		return array.toArray();
	}

	public Object[] getRequestEdges() {
		return getEdgeArray(Direction.OUT, L_REQUEST);
	}

	public ObjectNode getUserRequestStatus(UserModel user) {
		GremlinPipeline<Vertex, Edge> pipeEdge = new GremlinPipeline<Vertex, Edge>();
		pipeEdge.start(vertex).outE(L_REQUEST);
		ObjectNode info = Json.newObject();
		for (Edge e : pipeEdge) {
			GremlinPipeline<Edge, Vertex> pipeChildVertex = new GremlinPipeline<Edge, Vertex>();
			pipeChildVertex.start(e).inV();
			Vertex childVertex = pipeChildVertex.next();
			if (childVertex.getId() == user.getId()) {
				info.put(STATUS, Json.toJson(e.getProperty(STATUS)));
				break;
			}
		}
		return info;
	}

	public Boolean updateUserRequestStatus(ClaimModel claim, UserModel user,
			String status) {
		GremlinPipeline<Vertex, Edge> pipeEdge = new GremlinPipeline<Vertex, Edge>();
		pipeEdge.start(vertex).outE(L_REQUEST);
		for (Edge e : pipeEdge) {
			GremlinPipeline<Edge, Vertex> pipeChildVertex = new GremlinPipeline<Edge, Vertex>();
			pipeChildVertex.start(e).inV();
			Vertex childVertex = pipeChildVertex.next();
			if (childVertex.getId() == user.getId()) {
				e.setProperty(STATUS, status);
				break;
			}
		}
		return true;
	}

	public Object[] getUsersIdAndStatus() {
		GremlinPipeline<Vertex, Edge> pipeEdge = new GremlinPipeline<Vertex, Edge>();
		pipeEdge.start(vertex).outE(L_REQUEST);
		ArrayList<Object> array = new ArrayList<Object>();
		for (Edge e : pipeEdge) {
			GremlinPipeline<Edge, Vertex> pipeChildVertex = new GremlinPipeline<Edge, Vertex>();
			ObjectNode info = Json.newObject();
			pipeChildVertex.start(e).inV();
			Vertex childVertex = pipeChildVertex.next();
			info.put(ID, Json.toJson(childVertex.getId()));
			info.put(STATUS, Json.toJson(e.getProperty(STATUS)));
			array.add(info);
		}
		return array.toArray();
	}

	public Object[] getRequestUsersId() {
		return getVertexArray(Direction.OUT, NodeModel.REQUESTS);
	}

	public void editRequestsEdgeUsers(Object[] updateUsers) {
		TPGraph tpGraph = TPGraph.getInstance();
		Object[] currentUsers = getUsersId();
		HashSet<Object> currentUsersHashSet = new HashSet<Object>();
		for (Object u : currentUsers) {
			currentUsersHashSet.add(u);
		}
		for (Object updateUser : updateUsers) {
			if (currentUsersHashSet.contains(updateUser)) {
				currentUsersHashSet.remove(updateUser);
			} else {
				tpGraph.setLabelStatusToUser(this, updateUser.toString(),
						L_REQUEST, UNKNOWN);
			}
		}
		tpGraph.deleteRequestEdge(this, currentUsersHashSet);
	}

	public Object getAuthorId() {
		GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
		pipe.start(vertex).out(L_AUTHOR);
		if (!pipe.hasNext()) {
			return null;
		}
		Vertex authorV = pipe.next();
		return authorV.getId();
	}

	public long getAgreedNumber(Object[] requestEdges) {
		return getEdgeStatusNumber(requestEdges, AGREED);
	}

	public long getDeninedNumber(Object[] requestEdges) {
		return getEdgeStatusNumber(requestEdges, DENIED);
	}

	public long getDeniedNumber(Object[] requestEdges) {
		return getEdgeStatusNumber(requestEdges, DENIED);
	}

	private long getEdgeStatusNumber(Object[] requestEdges, String checkStatus) {
		TPGraph tpGraph = TPGraph.getInstance();
		long count = 0;
		for (Object eId : requestEdges) {
			Edge e = tpGraph.getEdge(eId);
			String status = e.getProperty(STATUS).toString();
			if (status.equals(checkStatus)) {
				count++;
			}
		}
		return count;
	}

	private Boolean checkUnanimously(String inverseRefutationStatus,
			String questionsStatus, long requestsNumber, long agreedNumber,
			long deniedNumber) {
		String preStatus = getProperty(STATUS).toString();
		if (inverseRefutationStatus == null && questionsStatus == null) {
			if (requestsNumber == agreedNumber) {
				setProperty(STATUS, PASS);
			} else if (requestsNumber == deniedNumber) {
				setProperty(STATUS, FAILED);
			} else {
				setProperty(STATUS, UNKNOWN);
			}
		} else if (inverseRefutationStatus == null && questionsStatus != null) {
			if (requestsNumber == agreedNumber && questionsStatus.equals(PASS)) {
				setProperty(STATUS, PASS);
			} else if (requestsNumber == deniedNumber
					&& questionsStatus.equals(FAILED)) {
				setProperty(STATUS, FAILED);
			} else {
				setProperty(STATUS, UNKNOWN);
			}
		} else if (inverseRefutationStatus != null & questionsStatus == null) {
			if (requestsNumber == agreedNumber && inverseRefutationStatus.equals(PASS)) {
				setProperty(STATUS, PASS);
			} else if (requestsNumber == deniedNumber
					&& inverseRefutationStatus.equals(FAILED)) {
				setProperty(STATUS, FAILED);
			} else {
				setProperty(STATUS, UNKNOWN);
			}
		}else if (inverseRefutationStatus != null & questionsStatus != null) {
			String childStatus = UNKNOWN;
			if (inverseRefutationStatus.equals(questionsStatus)) {
				childStatus = inverseRefutationStatus;
			}
			if ( requestsNumber == agreedNumber &&childStatus.equals(PASS) ){
				setProperty(STATUS, PASS);
			} else if ( requestsNumber == deniedNumber && childStatus.equals(DENIED)) {
				setProperty(STATUS, FAILED);
			} else {
				setProperty(STATUS, UNKNOWN);	
			}
		}
		String nowStatus = getProperty(STATUS).toString();
		return nowStatus.equals(preStatus);
	}

	private Boolean checkMajority(long requestsNumber, long agreedNumber,
			long deniedNumber) {
		// TODO
		return false;
	}

	public void computeAndUpdateStatus() {
		/* Check child claim */
		String inverseRefutationStatus = checkRefutationClaims();
		String questionsStatus = checkQuestionClaims();
		/* Check user request status */
		Object[] requestEdges = getRequestEdges();
		String type = getProperty(TYPE).toString();
		long requestsNumber = requestEdges.length;
		long agreedNumber = getAgreedNumber(requestEdges);
		long deniedNumber = getDeninedNumber(requestEdges);
		Boolean notChanged = false;
		if (type.equals(UNANIMOUSLY)) {
			notChanged = checkUnanimously(inverseRefutationStatus,
					questionsStatus, requestsNumber, agreedNumber, deniedNumber);
		} else if (type.equals(MAJORITY)) {
			/* !!!  !!! */
			notChanged = checkUnanimously(inverseRefutationStatus,
					questionsStatus, requestsNumber, agreedNumber, deniedNumber);
		} else {
			notChanged = false;
		}
		if (notChanged) {
			return;
		}
		ClaimModel parentClaim = new ClaimModel(getParentVertex());
		if (parentClaim.getVertex() == null) { // If parentClaim is Root.
			return;
		}
		parentClaim.computeAndUpdateStatus();
	}
	
	private String checkClaims(Direction direction, String... labels) {
		Iterable<Vertex> iter = getVertexIterable(direction, labels);
		if (iter == null) {
			return null;
		}
		String status = null;
		for (Vertex v : iter) {
			String nextChildStatus = v.getProperty(STATUS).toString();
			if (status == null) {
				status = nextChildStatus;
			}
			if (!nextChildStatus.equals(status)) {
				return UNKNOWN;
			}
		}
		return status;
	}

	private String checkQuestionClaims() {
		return checkClaims(Direction.OUT, L_QUESTION);		
	}
	
	private String checkQuestionAndSuggestionClaims() {
		return checkClaims(Direction.OUT, L_QUESTION, L_SUGGESTION);
	}

	private String checkRefutationClaims() {
		Iterable<Vertex> iter = getVertexIterable(Direction.OUT, L_REFUTATION);
		if (iter == null) {
			return null;
		}
		String status = null;
		for (Vertex v : iter) {
			String childStatus = v.getProperty(STATUS).toString();
			if (status == null) {
				status = childStatus;
			}
			if (status.equals(PASS)) {
				return FAILED;
			} else if (!status.equals(childStatus)) {
				status = UNKNOWN;
			}
		}
		if (status.equals(FAILED)) {
			return PASS;
		}
		return UNKNOWN;
	}

	private String checkAllChildsStatus() {
		String queAndSugStatus = checkQuestionAndSuggestionClaims();
		String refutationStatus = checkRefutationClaims();
		if (refutationStatus.equals(FAILED)) {
			return FAILED;
		} else if (refutationStatus.equals(queAndSugStatus)) {
			return queAndSugStatus;
		} else {
			return UNKNOWN;
		}
	}

	private Vertex getParentVertex() {
		GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
		pipe.start(vertex).in(L_QUESTION, L_REFUTATION, L_SUGGESTION);
		if (pipe.hasNext()) {
			return pipe.next();
		}
		return null;
	}

	private void copyRequestEdges(ClaimModel newClaim) {
		TPGraph tpGraph = TPGraph.getInstance();
		Iterable<Edge> reqEdges = getEdgeIterable(Direction.OUT, L_REQUEST);
		for (Edge e : reqEdges) {
			Vertex userVertex = e.getVertex(Direction.IN);
			String userName = (userVertex.getId()).toString();
			String status = (e.getProperty(STATUS)).toString();
			tpGraph.setLabelStatusToUser(newClaim, userName, L_REQUEST, status);
		}
	}
	
	public ClaimModel clone() {
		TPGraph tpGraph = TPGraph.getInstance();
		ClaimModel newClaim = new ClaimModel(tpGraph.addVertex(null));
		String author = (getAuthorId()).toString();
		String type = (this.getProperty(TYPE)).toString();
		JsonNode toulmin = (JsonNode)this.getProperty(TOULMIN);
		newClaim.setClaimProperties(toulmin, type);
		tpGraph.setLabelToAuthor(newClaim, author);
		copyRequestEdges(newClaim);
		return newClaim;
	}
	
	public ClaimModel cloneAndSetLabelPrev() {
		ClaimModel newClaim = this.clone();
		TPGraph tpGraph = TPGraph.getInstance();
		tpGraph.setLabelPrev(newClaim, this);
		return newClaim;
	}
	
	
	
}