1   package org.slf4j.migrator.helper;
2   
3   public class Abbreviator {
4     static final String FILLER = "...";
5   
6     final char folderSeparator;
7     final int invariantPrefixLength;
8     final int desiredLength;
9   
10    public Abbreviator(int invariantPrefixLength, int desiredLength,
11        char folderSeparator) {
12      this.invariantPrefixLength = invariantPrefixLength;
13      this.desiredLength = desiredLength;
14      this.folderSeparator = folderSeparator;
15    }
16  
17    public String abbreviate(String filename) {
18      if (filename.length() <= desiredLength) {
19        return filename;
20      } else {
21  
22        int firstIndex = filename.indexOf(folderSeparator, invariantPrefixLength);
23        if (firstIndex == -1) {
24          // we cant't process this string
25          return filename;
26        }
27        StringBuffer buf = new StringBuffer(desiredLength);
28        buf.append(filename.substring(0, firstIndex + 1));
29        buf.append(FILLER);
30        int nextIndex = computeNextIndex(filename, firstIndex);
31        if (nextIndex != -1) {
32          buf.append(filename.substring(nextIndex));
33        } else {
34          // better long than wrong
35          return filename;
36        }
37  
38        if (buf.length() < filename.length()) {
39          return buf.toString();
40        } else {
41          // we tried our best but we are still could not shorten the input
42          return filename;
43        }
44      }
45    }
46  
47    int computeNextIndex(String filename, int firstIndex) {
48      int nextIndex = firstIndex + 1;
49      int hitCount = 0;
50      int minToRemove = filename.length() - desiredLength + FILLER.length();
51      while (nextIndex < firstIndex + minToRemove) {
52        int tmpIndex = filename.indexOf(folderSeparator, nextIndex + 1);
53        if (tmpIndex == -1) {
54          if (hitCount == 0) {
55            return -1;
56          } else {
57            return nextIndex;
58          }
59        } else {
60          hitCount++;
61          nextIndex = tmpIndex;
62        }
63      }
64      return nextIndex;
65    }
66  }