consciouscode.seedling.tree
Class GenericBranch

java.lang.Object
  extended by consciouscode.seedling.tree.GenericNode
      extended by consciouscode.seedling.tree.GenericBranch
All Implemented Interfaces:
BranchingBranch, BranchNode, EventfulBranch, GrowingBranch, LocatableNode, ServiceNode
Direct Known Subclasses:
ScopeManager, StandardBranch

public class GenericBranch
extends GenericNode
implements EventfulBranch, BranchingBranch

Provides a basic implementation of BranchNode, suitable for extension.

This class cannot provision new nodes on request, and is thus decoupled from any particular provisioning mechanism. See StandardBranch for an implementation that provisions children via a NodeProvider.


Constructor Summary
GenericBranch()
           
 
Method Summary
 void addBranchChangeListener(BranchChangeListener listener)
          Registers the specified listener to receive branch change events for this branch.
 Object availableChild(String nodeName)
          Gets a child node, provisioning and installing it if possible.
 Collection<String> availableChildNames()
          Extracts a collection of the names of child nodes that are available on request from this branch.
protected  GenericBranch constructChildBranch()
          Strategy method called by provisionChildBranch() to do initial construction of child branches.
protected  Object createChild(String nodeName)
          Deprecated. Renamed to provisionChild(String). Subclasses should override that method instead of this one.
protected  void fireChildInstalled(String nodeName, Object node)
           
protected  void fireChildUninstalled(String nodeName, Object node)
           
 Object getChild(String nodeName)
          Deprecated. 
 Object getInstalledNode(String path)
          Deprecated. 
 String getLocalPathForChild(String nodeName)
          Deprecated. 
 RootNode getLocalRoot()
          Get the root of this node's local scope.
 Object getNode(String path)
          Deprecated. 
 void installChild(String nodeName, Object node)
          Installs an object as a child of this branch.
 Object installedChild(String nodeName)
          Gets a child node, but doesn't provision it if it's not already installed.
 Collection<String> installedChildNames()
          Extracts a collection of the names of this branch's current child nodes.
 void nodeInstalled(NodeLocation location)
          Register the Seedling address at which this node has been installed.
protected  Object provisionChild(String nodeName)
          Attempts to provision a child node, where one doesn't currently exist.
 BranchNode provisionChildBranch()
          Provisions a child branch intended for installation as a child of this one.
 void startService()
          Starts a Seedling service.
 void stopService()
          Stops a Seedling service.
 Object uninstallChild(String nodeName)
          Removes a child node from this branch.
 
Methods inherited from class consciouscode.seedling.tree.GenericNode
getLog, getNodeLocation, getNodeName, getParentBranch, isLoggingDebug, setLog, setLoggingDebug
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface consciouscode.seedling.BranchNode
getLog
 
Methods inherited from interface consciouscode.seedling.LocatableNode
getNodeLocation
 

Constructor Detail

GenericBranch

public GenericBranch()
Method Detail

nodeInstalled

public void nodeInstalled(NodeLocation location)
Register the Seedling address at which this node has been installed. This is called immediately after the node has been installed into the tree.

Note: This is not called setNodeLocation because the location is not intended as a writable property. This implementation calls super and then caches the location's local root.

Specified by:
nodeInstalled in interface LocatableNode
Overrides:
nodeInstalled in class GenericNode
Parameters:
location - is this node's new location. It must not be null.
See Also:
getLocalRoot()

addBranchChangeListener

public void addBranchChangeListener(BranchChangeListener listener)
Description copied from interface: EventfulBranch
Registers the specified listener to receive branch change events for this branch.

Specified by:
addBranchChangeListener in interface EventfulBranch
Parameters:
listener - the BranchChangeListener to add.

fireChildInstalled

protected void fireChildInstalled(String nodeName,
                                  Object node)

fireChildUninstalled

protected void fireChildUninstalled(String nodeName,
                                    Object node)

getLocalRoot

public RootNode getLocalRoot()
Get the root of this node's local scope.

This implementation returns a cached pointer, initialized by nodeInstalled(NodeLocation).

