package com.link_intersystems.gitdirstat.domain; import java.math.BigInteger; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Stack; import org.apache.commons.collections4.iterators.IteratorEnumeration; import org.apache.commons.lang3.StringUtils; public class TreeObject implements Comparable<TreeObject> { private List<TreeObject> children = new ArrayList<TreeObject>(); private List<ObjectSize> objectSizes = new ArrayList<ObjectSize>(); private String name; private BigInteger size; private TreeObject parent; private TreeObjectPath rootRelativePath; private TreeObjectPath thisPath; TreeObject(String name) { this.name = name; } public String getName() { return name; } void addObjectSize(ObjectSize objectSize) { objectSizes.add(objectSize); this.size = null; } public BigInteger getSize() { if (size == null) { size = BigInteger.ZERO; for (ObjectSize objectSize : objectSizes) { BigInteger thisSize = objectSize.getSize(); size = size.add(thisSize); } Enumeration<TreeObject> childEnumerations = children(); while (childEnumerations.hasMoreElements()) { TreeObject childTreeObject = childEnumerations.nextElement(); BigInteger childSize = childTreeObject.getSize(); size = size.add(childSize); } } return size; } public List<TreeObject> toFileList() { List<TreeObject> fileList = new ArrayList<TreeObject>(); if (this.isFile()) { fileList.add(this); } Enumeration<TreeObject> children = children(); while (children.hasMoreElements()) { TreeObject treeObject = children.nextElement(); List<TreeObject> childFiles = treeObject.toFileList(); fileList.addAll(childFiles); } return fileList; } public Enumeration<TreeObject> children() { return new IteratorEnumeration<TreeObject>(children.iterator()); } void add(TreeObject childTreeObject) { this.children.add(childTreeObject); childTreeObject.parent = this; } public TreeObject makePath(String path) { String[] splitPath = splitPath(path); TreeObject parentTreeObj = this; TreeObject currTreeObj = null; TreeObject lastTreeObj = null; Enumeration<TreeObject> treeNodes = parentTreeObj.children(); pathSegments: for (int i = 0; i < splitPath.length; i++) { String pathSegment = splitPath[i]; while (treeNodes.hasMoreElements()) { currTreeObj = treeNodes.nextElement(); if (pathSegment.equals(currTreeObj.getName())) { lastTreeObj = currTreeObj; parentTreeObj = currTreeObj; treeNodes = parentTreeObj.children(); continue pathSegments; } } currTreeObj = new TreeObject(pathSegment); lastTreeObj = currTreeObj; parentTreeObj.add(currTreeObj); parentTreeObj = currTreeObj; treeNodes = parentTreeObj.children(); } return lastTreeObj; } private String[] splitPath(String path) { return StringUtils.split(path, '/'); } public boolean isFile() { return this.children.isEmpty() && this.parent != null; } public TreeObjectPath getPath() { if (thisPath == null) { thisPath = new TreeObjectPath(this); if (parent != null) { TreeObjectPath parentPath = parent.getPath(); thisPath.prepend(parentPath); } } return thisPath; } public TreeObjectPath getRootRelativePath() { if (rootRelativePath == null) { rootRelativePath = new TreeObjectPath(this); if (parent != null && parent.parent != null) { TreeObjectPath parentPath = parent.getRootRelativePath(); rootRelativePath.prepend(parentPath); } } return rootRelativePath; } public Map<String, TreeObject> asRootRelativePathMap() { Stack<TreeObject> treeObjectStack = new Stack<TreeObject>(); treeObjectStack.push(this); Map<String, TreeObject> pathMap = new HashMap<String, TreeObject>(); TreeObject currTreeObject = null; while (!treeObjectStack.isEmpty()) { currTreeObject = treeObjectStack.pop(); if (currTreeObject.isFile()) { TreeObjectPath treePath = currTreeObject.getPath(); String pathname = treePath.getRootRelativePathname(); pathMap.put(pathname, currTreeObject); } Enumeration<TreeObject> children = currTreeObject.children(); while (children.hasMoreElements()) { TreeObject childTreeObject = children.nextElement(); treeObjectStack.push(childTreeObject); } } return pathMap; } @Override public int compareTo(TreeObject o) { return getSize().compareTo(o.getSize()); } public boolean isRoot() { return this.parent == null; } }