All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.odysz.semantic.DA.TreeIndenode Maven / Gradle / Ivy

package io.odysz.semantic.DA;

import static io.odysz.common.LangExt.len;
import static io.odysz.common.LangExt.isNull;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import io.odysz.anson.Anson;
import io.odysz.anson.AnsonField;
import io.odysz.anson.JsonOpt;
import io.odysz.anson.x.AnsonException;

/**
 * Tree node supporting indent for rendering tree structure.
 * 
 * TODO to be moved to Semantic.DA
 * 
 * @author Ody Z
 *
 */
public class TreeIndenode extends Anson {
	@Override
	public Anson toBlock(OutputStream stream, JsonOpt... opts)
			throws AnsonException, IOException {
		indents();
		return super.toBlock(stream, opts);
	}

	HashMap node;
	String id;
	String parentId;
	
	@AnsonField(ref=AnsonField.enclosing)
	TreeIndenode parent;

	ArrayList indents;

	// Only for Anson parser
	public TreeIndenode() { }

	public TreeIndenode(String id, TreeIndenode... parent) {
		this.id = id;
		this.parentId = len(parent) > 0 ? parent[0].id : null;
		this.parent   = len(parent) > 0 ? parent[0] : null;
		node = new HashMap();
	}
	
	public ArrayList getChildIndents() {
		ArrayList indents = indents();
		ArrayList ret = new ArrayList(indents);

		if (len(ret) > 0) {
			ret.remove(ret.size() - 1);
			if (lastSibling)
				ret.add(IndentFlag.space);
			else
				ret.add(IndentFlag.vlink);
		}
		return ret;
	}

	public ArrayList indents() {
		if (indents == null && parent != null) {
			indents = parent.getChildIndents();

			if (lastSibling) 
				indents.add(IndentFlag.childx);
			else
				indents.add(IndentFlag.childi);
		}
		if (indents == null)
			indents = new ArrayList();
		return indents;
	}

	public TreeIndenode put(String k, Object v) {
		node.put(k, v);
		return this;
	}

	public Object get(String k) {
		return node == null ? null : node.get(k);
	}

	public String id() { return id; }
	public String parent() { return parentId; }
	public String fullpath() { 
		return node == null ? null : (String) node.get("fullpath");
	}

	public List children() {
		return node == null ? null : (List) node.get("children");
	}

	public Object child(int cx) {
		return node == null ? null : ((List) node.get("children")).get(cx);
	}

	public TreeIndenode child(TreeIndenode ch) {
		@SuppressWarnings("unchecked")
		List children = (List) get("children");
		if (children == null) {
			children = new ArrayList();
			children_(children);
		}
		children.add(ch);
		return this;
	}

	/**
	 * node: { children: arrChildren<List> }
	 * @param arrChildren
	 */
	public void children(List arrChildren) {
		put("children", arrChildren);
	}

	public TreeIndenode children_(List childrenArray) {
		put("children", childrenArray);
		return this;
	}
	
	/**
	 * Set last child as the last sibling.
	 * @return this
	 */
	public TreeIndenode tagLast() {
		@SuppressWarnings("unchecked")
		ArrayList children = (ArrayList) get("children");
		if (!isNull(children))
			children.get(children.size() - 1).asLastSibling();
		return this;
	}

	boolean lastSibling;
	public TreeIndenode asLastSibling() {
		lastSibling = true;
		return this;
	}
}