Mercurial > hg > jslab
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(); } +}