# Class DataNodeFactory

java.lang.Object
uk.ac.starlink.datanode.factory.DataNodeFactory

public class DataNodeFactory extends Object
Factory class for constructing `DataNode` objects. Instances of this class can be used to construct a `DataNode` from a generic input - for instance a `String` or a `File`. It tries to find the most appropriate existing object of one of the classes which implements `DataNode`. The classes it knows about, in rough order of preference, are:

- invalid reference

      uk.ac.starlink.datanode.nodes.NDFDataNode

- invalid reference

      uk.ac.starlink.datanode.nodes.WCSDataNode

- invalid reference

      uk.ac.starlink.datanode.nodes.ARYDataNode

- invalid reference

      uk.ac.starlink.datanode.nodes.HDSDataNode

- `FITSFileDataNode`
- `VOTableDataNode`
- `ZipFileDataNode`
- `TarStreamDataNode`
- `FITSStreamDataNode`
- `JDBCDataNode`
- `StarTableDataNode`
- `DocumentDataNode`
- `XMLDataNode`
- `CompressedDataNode`
- `FileDataNode`
- `BranchDataNode`
- `PlainDataNode`

The factory will churn out a `DataNode` object based on the object it is given for construction, the constructors available from the known implementing objects (the above list), and optionally a list of preferences which may be examined and modified using supplied methods.

The factory has a list of DataNodeBuilder objects which it uses to try to construct nodes from any given object, be it a filename, string, XML source, or whatever. The `makeDataNode(DataNode, Object)` method passes the object to each suitable builder to see if it can turn it into a DataNode, and returns the first successful result. Thus the list of DataNodeBuilders and its order determines what kind of DataNode you will get.

There are two types of builder in the list. The first is generated by reflection on a number of DataNode-implementing classes as listed above. These are made out of suitable (one-argument) constructors supplied by those classes. The second type is a special one of type `DataNodeBuilder`. This is smart and fast and can make clever decisions about what kind of data node a given file should be turned into.

Initially a newly constructed DataNodeFactory has a `FileDataNodeBuilder`, `StringDataNodeBuilder`, `SourceDataNodeBuilder` `DocumentDataNodeBuilder` and `XMLDataNodeBuilder` at the head of the list, followed by ones got from constructors of the known DataNode implementations. This means that a file or string will get tackled first by the clever classes, but if that fails it will trawl through all the other possibilities.

Version:
  $Id$
Author:
  Mark Taylor (Starlink)

## Constructor Summary

Constructors
Constructor
Description
`DataNodeFactory()`
Constructs a new factory with a default list of node builders.
`DataNodeFactory(DataNodeFactory orig)`
Copy constructor.

## Method Summary

Modifier and Type
Method
Description
`void`
`configureDataNode(DataNode node, DataNode parentNode, Object obj)`
Performs some of the desirable configuration on a new DataNode which is about to get inserted into the tree.
`void`
`fillInAncestors(DataNode node)`
Sets the `CreationState` of a datanode and its ancestors.
`List`
`getBuilders()`
Returns the list of `DataNodeBuilder`s which this factory uses to construct data nodes.
`boolean`
`getDebug()`
Indicates whether this factory is running in debug mode.
`static List`
`getDefaultClassList()`
Returns the default class list from which the list of constructor-based builders is initialised.
`static List`
`getSpecialBuilders()`
Returns a list of builders which, for a default DataNodeFactory, are invoked before any of the constructor-based ones.
`DataNode`
`makeChildNode(DataNode parent, Object obj)`
Convenience method which invokes `makeDataNode(DataNode, Object)` but does not throw a `NoSuchDataException`.
`DataNode`
`makeDataNode(DataNode parent, Object obj)`
Generates a new DataNode from a given object.
`DataNode`
`makeErrorDataNode(DataNode parent, Throwable th)`
Makes a DataNode from a Throwable.
`void`
`removeNodeClass(Class clazz)`
Ensures that the factory will not generate nodes of a given class.
`void`
`setDebug(boolean debug)`
Sets whether this factory is running in debug mode.
`void`
`setDeprecatedClass(Class clazz)`
Sets the class you would least like to see generated by this factory.
`void`
`setPreferredClass(Class clazz)`
Sets the class you would most like to see generated by this factory.
`String`
`toString()`
Returns a string representation of this factory.

### Methods inherited from class Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

## Constructor Details

### DataNodeFactory

public DataNodeFactory()
Constructs a new factory with a default list of node builders.

### DataNodeFactory

public DataNodeFactory(DataNodeFactory orig)
Copy constructor. Creates a clone of `orig` which has identical characteristics to it but its own copies of the data structures, so that modifying the resulting factory will not affect the original.

Parameters:
  `orig` - the original factory on which to base this one

## Method Details

### removeNodeClass

public void removeNodeClass(Class clazz)
Ensures that the factory will not generate nodes of a given class. Following this call, calls to `makeDataNode(DataNode, Object)` will not return any nodes of class `clazz`. Note this does not affect the construction of classes of subtypes of `clazz`.

Parameters:
  `clazz` - the shunned class (presumably a subtype of DataNode)

### setPreferredClass

public void setPreferredClass(Class clazz)
Sets the class you would most like to see generated by this factory. This raises any constructor-based builders for the named class to the head of the builder list, so if it is possible to build a node of this type, that is what subsequent calls of `makeDataNode(DataNode, Object)` will do.

