001/**
002 * Copyright 2010-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.common.util.tree;
017
018import static com.google.common.collect.Lists.newArrayList;
019import static com.google.common.collect.Lists.transform;
020
021import java.util.List;
022
023import org.apache.commons.lang3.StringUtils;
024
025import com.google.common.base.Function;
026import com.google.common.collect.ImmutableList;
027
028public class Trees {
029
030        public static <T> List<Node<T>> getLeaves(List<Node<T>> nodes) {
031                List<Node<T>> leaves = newArrayList();
032                for (Node<T> node : nodes) {
033                        leaves.addAll(getLeaves(node));
034                }
035                return leaves;
036        }
037
038        public static <T> List<Node<T>> getLeaves(Node<T> root) {
039                List<Node<T>> leaves = newArrayList();
040                List<Node<T>> nodes = breadthFirst(root);
041                for (Node<T> node : nodes) {
042                        if (node.isLeaf()) {
043                                leaves.add(node);
044                        }
045                }
046                return leaves;
047        }
048
049        public static <T> List<T> breadthFirstElements(Node<T> node) {
050                return transform(breadthFirst(node), new NodeElementFunction<T>());
051        }
052
053        public static <T> List<Node<T>> breadthFirst(List<Node<T>> nodes) {
054                List<Node<T>> list = newArrayList();
055                for (Node<T> node : nodes) {
056                        list.addAll(breadthFirst(node));
057                }
058                return list;
059        }
060
061        public static <T> List<Node<T>> breadthFirst(Node<T> node) {
062                NodeTraverser<T> nt = NodeTraverser.create();
063                Iterable<Node<T>> itr = nt.breadthFirstTraversal(node);
064                return newArrayList(itr);
065        }
066
067        public static <T> List<Node<T>> postOrder(Node<T> node) {
068                NodeTraverser<T> nt = NodeTraverser.create();
069                Iterable<Node<T>> itr = nt.postOrderTraversal(node);
070                return newArrayList(itr);
071        }
072
073        public static <T> List<Node<T>> preOrder(Node<T> node) {
074                NodeTraverser<T> nt = NodeTraverser.create();
075                Iterable<Node<T>> itr = nt.preOrderTraversal(node);
076                return newArrayList(itr);
077        }
078
079        public static <T> String html(String title, Node<T> node) {
080                Function<Node<T>, String> converter = NodeStringFunction.create();
081                return html(title, ImmutableList.of(node), converter);
082        }
083
084        public static <T> String html(String title, Node<T> node, Function<Node<T>, String> converter) {
085                return html(title, ImmutableList.of(node), converter);
086        }
087
088        public static <T> String html(String title, List<Node<T>> nodes) {
089                Function<Node<T>, String> converter = NodeStringFunction.create();
090                return html(title, nodes, converter);
091        }
092
093        public static <T> String html(String title, List<Node<T>> nodes, Function<Node<T>, String> converter) {
094                StringBuilder sb = new StringBuilder();
095                sb.append("<table border=\"1\">\n");
096                sb.append(" <th>" + title + "</th>\n");
097                sb.append(" <tr>\n");
098                sb.append("  <td>\n");
099                for (Node<T> node : nodes) {
100                        sb.append(html(node, 3, converter));
101                }
102                sb.append("  </td>\n");
103                sb.append(" </tr>\n");
104                sb.append("</table>\n");
105                return sb.toString();
106        }
107
108        public static <T> String html(Node<T> node) {
109                Function<Node<T>, String> converter = NodeStringFunction.create();
110                return html(node, 0, converter);
111        }
112
113        public static <T> String html(Node<T> node, Function<Node<T>, String> converter) {
114                return html(node, 0, converter);
115        }
116
117        public static <T> String html(Node<T> node, int indent, Function<Node<T>, String> converter) {
118                StringBuilder sb = new StringBuilder();
119                String prefix = StringUtils.repeat(" ", indent);
120                sb.append(prefix + "<table border=\"1\">\n");
121                sb.append(prefix + " <tr>\n");
122                sb.append(prefix + "  <td>" + converter.apply(node) + "</td>\n");
123                List<Node<T>> children = node.getChildren();
124                if (!children.isEmpty()) {
125                        sb.append(prefix + "  <td>\n");
126                        for (Node<T> child : children) {
127                                sb.append(html(child, indent + 3, converter));
128                        }
129                        sb.append(prefix + "  </td>\n");
130                }
131                sb.append(prefix + " </tr>\n");
132                sb.append(prefix + "</table>\n");
133                return sb.toString();
134        }
135
136}