summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/gitblit/utils/PathUtils.java
diff options
context:
space:
mode:
authorMilos Cubrilo <milos.cubrilo@gmail.com>2015-01-11 13:41:29 +0100
committerMilos Cubrilo <milos.cubrilo@gmail.com>2015-01-11 13:41:29 +0100
commita9a2ffcf9a34bd25fe2e05bfdd4cde74725bb17d (patch)
tree69489cfef9060831b3c802bbb237f9d70f4a13ac /src/main/java/com/gitblit/utils/PathUtils.java
parentde6f6625cb96775b640240ed2e57499743670fe2 (diff)
downloadgitblit-a9a2ffcf9a34bd25fe2e05bfdd4cde74725bb17d.tar.gz
gitblit-a9a2ffcf9a34bd25fe2e05bfdd4cde74725bb17d.zip
#230 - Improve empty folder navigation.
Empty folders are automatically skipped when browsing repository tree (similar to github "folder jumping" feature).
Diffstat (limited to 'src/main/java/com/gitblit/utils/PathUtils.java')
-rw-r--r--src/main/java/com/gitblit/utils/PathUtils.java92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/main/java/com/gitblit/utils/PathUtils.java b/src/main/java/com/gitblit/utils/PathUtils.java
new file mode 100644
index 00000000..a3c7d8d6
--- /dev/null
+++ b/src/main/java/com/gitblit/utils/PathUtils.java
@@ -0,0 +1,92 @@
+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();
+ }
+
+}