blob: 79a2143d9ce21636c140fe07ec92822ab1baa7ff [file] [log] [blame]
/*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
/*
* $Id: Graph.java,v 1.3 2004/11/14 07:33:13 tcfujii Exp $
*/
package components.model;
import java.util.HashMap;
import java.util.Iterator;
/**
* <p>Graph is a JavaBean representing a complete graph of {@link Node}s.</p>
*/
public class Graph {
// ----------------------------------------------------------- Constructors
// No-args constructor
public Graph() {
super();
}
// Constructor with specified root
public Graph(Node root) {
setRoot(root);
}
// ------------------------------------------------------------- Properties
/**
* The collection of nodes that represent this hierarchy, keyed by name.
*/
protected HashMap registry = new HashMap();
// The root node
private Node root = null;
public Node getRoot() {
return (this.root);
}
public void setRoot(Node root) {
setSelected(null);
if (this.root != null) {
removeNode(this.root);
}
if (root != null) {
addNode(root);
}
root.setLast(true);
this.root = root;
}
// The currently selected node (if any)
private Node selected = null;
public Node getSelected() {
return (this.selected);
}
public void setSelected(Node selected) {
if (this.selected != null) {
this.selected.setSelected(false);
}
this.selected = selected;
if (this.selected != null) {
this.selected.setSelected(true);
}
}
// --------------------------------------------------------- Public Methods
/**
* <p>Find and return the named {@link Node} if it exists; otherwise,
* return <code>null</code>. The search expression must start with a
* slash character ('/'), and the name of each intervening node is
* separated by a slash.</p>
*
* @param path Absolute path to the requested node
*/
public Node findNode(String path) {
if (!path.startsWith("/")) {
throw new IllegalArgumentException(path);
}
Node node = getRoot();
path = path.substring(1);
while (path.length() > 0) {
String name = null;
int slash = path.indexOf("/");
if (slash < 0) {
name = path;
path = "";
} else {
name = path.substring(0, slash);
path = path.substring(slash + 1);
}
node = node.findChild(name);
if (node == null) {
return (null);
}
}
return (node);
}
/**
* Register the specified node in our registry of the complete tree.
*
* @param node The <code>Node</code> to be registered
*
* @throws IllegalArgumentException if the name of this node
* is not unique
*/
protected void addNode(Node node) throws IllegalArgumentException {
synchronized (registry) {
String name = node.getName();
if (registry.containsKey(name)) {
throw new IllegalArgumentException("Name '" + name +
"' is not unique");
}
node.setGraph(this);
registry.put(name, node);
}
}
/**
* Deregister the specified node, as well as all child nodes of this
* node, from our registry of the complete tree. If this node is not
* present, no action is taken.
*
* @param node The <code>Node</code> to be deregistered
*/
void removeNode(Node node) {
synchronized (registry) {
Iterator nodeItr = node.getChildren();
while (nodeItr.hasNext()) {
removeNode((Node) nodeItr.next());
}
node.setParent(null);
node.setGraph(null);
if (node == this.root) {
this.root = null;
}
}
}
/**
* Return <code>Node</code> by looking up the node registry.
*
* @param nodename Name of the <code>Node</code> to look up.
*/
public Node findNodeByName(String nodename) {
synchronized (registry) {
return ((Node) registry.get(nodename));
}
}
}