diff src/samer/core_/Node.java @ 0:bf79fb79ee13

Initial Mercurial check in.
author samer
date Tue, 17 Jan 2012 17:50:20 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/samer/core_/Node.java	Tue Jan 17 17:50:20 2012 +0000
@@ -0,0 +1,99 @@
+/*
+ *	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(); }
+}