⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hierarchicalconfiguration.java

📁 java servlet著名论坛源代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

    /**
     * <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);
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -