/* * Licensed 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 com.addthis.hydra.data.util; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; public class UrlTreeObject { private TreeValue treeValue; private Map<String, UrlTreeObject> leaves; private boolean hasTrailingSep; public UrlTreeObject(String data) { treeValue = new TreeValue(data, 0d); leaves = new HashMap<>(); } public TreeValue getTreeValue() { return treeValue; } public int size() { return leaves.size(); } public boolean hasTrailingSlash() { return hasTrailingSep; } public void setHasTrailingSep(boolean hasTrailingSep) { this.hasTrailingSep = hasTrailingSep; } public void addBranch(List<String> data, double value, boolean hashTrailingSep) { if (data != null) { String key = data.get(0); UrlTreeObject leaf = leaves.get(key); if (leaf == null) { leaf = new UrlTreeObject(key); leaves.put(key, leaf); } if (data.size() > 1) { List<String> subList = data.subList(1, data.size()); leaf.addBranch(subList, value, hashTrailingSep); } else { // only the end leaf will contain the value leaf.getTreeValue().updateValue(value); leaf.setHasTrailingSep(hashTrailingSep); } } } public List<TreeValue> getBranches(String sep) { List<TreeValue> branches = new ArrayList<>(); if (leaves.size() > 0) { for (UrlTreeObject leaf : leaves.values()) { for (TreeValue branch : leaf.getBranches(sep)) { if (treeValue.getData().length() > 0) { branches.add(new TreeValue(new StringBuffer().append(treeValue.getData()) .append(sep) .append(branch.getData()) .toString(), branch.getValue())); } else { branches.add(new TreeValue(new StringBuffer().append(branch.getData()).toString(), branch.getValue())); } } } } else { if (hasTrailingSep) { branches.add(new TreeValue(treeValue.getData() + (hasTrailingSep ? sep : ""), treeValue.getValue())); } else { branches.add(treeValue); } } return branches; } public static class TreeValue { private String data; private Double value; TreeValue(String data, Double value) { this.data = data; this.value = value; } public String getData() { return data; } public void setData(String data) { this.data = data; } public Double getValue() { return value; } public void updateValue(Double value) { this.value += value; } public void setValue(Double value) { this.value = value; } public String toString() { return data + ":" + value; } @Override public boolean equals(Object obj) { if (!(obj instanceof TreeValue)) { return false; } TreeValue other = (TreeValue) obj; return Objects.equals(this.data, other.data) && Objects.equals(this.value, other.value); } @Override public int hashCode() { return Objects.hash(data, value); } } }