?? hierarchicalconfiguration.java
字號(hào):
/**
* <p>Returns an iterator with all keys defined in this configuration.</p>
* <p>Note that the keys returned by this method will not contain
* any indices. This means that some structure will be lost.</p>
* @return an iterator with the defined keys in this configuration
*/
public Iterator getKeys()
{
DefinedKeysVisitor visitor = new DefinedKeysVisitor();
getRoot().visit(visitor, new ConfigurationKey());
return visitor.getKeyList().iterator();
}
/**
* Creates a new <code>Configuration</code> object containing all keys
* that start with the specified prefix. This implementation will return
* a <code>HierarchicalConfiguration</code> object so that the structure
* of the keys will be saved.
* @param prefix the prefix of the keys for the subset
* @return a new configuration object representing the selected subset
*/
public Configuration subset(String prefix)
{
Collection nodes = fetchNodeList(prefix);
if (nodes.isEmpty())
{
return null;
} /* if */
HierarchicalConfiguration result = new HierarchicalConfiguration();
CloneVisitor visitor = new CloneVisitor();
for (Iterator it = nodes.iterator(); it.hasNext();)
{
Node nd = (Node) it.next();
nd.visit(visitor, null);
Container children = visitor.getClone().getChildren();
if (children.size() > 0)
{
for (int i = 0; i < children.size(); i++)
{
result.getRoot().addChild((Node) children.get(i));
} /* for */
} /* if */
else
{
// In this case we cannot shorten the key because only
// values are found without further child nodes.
result.getRoot().addChild(visitor.getClone());
} /* else */
} /* for */
return (result.isEmpty()) ? null : result;
}
/**
* Returns the maximum defined index for the given key. This is
* useful if there are multiple values for this key. They can then be
* addressed separately by specifying indices from 0 to the return value
* of this method.
* @param key the key to be checked
* @return the maximum defined index for this key
*/
public int getMaxIndex(String key)
{
return fetchNodeList(key).size() - 1;
}
/**
* Helper method for fetching a list of all nodes that are addressed by
* the specified key.
* @param key the key
* @return a list with all affected nodes (never <b>null</b>)
*/
protected List fetchNodeList(String key)
{
List nodes = new LinkedList();
findPropertyNodes(
new ConfigurationKey(key).iterator(),
getRoot(),
nodes);
return nodes;
}
/**
* Recursive helper method for fetching a property. This method
* processes all facets of a configuration key, traverses the tree of
* properties and fetches the the nodes of all matching properties.
* @param keyPart the configuration key iterator
* @param node the actual node
* @param data here the found nodes are stored
*/
protected void findPropertyNodes(
ConfigurationKey.KeyIterator keyPart,
Node node,
Collection data)
{
if (!keyPart.hasNext())
{
data.add(node);
} /* if */
else
{
String key = keyPart.nextKey(true);
Container children = node.getChildren(key);
if (keyPart.hasIndex())
{
if (keyPart.getIndex() < children.size()
&& keyPart.getIndex() >= 0)
{
findPropertyNodes(
(ConfigurationKey.KeyIterator) keyPart.clone(),
(Node) children.get(keyPart.getIndex()),
data);
} /* if */
} /* if */
else
{
for (Iterator it = children.iterator(); it.hasNext();)
{
findPropertyNodes(
(ConfigurationKey.KeyIterator) keyPart.clone(),
(Node) it.next(),
data);
} /* for */
} /* else */
}
}
/**
* Checks if the specified node is defined.
* @param node the node to be checked
* @return a flag if this node is defined
*/
protected boolean nodeDefined(Node node)
{
DefinedVisitor visitor = new DefinedVisitor();
node.visit(visitor, null);
return visitor.isDefined();
}
/**
* Removes the specified node from this configuration. This method
* ensures that parent nodes that become undefined by this operation
* are also removed.
* @param node the node to be removed
*/
protected void removeNode(Node node)
{
Node parent = node.getParent();
if (parent != null)
{
parent.remove(node);
if (!nodeDefined(parent))
{
removeNode(parent);
} /* if */
} /* if */
}
/**
* Returns a reference to the parent node of an add operation.
* Nodes for new properties can be added as children of this node.
* If the path for the specified key does not exist so far, it is created
* now.
* @param keyIt the iterator for the key of the new property
* @param startNode the node to start the search with
* @return the parent node for the add operation
*/
protected Node fetchAddNode(
ConfigurationKey.KeyIterator keyIt,
Node startNode)
{
if (!keyIt.hasNext())
{
throw new IllegalArgumentException("Key must be defined!");
} /* if */
return createAddPath(keyIt, findLastPathNode(keyIt, startNode));
}
/**
* Finds the last existing node for an add operation. This method
* traverses the configuration tree along the specified key. The last
* existing node on this path is returned.
* @param keyIt the key iterator
* @param node the actual node
* @return the last existing node on the given path
*/
protected Node findLastPathNode(
ConfigurationKey.KeyIterator keyIt,
Node node)
{
String keyPart = keyIt.nextKey(true);
if (keyIt.hasNext())
{
Container c = node.getChildren(keyPart);
int idx = (keyIt.hasIndex()) ? keyIt.getIndex() : c.size() - 1;
if (idx < 0 || idx >= c.size())
{
return node;
} /* if */
else
{
return findLastPathNode(keyIt, (Node) c.get(idx));
} /* else */
} /* if */
else
{
return node;
} /* else */
}
/**
* Creates the missing nodes for adding a new property. This method
* ensures that there are corresponding nodes for all components of the
* specified configuration key.
* @param keyIt the key iterator
* @param root the base node of the path to be created
* @return the last node of the path
*/
protected Node createAddPath(ConfigurationKey.KeyIterator keyIt, Node root)
{
if (keyIt.hasNext())
{
Node child = new Node(keyIt.currentKey(true));
root.addChild(child);
keyIt.next();
return createAddPath(keyIt, child);
} /* if */
else
{
return root;
} /* else */
}
/**
* Helper method for adding all elements of a collection to a
* container.
* @param cont the container
* @param items the collection to be added
*/
private static void addContainer(Container cont, Collection items)
{
for (Iterator it = items.iterator(); it.hasNext();)
{
cont.add(it.next());
} /* for */
}
/**
* A data class for storing (hierarchical) property information. A property
* can have a value and an arbitrary number of child properties.
*
* @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a>
*/
public static class Node implements Serializable, Cloneable
{
/** Stores a reference to this node's parent.*/
private Node parent;
/** Stores the name of this node.*/
private String name;
/** Stores the value of this node.*/
private Object value;
/** Stores the children of this node.*/
private Map children;
/**
* Creates a new instance of <code>Node</code>.
*/
public Node()
{
this(null);
}
/**
* Creates a new instance of <code>Node</code> and sets the name.
* @param name the node's name
*/
public Node(String name)
{
setName(name);
}
/**
* Returns the name of this node.
* @return the node name
*/
public String getName()
{
return name;
}
/**
* Returns the value of this node.
* @return the node value (may be <b>null</b>)
*/
public Object getValue()
{
return value;
}
/**
* Returns the parent of this node.
* @return this node's parent (can be <b>null</b>)
*/
public Node getParent()
{
return parent;
}
/**
* Sets the name of this node.
* @param string the node name
*/
public void setName(String string)
{
name = string;
}
/**
* Sets the value of this node.
* @param object the node value
*/
public void setValue(Object object)
{
value = object;
}
/**
* Sets the parent of this node.
* @param node the parent node
*/
public void setParent(Node node)
{
parent = node;
}
/**
* Adds the specified child object to this node. Note that there can
* be multiple children with the same name.
* @param child the child to be added
*/
public void addChild(Node child)
{
if (children == null)
{
children = new SequencedHashMap();
} /* if */
List c = (List) children.get(child.getName());
if (c == null)
{
c = new ArrayList();
children.put(child.getName(), c);
} /* if */
c.add(child);
child.setParent(this);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -