view app/models/ClaimModel.java @ 47:9645bfb49603

modified computeAndUpdateStatus
author one
date Thu, 04 Oct 2012 08:55:13 +0900
parents 49aa4ad3008f
children bc35c27966f5
line wrap: on
line source

package models;

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

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(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(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 = Json.newObject();
		property.put(TYPE, Json.toJson(getProperty(TYPE)));
		property.put(STATUS, Json.toJson(getProperty(STATUS)));
		property.put(TOULMIN, Json.toJson(getProperty(TOULMIN)));
		property.put(L_AUTHOR, Json.toJson(getAuthorId()));
		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> getVertex(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 = getVertex(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);
	}
		
	public Object[] getEdgeArray(String... labels) {
		GremlinPipeline<Vertex,Edge> pipe = new GremlinPipeline<Vertex,Edge>();
		pipe.start(vertex).outE(labels);
		ArrayList<Object> array = new ArrayList<Object>();
		for (Edge e : pipe) {
			array.add(e.getId());
		}
		if (array.size() == 0) {
			return null;
		}
		return array.toArray();
	}
	
	public Object[] getRequestEdges() {
		return getEdgeArray(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();
		Graph graph = tpGraph.getGraph();
		long count = 0;
		for (Object eId : requestEdges) {
			Edge e = graph.getEdge(eId);
			String status = e.getProperty(STATUS).toString();
			if (status.equals(checkStatus)) {
				count++;
			}
		}
		return count;
	}
	
	private Boolean checkUnanimously(String childStatus, long requestsNumber, long agreedNumber, long deniedNumber) {
		String preStatus = getProperty(STATUS).toString();
		if ( requestsNumber == agreedNumber && childStatus.equals(PASS)) {
			setProperty(STATUS,PASS);
		} else if ( requestsNumber == deniedNumber && childStatus.equals(FAILED)){
			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 refutationStatus = checkRefutationClaims();
		if (refutationStatus.equals(FAILED)) {
			setProperty(STATUS,FAILED);
			return;
		} else if (refutationStatus.equals(UNKNOWN)) {
			setProperty(STATUS,UNKNOWN);
			return;
		}
		String queAndSugStatus = checkQuestionAndSuggestionClaims();
		if (queAndSugStatus.equals(UNKNOWN)) {
			setProperty(STATUS,UNKNOWN);
			return;
		}
		String childStatus;
		/* refutationStatus == PASS */
		if (refutationStatus.equals(queAndSugStatus)) {
			childStatus = PASS;
		} else { /* queAndSugStatus == FAILED */
			childStatus = FAILED;
		}
		/* 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 statusChanged = false;
		if (type.equals(UNANIMOUSLY)) {
			statusChanged = checkUnanimously(childStatus, requestsNumber, agreedNumber, deniedNumber);
		} else if (type.equals(MAJORITY)) {
			
		} else {
			statusChanged = false;
		}
		if (statusChanged) {
			ClaimModel parentClaim = new ClaimModel(getParentVertex());
			if (parentClaim.getVertex() == null) { // If parentClaim is Root.  
				return;
			}
			parentClaim.computeAndUpdateStatus();			
		}
	}
	
	private String checkQuestionAndSuggestionClaims() {
		Iterable<Vertex> iter = getVertex(Direction.OUT, L_QUESTION, L_SUGGESTION);			
		if (iter == null) {
			return PASS;
		}
		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 checkRefutationClaims() {
		Iterable<Vertex> iter = getVertex(Direction.OUT, L_REFUTATION);
		if (iter == null) {
			return PASS;
		}
		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;
	}
}