Specified by:
getLocalRoot in interface BranchNode
Overrides:
getLocalRoot in class GenericNode
Returns:
the local root; not null after LocatableNode.nodeInstalled(NodeLocation) is invoked.
See Also:
BranchNode.getLocalRoot()

installedChildNames

public Collection<String> installedChildNames()
Description copied from interface: BranchNode
Extracts a collection of the names of this branch's current child nodes.

The result is a snapshot of the current state: subsequent changes to the branch are not reflected in the result. Thus the actual children may have changed by the time the collection is inspected; in particular, another thread may uninstall a node named in this collection before the name is even read from this list.

Implementations must ensure that the result stays usable even when the branch changes in another thread. For example, iterating the result must not throw ConcurrentModificationException if the branch changes during iteration.

Specified by:
installedChildNames in interface BranchNode
Returns:
not null.

availableChildNames

public Collection<String> availableChildNames()
Description copied from interface: BranchNode
Extracts a collection of the names of child nodes that are available on request from this branch. This set includes all installed children, as well as any other nodes that could be created on demand (usually via automated injection from configuration files).

The result is a snapshot of the current state: subsequent changes to the branch are not reflected in the result. Thus the actual children may have changed by the time the collection is inspected; in particular, another thread may uninstall a node named in this collection (thereby making it unavailable) before the name is even read from this collection.

Implementations must ensure that the result stays usable even when the branch changes in another thread. For example, iterating the result must not throw ConcurrentModificationException if the branch changes during iteration.

Specified by:
availableChildNames in interface BranchNode
Returns:
not null.

getNode

@Deprecated
public Object getNode(String path)
               throws NodeProvisioningException
Deprecated. 

Description copied from interface: BranchNode
Gets a node from a path relative to this branch, instantiating and installing it if necessary.

Specified by:
getNode in interface BranchNode
Parameters:
path - is interpreted relative to this branch. It may also be a (local or global) full path. It must not be null or empty.
Returns:
the requested node.
Throws:
NodeProvisioningException - if no such node exists, or if there was an error instantiating it.

getInstalledNode

@Deprecated
public Object getInstalledNode(String path)
Deprecated. 

Description copied from interface: BranchNode
Looks for a node relative to this branch, without instantiating any new nodes.

Specified by:
getInstalledNode in interface BranchNode
Parameters:
path - is interpreted relative to this branch. It may also be a (local or global) full path. It must not be null or empty.
Returns:
the requested node, or null if no node exists at the given path.

getLocalPathForChild

@Deprecated
public String getLocalPathForChild(String nodeName)
Deprecated. 


getChild

@Deprecated
public Object getChild(String nodeName)
                throws NoSuchNodeException,
                       NodeProvisioningException
Deprecated. 

Description copied from interface: BranchNode
Gets a required child node, provisioning and installing it if necessary.

Provisioning of uninstalled nodes is defined by the implementation class, which may not do any dynamic provisioning at all.

This method will not return null; see BranchNode.availableChild(String) and BranchNode.installedChild(String) for alternatives.

Specified by:
getChild in interface BranchNode
Parameters:
nodeName - must not be null or empty.
Throws:
NoSuchNodeException - if the node isn't installed and if the branch cannot provision it on demand. This usually means that there's no applicable configuration for the node
NodeProvisioningException - if there was an error provisioning the node.

availableChild

public Object availableChild(String nodeName)
                      throws NodeProvisioningException
Description copied from interface: BranchNode
Gets a child node, provisioning and installing it if possible.

A node is available if its already installed, or if it can be provided for installation, usually by being created from configuration. Provisioning of uninstalled nodes is defined by the implementation class, which may not do any dynamic provisioning at all, in which case this method behaves identically to BranchNode.installedChild(String).

If the requested node is not available then null is returned. This is in contrast to BranchNode.getChild(String), which throws NoSuchNodeException in that case.

Specified by:
availableChild in interface BranchNode
Parameters:
nodeName - must not be null or empty.
Returns:
the requested node, or null if it's not available.
Throws:
NodeProvisioningException - if there was an error provisioning the node.

installedChild

public Object installedChild(String nodeName)
Description copied from interface: BranchNode
Gets a child node, but doesn't provision it if it's not already installed.

