view src/nabble/view/web/template/NodeList.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.view.web.template;

import fschmidt.util.java.Filter;
import nabble.model.ModelHome;
import nabble.model.Node;
import nabble.model.NodeIterator;
import nabble.model.NodeSearcher;
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.Namespace;
import nabble.naml.compiler.ScopedInterpreter;
import nabble.naml.namespaces.ListSequence;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;


@Namespace (
	name = "node_list",
	global = true
)
public final class NodeList extends ListSequence<Node> {

	static void subapps(IPrintWriter out,ScopedInterpreter<NodeList> interp,Node loopNode,String filter) {
		List<Node> nodes = loopNode.getChildApps(filter).get(0, 100);
		NodeList loop = new NodeList(nodes, loopNode, false);
		Object block = interp.getArg(loop,"do");
		out.print(block);
	}

	static void descendantApps(IPrintWriter out,ScopedInterpreter<NodeList> interp,Node loopNode) {
		List<Node> nodes = loopNode.getDescendantApps().get(0, 1000);
		NodeList loop = new NodeList(nodes, loopNode, false);
		Object block = interp.getArg(loop,"do");
		out.print(block);
	}

	static void ancestors(IPrintWriter out,ScopedInterpreter<NodeList> interp,Node loopNode,String order) {
		Node parent = loopNode.getParent();
		List<Node> nodes = parent != null? parent.getAncestors().get(0, 1000) : Collections.<Node>emptyList();
		if ("reverse".equalsIgnoreCase(order) && nodes.size() > 1)
			Collections.reverse(nodes);
		NodeList loop = new NodeList(nodes, loopNode, false);
		Object block = interp.getArg(loop,"do");
		out.print(block);
	}

	private static boolean hasMore(List<Node> nodes,int size) {
		if( nodes.size() <= size )
			return false;
		nodes.remove(size);
		return true;
	}

	public static void children(IPrintWriter out,ScopedInterpreter<NodeList> interp,Node loopNode,NodeIterator<? extends Node> nodeIter,int indexRecord,int length) {
		List<Node> nodes = nodeIter.get(indexRecord, length+1);
		boolean hasMore = hasMore(nodes,length);
		NodeList loop = new NodeList(nodes, loopNode, hasMore);
		Object block = interp.getArg(loop,"do");
		out.print(block);
	}

	public static void topics(IPrintWriter out,ScopedInterpreter<NodeList> interp,Node loopNode,NodeIterator<? extends Node> nodeIter,int indexRecord,int length) {
		List<Node> nodes = nodeIter.get(indexRecord, length+1);
		boolean hasMore = hasMore(nodes,length);
		NodeList loop = new NodeList(nodes, loopNode, hasMore);
		Object block = interp.getArg(loop,"do");
		out.print(block);
	}

	public static void posts(IPrintWriter out,ScopedInterpreter<NodeList> interp,Node loopNode,int indexRecord,int length,String sortBy,Filter<Node> filter) {
		List<Node> nodes;
		if ("date-ascending".equals(sortBy)) {
			nodes = loopNode.getPostsByDateAscending(filter).get(indexRecord, length+1);
		} else if ("date-descending".equals(sortBy)) {
			nodes = loopNode.getPostsByDate(filter).get(indexRecord, length+1);
		} else {
			throw new RuntimeException("'sort' attribute not set");
		}
		boolean hasMore = hasMore(nodes,length);
		NodeList loop = new NodeList(nodes, loopNode, hasMore);
		Object block = interp.getArg(loop,"do");
		out.print(block);
	}

	static void userNodes(IPrintWriter out,ScopedInterpreter<NodeList> interp, NodeIterator<? extends Node> nodeIter, int indexRecord,int length) {
		List<Node> nodes = nodeIter.get(indexRecord,length+1);
		boolean hasMore = hasMore(nodes,length);
		NodeList loop = new NodeList(nodes, null, hasMore);
		Object block = interp.getArg(loop,"do");
		out.print(block);
	}


	private final Node loopNode;
	private final boolean hasMore;

	/**
	 * Cache the lastNodes to prevent them from being
	 * garbage collected so that there aren't multiple
	 * database accesses.  This is an optimization.
	 */
	private final Collection<Node> lastNodes;

	public NodeList(List<Node> nodes, Node loopNode,boolean hasMore) {
		super(nodes);
		this.loopNode = loopNode;
		this.hasMore = hasMore;
		lastNodes = NabbleNamespace.current().site().cacheLastNodes(nodes);
	}

	public static final CommandSpec preload_messages = CommandSpec.NO_OUTPUT;

	@Command public void preload_messages(IPrintWriter out,Interpreter interp) {
		ModelHome.preloadMessages(elements);
	}

	@Command public void there_is_more(IPrintWriter out,Interpreter interp) {
		out.print( hasMore );
	}

	@Command public void has_loop_node(IPrintWriter out,Interpreter interp) {
		out.print( loopNode != null );
	}

	public static final CommandSpec loop_node = CommandSpec.DO;

	@Command public void loop_node(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) {
 		out.print( interp.getArg(new NodeNamespace(loopNode),"do") );
	}

	public static final CommandSpec current_node = CommandSpec.DO;

	@Command public void current_node(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) {
		NodeNamespace row = new NodeNamespace(get());
		Object block = interp.getArg(row,"do");
		out.print(block);
	}

	public static final CommandSpec node_at = CommandSpec.DO()
		.parameters("index")
		.build()
	;

	@Command public void node_at(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) {
		int index = interp.getArgAsInt("index");
		NodeNamespace row = new NodeNamespace(elements.get(index));
		Object block = interp.getArg(row,"do");
		out.print(block);
	}

	@Command public void next_node(IPrintWriter out,Interpreter interp) {
		next_element(out,interp);
	}

	@Command public void has_previous_node(IPrintWriter out,Interpreter interp) {
		out.print( getPrevious() != null );
	}

	public static final CommandSpec previous_node = CommandSpec.DO;

	@Command public void previous_node(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) {
		NodeNamespace row = new NodeNamespace(getPrevious());
		Object block = interp.getArg(row,"do");
		out.print(block);
	}

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

	@Command public void sub_list(IPrintWriter out,ScopedInterpreter<NodeList> interp) {
		int start = interp.getArgAsInt("start",0);
		int length = interp.getArgAsInt("length");
		NodeList ns ;
		if( start==0 && length >= elements.size() ) {
			ns = this;
		} else {
			ns = new NodeList( elements.subList(start,Math.min(elements.size(),start+length)), loopNode, false );
		}
		out.print( interp.getArg(ns,"do") );
	}

}