| package com.gitblit.utils; |
| |
| import com.google.common.base.Joiner; |
| import com.google.common.base.Splitter; |
| import com.google.common.collect.Iterables; |
| |
| import java.util.*; |
| |
| /** |
| * Utils for handling path strings |
| * |
| */ |
| public class PathUtils { |
| |
| private PathUtils() {} |
| |
| /** |
| * Compress paths containing no files |
| * |
| * @param paths lines from `git ls-tree -r --name-only ${branch}` |
| * @return compressed paths |
| */ |
| public static List<String> compressPaths(final Iterable<String> paths) { |
| |
| ArrayList<String> pathList = new ArrayList<>(); |
| Map<String, List<String[]>> folderRoots = new LinkedHashMap<>(); |
| |
| for (String s: paths) { |
| String[] components = s.split("/"); |
| |
| // File in current directory |
| if (components.length == 1) { |
| pathList.add(components[0]); |
| |
| // Directory path |
| } else { |
| List<String[]> rootedPaths = folderRoots.get(components[0]); |
| if (rootedPaths == null) { |
| rootedPaths = new ArrayList<>(); |
| } |
| rootedPaths.add(components); |
| folderRoots.put(components[0], rootedPaths); |
| } |
| } |
| |
| for (String folder: folderRoots.keySet()) { |
| List<String[]> matchingPaths = folderRoots.get(folder); |
| |
| if (matchingPaths.size() == 1) { |
| pathList.add(toStringPath(matchingPaths.get(0))); |
| } else { |
| pathList.add(longestCommonSequence(matchingPaths)); |
| } |
| } |
| return pathList; |
| } |
| |
| /** |
| * Get last path component |
| * |
| * |
| * @param path string path separated by slashes |
| * @return rightmost entry |
| */ |
| public static String getLastPathComponent(final String path) { |
| return Iterables.getLast(Splitter.on("/").omitEmptyStrings().split(path), path); |
| } |
| |
| private static String toStringPath(final String[] pathComponents) { |
| List<String> tmp = Arrays.asList(pathComponents); |
| return Joiner.on('/').join(tmp.subList(0,tmp.size()-1)) + '/'; |
| } |
| |
| |
| private static String longestCommonSequence(final List<String[]> paths) { |
| |
| StringBuilder path = new StringBuilder(); |
| |
| for (int i = 0; i < paths.get(0).length; i++) { |
| String current = paths.get(0)[i]; |
| for (int j = 1; j < paths.size(); j++) { |
| if (!current.equals(paths.get(j)[i])) { |
| return path.toString(); |
| } |
| } |
| path.append(current); |
| path.append('/'); |
| } |
| return path.toString(); |
| } |
| |
| } |