All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.jackrabbit.vault.util.Tree Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jackrabbit.vault.util;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * {@code Tree}...
 */
public class Tree {

    private final char separator;

    private Node root = new Node(null, "");

    public Tree() {
        this('/');
    }

    public Tree(char separator) {
        this.separator = separator;
    }

    public void clear() {
        root.elem = null;
        root.children.clear();
    }

    public E put(String path, E elem) {
        E previous;
        Node n = get(path, true);
        previous = n.elem;
        n.elem = elem;
        return previous;
    }

    public E get(String path) {
        Node n = get(path, false);
        return n == null ? null : n.elem;
    }

    public Node getNode(String path) {
        return get(path, false);
    }

    public E remove(String path) {
        Node n = get(path, false);
        if (n == null) {
            return null;
        }
        E previous = n.elem;
        n.elem = null;
        n.prune();
        return previous;
    }

    private Node get(String path, boolean create) {
        String[] segs = Text.explode(path, separator);
        Node n = root;
        for (String name: segs) {
            Node c = n.get(name, create);
            if (c == null) {
                return null;
            }
            n = c;
        }
        return n;
    }

    public void removeChildren(String path) {
        Node n = get(path, false);
        if (n != null) {
            n.removeChildren();
        }
    }

    public Map map() {
        Map map = new LinkedHashMap();
        fill(map, root, "");
        return map;
    }

    public String getRootPath() {
        Node n = root;
        StringBuffer path = new StringBuffer();
        while (n.elem == null && n.children.size() == 1) {
            n = n.children.values().iterator().next();
            path.append(separator).append(n.name);
        }
        if (path.length() == 0) {
            path.append(separator);
        }
        return path.toString();
    }

    public Node getRootNode() {
        Node n = root;
        while (n.elem == null && n.children.size() == 1) {
            n = n.children.values().iterator().next();
        }
        return n;
    }

    private void fill(Map map, Node node, String parentPath) {
        String path;
        if (parentPath.length() != 1) {
            // stupid check for root path
            path = parentPath + separator + node.name;
        } else {
            path = parentPath + node.name;
        }
        if (node.elem != null) {
            map.put(path, node.elem);
        }
        for (Node child: node.children.values()) {
            fill(map, child, path);
        }
    }

    public static class Node {

        private String name;

        private E elem;

        private final Node parent;

        private final Map> children = new LinkedHashMap>();

        private Node(Node parent, String name) {
            this.parent = parent;
            this.name = name;
        }

        private Node get(String name, boolean create) {
            Node child = children.get(name);
            if (child == null && create) {
                child = new Node(this, name);
                children.put(name, child);
            }
            return child;
        }

        private Node remove(String name) {
            return children.remove(name);
        }

        private void prune() {
            if (children.isEmpty() && elem == null && parent != null) {
                parent.remove(this.name);
                parent.prune();
            }
        }

        private void removeChildren() {
            children.clear();
            prune();
        }

        public String getName() {
            return name;
        }

        public E getElem() {
            return elem;
        }

        public Node getParent() {
            return parent;
        }

        public Map> getChildren() {
            return children;
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder();
            sb.append("Node");
            sb.append("{name='").append(name).append('\'');
            sb.append(", elem=").append(elem);
            sb.append(", children=").append(children.keySet());
            sb.append('}');
            return sb.toString();
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy