view app/models/ClaimModel.java @ 50:d6c623e92837

modified routes
author one
date Thu, 04 Oct 2012 16:14:30 +0900
parents 36ddbd5e5d45
children f3db6edc61ad
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> 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();
		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 inverseRefutationStatus, String queAndSugStatus, long requestsNumber, long agreedNumber, long deniedNumber) {
		String preStatus = getProperty(STATUS).toString();
		if ( inverseRefutationStatus == null && queAndSugStatus == null) {
			if (requestsNumber == agreedNumber) {
				setProperty(STATUS, PASS);
			} else if (requestsNumber == deniedNumber) {
				setProperty(STATUS, FAILED);			
			} else {
				setProperty(STATUS, UNKNOWN);		
			}
		} else if (inverseRefutationStatus != null && queAndSugStatus == null) {
			if (inverseRefutationStatus.equals(FAILED)) {
				setProperty(STATUS, FAILED);
			} else if (requestsNumber == agreedNumber && inverseRefutationStatus.equals(PASS)) {
				setProperty(STATUS, PASS);
			} else {
				setProperty(STATUS, UNKNOWN);			
			}
		} else if (inverseRefutationStatus == null && queAndSugStatus != null) {
			if (requestsNumber == agreedNumber && queAndSugStatus.equals(PASS)) {
				setProperty(STATUS, PASS);
			} else if (requestsNumber == deniedNumber && queAndSugStatus.equals(FAILED)) {
				setProperty(STATUS, FAILED);			
			}			
		} else if (inverseRefutationStatus.equals(queAndSugStatus)){
			setProperty(STATUS, inverseRefutationStatus);						
		} 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 queAndSugStatus = checkQuestionAndSuggestionClaims();
		/* 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, queAndSugStatus, requestsNumber, agreedNumber, deniedNumber);
		} else if (type.equals(MAJORITY)) {
			
		} else {
			notChanged = false;
		}
		if (notChanged) {
			return;
		}
		ClaimModel parentClaim = new ClaimModel(getParentVertex());
		if (parentClaim.getVertex() == null) { // If parentClaim is Root.  
			return;
		}
		parentClaim.computeAndUpdateStatus();			
	}
	
	private String checkQuestionAndSuggestionClaims() {
		Iterable<Vertex> iter = getVertexIterable(Direction.OUT, L_QUESTION, L_SUGGESTION);			
		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 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;
	}
}