view src/nabble/modules/workgroup/NodeNamespaceExt.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
line wrap: on
line source

package nabble.modules.workgroup;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.NoSuchElementException;
import javax.servlet.ServletException;
import fschmidt.util.java.Filter;
import fschmidt.util.java.Stack;
import fschmidt.util.java.ArrayStack;
import nabble.model.Db;
import nabble.model.ModelHome;
import nabble.model.Node;
import nabble.model.NodeIterator;
import nabble.model.Site;
import nabble.model.DbParamSetter;
import nabble.model.User;
import nabble.naml.compiler.Command;
import nabble.naml.compiler.CommandSpec;
import nabble.naml.compiler.IPrintWriter;
import nabble.naml.compiler.Interpreter;
import nabble.naml.compiler.NamespaceExtension;
import nabble.naml.compiler.ScopedInterpreter;
import nabble.view.web.template.NodeList;
import nabble.view.web.template.NodeNamespace;
import nabble.view.web.template.ServletNamespace;
import nabble.view.web.template.UserNamespace;


@NamespaceExtension (
	name = "workgroup_node",
	target = NodeNamespace.class
)
public final class NodeNamespaceExt {
	private final NodeNamespace ns;
	private final Node node;
	private final Site site;

	public NodeNamespaceExt(NodeNamespace ns) {
		this.ns = ns;
		this.node = ns.node();
		this.site = node.getSite();
	}

	private static Integer priority(Interpreter interp) {
		String priorityS = interp.getArgString("priority");
		return priorityS == null ? null : Integer.valueOf(priorityS);
	}

	private User assignee(Interpreter interp) {
		String assigneeS = interp.getArgString("assignee");
		return assigneeS == null || "0".equals(assigneeS) ? null : node.getSite().getUser(Long.valueOf(assigneeS));
	}

	public static final CommandSpec assignment_filter = new CommandSpec.Builder()
		.parameters("assignee","priority")
		.build()
	;

	@Command public void assignment_filter(IPrintWriter out,Interpreter interp) {
		Integer priority = priority(interp);
		out.print( ModelHome.assignmentCondition(assignee(interp), priority == null? null : priority == 0? 5 : priority) );
	}

	@Command public void is_assigned(IPrintWriter out,Interpreter interp) {
		out.print( Assignment.of(node) != null );
	}

	@Command public void priority(IPrintWriter out,Interpreter interp) {
		out.print( Assignment.of(node).priority );
	}

	public static final CommandSpec assignee = CommandSpec.DO;

	@Command public void assignee(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) {
		out.print( interp.getArg(new UserNamespace(Assignment.of(node).assignee),"do") );
	}

	public static final CommandSpec unassign = CommandSpec.NO_OUTPUT;

	@Command public void unassign(IPrintWriter out,Interpreter interp) {
		Assignment.unassign(node);
	}

	public static final CommandSpec assign = CommandSpec.NO_OUTPUT()
		.parameters("assignee","priority")
		.build()
	;

	@Command public void assign(IPrintWriter out,Interpreter interp) {
		UserNamespace userNs = interp.getArgAsNamespace(UserNamespace.class,"assignee");
		User assignee = userNs.user();
		int priority = interp.getArgAsInt("priority");
		new Assignment(node,assignee,priority).save();
	}

	public static final CommandSpec children_list_by_priority = CommandSpec.DO()
		.parameters("length")
		.optionalParameters("start", "filter")
		.build()
	;

	@Command public void children_list_by_priority(IPrintWriter out,ScopedInterpreter<NodeList> interp) {
		int start = NodeNamespace.getLoopStart(interp);
		int length = NodeNamespace.getLoopLength(interp);
		String filter = interp.getArgString("filter");
		NodeIterator<? extends Node> nodeIter = getChildrenByPriority(filter);
		NodeList.children(out,interp,node,nodeIter,start,length);
	}

