view src/samer/core_/Node.java @ 8:5e3cbbf173aa tip

Reorganise some more
author samer
date Fri, 05 Apr 2019 22:41:58 +0100
parents bf79fb79ee13
children
line wrap: on
line source
/*
 *	Node.java	
 *
 *	Copyright (c) 2000, Samer Abdallah, King's College London.
 *	All rights reserved.
 *
 *	This software is provided AS iS and WITHOUT ANY WARRANTY; 
 *	without even the implied warranty of MERCHANTABILITY or 
 *	FITNESS FOR A PARTICULAR PURPOSE.
 *
 *	Change history:
 *
 *	Removed all references to parent nodes - each node now
 *	stores its full name. Uses more memory but simpler in the
 *	long run, I think.
 */

package samer.core;
import java.util.*;

/**
	<p> A Node is essentially a path in a hierarchical
	name space. Each node is an independent object. 
	A Node can be constructed either with an explicit
	parent Node, or with an absolute path, or as a child
	of the current Node maintained by the current Shell.
	Names are constructed in parts, concatenated with 
	dots, eg,
	<code>
		Node A=new Node("top",null);
		Node B=new Node("middle",A);
		Node C=new Node("bottom",B);
	</code>
	Then node A is "top", node B is "top.middle" and node
	C is "top.middle.bottom"

	<p>The top level Environment (see Environment)
	actually uses a nameless top level node: "", so that
	all fully specified node paths begin with ".", eg
	".antelope.gibbon.firebucket"
	This is so that names that <I>don't</I> start with a
 	dot are treated as relative to the current Environment's node.
 */

public class Node implements java.io.Serializable
{
	private final String	name;

	/** Construct new Node with given name as a child of the
		current Environment's base node, ie
		<code>Shell.env().node()</code>
	 */
	public Node(String name) {
		if (name==null || name.equals(""))
			throw new Error("Node with empty name");

		if (isAbsolute(name)) this.name=name;
		else this.name=Shell.env().node().fullNameFor(name);
	}


	private Node() { name=""; }

	/** Construct new Node with given name and parent
		If parent is null, a top level node is created
	*/
	public Node(String name, Node parent) { this.name = parent.fullName()+"."+name; }

	/** Returns parent Node, or null if no parent */
	public Node   getParent()	{ return new Node(name.substring(0,name.lastIndexOf('.'))); }
	public static String lastPart(String str) { return str.substring(1+str.lastIndexOf('.')); }
	public String fullName() { return name; }
	public String shortName() { return lastPart(name); }

	/** Return full name of hypothetical Node with given name
		as a child of this Node, ie, this node's full name + "."+ nm.
	*/
	public String fullNameFor(String nm) { return name+"."+nm; }

	/** Absolute names start with a . This is only true of the top
		level Node has an empty name!
	*/
	public static boolean isAbsolute(String nm) { return (nm.charAt(0)=='.'); }

	/** Returns true if and only if the given name is a child of this one.
		This is trivially true if the given name is relative (ie doesn't start
		with a dot). If it does, then the initial substrings must match.
	*/
	public boolean isSubnode(String nm) {
		if (!isAbsolute(nm)) return true;
		return nm.startsWith(name);
	}

	/** Returns the full name of this node. */
	public String toString() { return name; }

	/** Returns a NEW top-level node each time it is called. */
	public static Node root() { return new Node(); }
}