Specified by:
installedChild in interface BranchNode
Parameters:
nodeName - must not be null or empty.
Returns:
the child node installed with the requested name, or null if no such child is installed.

installChild

public void installChild(String nodeName,
                         Object node)
                  throws ChildExistsException,
                         ServiceException
Description copied from interface: GrowingBranch
Installs an object as a child of this branch. After installation, the appropriate successor lifecycle APIs will be invoked. In particular, if the node implements ServiceNode then ServiceNode.startService() will be called.

Specified by:
installChild in interface GrowingBranch
Parameters:
nodeName - must not be null or empty. It must not match the name of an existing child node.
node - must not be null.
Throws:
ChildExistsException - if a node is already installed at the given nodeName. (The node will not have been installed in this case.)
ServiceException - if node implements ServiceNode and could not be started. (The node will not have been installed in this case.)

uninstallChild

public Object uninstallChild(String nodeName)
Removes a child node from this branch.

This implementation invokes ServiceNode.stopService() on nodes that implement it.

Specified by:
uninstallChild in interface GrowingBranch
Parameters:
nodeName - must not be null, but it does not need to match an actual child of this branch.
Returns:
the removed child node, or null if no such child is installed.

startService

public void startService()
                  throws Exception
Starts a Seedling service. This is called by the Seedling runtime after the node has been installed and all properties have been set to their configured values. Any exceptions thrown by an implementation of this method are handled by the Seedling. Instances of RuntimeException are propagated to the application, but any other kind of exception is wrapped in a ServiceException and rethrown.

This implementation currently does nothing.

Specified by:
startService in interface ServiceNode
Throws:
Exception

stopService

public void stopService()
Stops a Seedling service. This is called by the Seedling runtime as the node is uninstalled, either explicitly or by the Seedling itself being stopped.

Implementations of this method must not do anything that may change the state of the parent Seedling. In particular, it cannot call any overload of the following methods: BranchNode.getNode(java.lang.String), BranchNode.getChild(java.lang.String), GrowingBranch.installChild(java.lang.String, java.lang.Object), GrowingBranch.uninstallChild(java.lang.String).

Furthermore, this method may be called from within a JVM shutdown hook, which implies that it must work promptly and carefully.

This implementation loops through all child nodes and uninstall them.

Specified by:
stopService in interface ServiceNode
See Also:
Runtime.addShutdownHook(java.lang.Thread)

provisionChild

protected Object provisionChild(String nodeName)
                         throws NodeProvisioningException
Attempts to provision a child node, where one doesn't currently exist. This is not guaranteed to succeed; for instance there may be no appropriate configuration, or the branch may not support automatic child provisioning.

This implementation always returns null.

Returns:
the newly-created child node, or null if the node is not available.
Throws:
NodeProvisioningException - if there's a problem provisioning the node.

createChild

@Deprecated
protected Object createChild(String nodeName)
                      throws NodeInstantiationException
Deprecated. Renamed to provisionChild(String). Subclasses should override that method instead of this one.

Throws:
NodeInstantiationException

provisionChildBranch

public BranchNode provisionChildBranch()
                                throws NodeProvisioningException
Provisions a child branch intended for installation as a child of this one. Typically this will have the same type and configuration as the parent.

This method doesn't take a node name because we don't want provisioning to vary by name here. If that's desired then provisioning should happen in the normal way via BranchNode.availableChild(String).

This implementation calls constructChildBranch() to construct a new GenericBranch, and then configures it similarly to this instance. Subclasses will probably want to override that method rather than this one.

Specified by:
provisionChildBranch in interface BranchingBranch
Returns:
a new branch to be installed within this one; not null.
Throws:
NodeProvisioningException - if there's a problem providing an appropriate child branch.
See Also:
constructChildBranch()

constructChildBranch

protected GenericBranch constructChildBranch()
                                      throws NodeProvisioningException
Strategy method called by provisionChildBranch() to do initial construction of child branches. Subclasses will generally override this to construct a new instance of their own class.

Returns:
a new GenericBranch.
Throws:
NodeProvisioningException
See Also:
provisionChildBranch()


Copyright © 2001–2012 Todd V. Jonker. All Rights Reserved.