Parameters:
  `clazz` - the preferred class (presumably a subtype of DataNode)

### setDeprecatedClass

public void setDeprecatedClass(Class clazz)
Sets the class you would least like to see generated by this factory. Unlike `removeNodeClass(Class)` this does not remove the possibility of this factory producing such a node at all, but it demotes builders which are known to produce this type of node to the bottom of the builder list.

Parameters:
  `clazz` - the deprecated class (presumably a subtype of DataNode)

### getBuilders

public List getBuilders()
Returns the list of `DataNodeBuilder`s which this factory uses to construct data nodes. This may be modified by code which reckons it knows what it's doing, but beware that by modifying this list in strange ways the behaviour of this factory may be compromised. In particular, don't put anything in here which is not a `DataNodeBuilder` object.

Returns:
  a mutable list of `DataNodeBuilder` objects

### makeDataNode

public DataNode makeDataNode(DataNode parent, Object obj) throws NoSuchDataException
Generates a new DataNode from a given object. It goes through this factory's list of builder objects and tries each one with the given object until one of the builders can turn it into a DataNode.

Ideally, all data node construction (except perhaps the root of a tree) should be done using this method, since it keeps track of various data structures which invoking constructors directly may not.

Parameters:
  `parent` - the DataNode whose child the new node will be in the node hierarchy. May be `null` for a hierarchy root
  `obj` - an object which is to be turned into a DataNode by one of the builders
Returns:
  a new DataNode object based on `obj`
Throws:
  `NoSuchDataException` - if none of the builders in the list could turn `obj` into a `DataNode`

### configureDataNode

public void configureDataNode(DataNode node, DataNode parentNode, Object obj)
Performs some of the desirable configuration on a new DataNode which is about to get inserted into the tree. This method is called by `makeDataNode(DataNode, Object)` and in most cases should not be called by nodes creating children. However, if a node is creating children other than using `makeDataNode` (for instance because their constructors are not suitable for the generic node creation system on which this class is based) then this method should be called on the new child before it is returned from the child iterator. Configuring new-born nodes using this method is not essential, but it is likely to ensure that the node is as far as possible a well-behaved member of the node tree; not doing it can lead to some impairment of functionality for the nodes in question.

Parameters:
  `node` - the new node to configure
  `parentNode` - `node`'s parent data node (may be `null`) if it's at the top of the tree)
  `obj` - the object on which `node` is based (may be `null`) if nothing suitable applies

### makeErrorDataNode

public DataNode makeErrorDataNode(DataNode parent, Throwable th)
Makes a DataNode from a Throwable. This behaves the same as `makeDataNode` but for convenience it doesn't throw a NoSuchDataException, since it can guarantee to make a DataNode from the throwable.

Parameters:
  `parent` - the DataNode whose child this is
  `th` - the Throwable object from which to construct the node
Returns:
  a DataNode (probably an ErrorDataNode) representing `th`

### makeChildNode

public DataNode makeChildNode(DataNode parent, Object obj)
Convenience method which invokes `makeDataNode(DataNode, Object)` but does not throw a `NoSuchDataException`. If the node construction fails, then `makeErrorDataNode(DataNode, Throwable)` will be called to construct the node for return instead.

Parameters:
  `parent` - the DataNode whose child the new node will be in the node hierarchy. May be `null` for a hierarchy root
  `obj` - an object which is to be turned into a DataNode by one of the builders
Returns:
  a new DataNode object based on `obj`

### fillInAncestors

public void fillInAncestors(DataNode node)
Sets the `CreationState` of a datanode and its ancestors. The node is queried for its parent object, and a new datanode is made out of this and inserted into the CreationState as its parent. The same is recursively done to the parent, until there is no parent object or node creation fails.

Parameters:
  `node` - node whose ancestors are to be filled in

### getDebug

public boolean getDebug()
Indicates whether this factory is running in debug mode.

Returns:
  debug mode flag

### setDebug

public void setDebug(boolean debug)
Sets whether this factory is running in debug mode.

Parameters:
  `debug` - debug mode flag

### toString

public String toString()
Returns a string representation of this factory. The returned string is a comprehensive list of which constructors will be tried.

Overrides:
  `toString` in class `Object`
Returns:
  an ordered list of the constructors that the `makeDataNode` will try to use.

### getSpecialBuilders

public static List getSpecialBuilders()
Returns a list of builders which, for a default DataNodeFactory, are invoked before any of the constructor-based ones. These allow cleverer decisions to be made about what kind of node is generated from what object: if a given object could make either a FooDataNode or a BarDataNode but would be better off as a BarDataNode, this can be done even if FooDataNode was higher in the class preference list for this factory. For the default configuration, this list should come first in the list of builders, if the user reconfigures the preferred class list it may slip lower down or disappear from the hierarchy.

This method is called in the constructor to initialise the factory's default state.

Returns:
  a list of `DataNodeBuilder` objects

### getDefaultClassList

public static List getDefaultClassList()
Returns the default class list from which the list of constructor-based builders is initialised.

This method is called in the constructor to initialise the factory's default state.

Returns:
  a list of `Class` objects representing concrete implementations of the `DataNode` interface