View Javadoc

1   /**
2    * LOGBack: the reliable, fast and flexible logging library for Java.
3    *
4    * Copyright (C) 1999-2006, QOS.ch
5    *
6    * This library is free software, you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public License as
8    * published by the Free Software Foundation.
9    */
10  package ch.qos.logback.classic.pattern;
11  
12  import ch.qos.logback.core.CoreConstants;
13  
14  public class TargetLengthBasedClassNameAbbreviator implements Abbreviator {
15  
16    static private final int BUF_LIMIT = 256;
17    static private final int MAX_DOTS = 12;
18  
19    final int targetLength;
20    StringBuffer buf;
21  
22    public TargetLengthBasedClassNameAbbreviator(int targetLength) {
23      this.targetLength = targetLength;
24      buf = new StringBuffer(targetLength);
25    }
26  
27    public String abbreviate(String fqClassName) {
28      if (fqClassName == null) {
29        throw new IllegalArgumentException("Class name may not be null");
30      }
31  
32      int inLen = fqClassName.length();
33      if (inLen < targetLength) {
34        return fqClassName;
35      }
36  
37      if (buf.capacity() > BUF_LIMIT) {
38        buf = new StringBuffer(targetLength);
39      }
40      buf.setLength(0);
41  
42      int[] dotArray = new int[MAX_DOTS];
43      int[] lengthArray = new int[MAX_DOTS];
44  
45      int dotCount = computeIndexes(fqClassName, dotArray);
46  
47      // System.out.println();
48      // System.out.println("Dot count for [" + className + "] is " + dotCount);
49      // if there are not dots than abbreviation is not possible
50      if (dotCount == 0) {
51        return fqClassName;
52      }
53      // printArray("dotArray: ", dotArray);
54      computeLengthArray(fqClassName, dotArray, lengthArray, dotCount);
55      // printArray("lengthArray: ", lengthArray);
56      for (int i = 0; i <= dotCount; i++) {
57        if (i == 0) {
58          buf.append(fqClassName.substring(0, lengthArray[i] - 1));
59        } else {
60          buf.append(fqClassName.substring(dotArray[i - 1], dotArray[i - 1]
61              + lengthArray[i]));
62        }
63        // System.out.println("i=" + i + ", buf=" + buf);
64      }
65  
66      return buf.toString();
67    }
68  
69  
70    static int computeIndexes(final String className, int[] dotArray) {
71      int dotCount = 0;
72      int k = 0;
73      while (true) {
74        k = className.indexOf(CoreConstants.DOT, k);
75        if (k != -1 && dotCount < MAX_DOTS) {
76          dotArray[dotCount] = k;
77          dotCount++;
78          k++;
79        } else {
80          break;
81        }
82      }
83      return dotCount;
84    }
85  
86    void computeLengthArray(final String className, int[] dotArray,
87        int[] lengthArray, int dotCount) {
88      int toTrim = className.length() - targetLength;
89      // System.out.println("toTrim=" + toTrim);
90  
91      // int toTrimAvarage = 0;
92  
93      int len;
94      for (int i = 0; i < dotCount; i++) {
95        int previousDotPosition = -1;
96        if (i > 0) {
97          previousDotPosition = dotArray[i - 1];
98        }
99        int available = dotArray[i] - previousDotPosition - 1;
100       // System.out.println("i=" + i + ", available = " + available);
101 
102       len = (available < 1) ? available : 1;
103       // System.out.println("i=" + i + ", toTrim = " + toTrim);
104 
105       if (toTrim > 0) {
106         len = (available < 1) ? available : 1;
107       } else {
108         len = available;
109       }
110       toTrim -= (available - len);
111       lengthArray[i] = len + 1;
112     }
113 
114     int lastDotIndex = dotCount - 1;
115     lengthArray[dotCount] = className.length() - dotArray[lastDotIndex];
116   }
117 
118   static void printArray(String msg, int[] ia) {
119     System.out.print(msg);
120     for (int i = 0; i < ia.length; i++) {
121       if (i == 0) {
122         System.out.print(ia[i]);
123       } else {
124         System.out.print(", " + ia[i]);
125       }
126     }
127     System.out.println();
128   }
129 }