	public static final CommandSpec topics_list_by_priority = CommandSpec.DO()
		.parameters("length")
		.optionalParameters("start","filter")
		.requiredInStack(ServletNamespace.class)
		.build()
	;

	@Command public void topics_list_by_priority(IPrintWriter out,ScopedInterpreter<NodeList> interp)
		throws ServletException
	{
		int start = NodeNamespace.getLoopStart(interp);
		int length = NodeNamespace.getLoopLength(interp);
		String filter = interp.getArgString("filter");
		NodeIterator<Node> nodeIter = getTopicsByPriority(filter,ns.filter(interp));
		NodeList.topics(out,interp,node,nodeIter,start,length);
	}


	private static final class PriorityNode implements Comparable<PriorityNode> {
		final long nodeId;
		final int priority;
		final long lastNodeDate;

		PriorityNode(ResultSet rs) throws SQLException {
			nodeId = rs.getLong("node_id");
			priority = rs.getInt("assigned_priority");
			lastNodeDate = rs.getTimestamp("last_node_date").getTime();
		}

		public int compareTo(PriorityNode pn) {
			int diff = priority - pn.priority;
			return diff != 0 ? diff
				: lastNodeDate < pn.lastNodeDate ? -1
				: lastNodeDate > pn.lastNodeDate ? 1
				: 0
			;
		}
	}

	private static class NodePriorityIterator extends NodeIterator<Node> {
		private final Site site;
		private final List<PriorityNode> list;
		private int next = 0;

		NodePriorityIterator(Site site,List<PriorityNode> list) {
			this.site = site;
			this.list = list;
		}

		public void skip(int n) {
			next += n;
		}

		public boolean hasNext() {
			return next < list.size();
		}

		public Node next() throws NoSuchElementException {
			return site.getNode(list.get(next++).nodeId);
		}

		public void close() {}
	}

	private NodeIterator<Node> getTopicsByPriority(String cnd,Filter<Node> filter) {
		if( node.getKind() != Node.Kind.APP )
			return NodeIterator.empty();
		List<PriorityNode> list = new ArrayList<PriorityNode>();
		try {
			Connection con = site.getDb().getConnection();
			PreparedStatement pstmtTopics = con.prepareStatement(
				"select node_id, assigned_priority, last_node_date from node where parent_id = ? and is_app is null" + (cnd==null ? "" : " and " + cnd)
			);
			PreparedStatement pstmtApps = con.prepareStatement(
				"select * from node where parent_id = ? and is_app"
			);
			Stack<Long> stack = new ArrayStack<Long>();
			stack.push(node.getId());
			do {
				long nodeId = stack.pop();
				pstmtTopics.setLong(1,nodeId);
				ResultSet rs = pstmtTopics.executeQuery();
				while( rs.next() ) {
					list.add( new PriorityNode(rs) );
				}
				rs.close();
				pstmtApps.setLong(1,nodeId);
				rs = pstmtApps.executeQuery();
				while( rs.next() ) {
					Node node = site.getNode(rs);
					if( filter.ok(node) )
						stack.push( node.getId() );
				}
				rs.close();
			} while( !stack.isEmpty() );
			con.close();
		} catch(SQLException e) {
			throw new RuntimeException(e);
		}
		Collections.sort(list);
		return new NodePriorityIterator(site,list);
	}


	public NodeIterator<? extends Node> getChildrenByPriority(String cnd) {
		if( !node.isInDb() ) {
/*
			List<Node> children = dummyChildMap.get(this);
			if( children == null )
				return NodeIterator.empty();
			return NodeIterator.nodeIterator( children.iterator() );
*/
			throw new RuntimeException();
		}
		return site.getNodeIterator(
				"select *"
				+" from node"
				+" where parent_id = ?"
				+(cnd==null?"":"and " + cnd)
				+" order by assigned_priority, last_node_date, node_id"
			,
				new DbParamSetter() {
					public void setParams(PreparedStatement stmt) throws SQLException {
						stmt.setLong(1, node.getId());
					}
				}
		);
	}

}