View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.classic.pattern;
15  
16  import ch.qos.logback.classic.ClassicConstants;
17  import ch.qos.logback.core.CoreConstants;
18  
19  public class TargetLengthBasedClassNameAbbreviator implements Abbreviator {
20  
21    final int targetLength;
22  
23    public TargetLengthBasedClassNameAbbreviator(int targetLength) {
24      this.targetLength = targetLength;
25    }
26  
27    public String abbreviate(String fqClassName) {
28      StringBuilder buf = new StringBuilder(targetLength);
29      if (fqClassName == null) {
30        throw new IllegalArgumentException("Class name may not be null");
31      }
32  
33      int inLen = fqClassName.length();
34      if (inLen < targetLength) {
35        return fqClassName;
36      }
37  
38      int[] dotIndexesArray = new int[ClassicConstants.MAX_DOTS];
39      // a.b.c contains 2 dots but 2+1 parts.
40      // see also http://jira.qos.ch/browse/LBCLASSIC-110
41      int[] lengthArray = new int[ClassicConstants.MAX_DOTS + 1];
42  
43      int dotCount = computeDotIndexes(fqClassName, dotIndexesArray);
44  
45      // System.out.println();
46      // System.out.println("Dot count for [" + className + "] is " + dotCount);
47      // if there are not dots than abbreviation is not possible
48      if (dotCount == 0) {
49        return fqClassName;
50      }
51      // printArray("dotArray: ", dotArray);
52      computeLengthArray(fqClassName, dotIndexesArray, lengthArray, dotCount);
53      // printArray("lengthArray: ", lengthArray);
54      for (int i = 0; i <= dotCount; i++) {
55        if (i == 0) {
56          buf.append(fqClassName.substring(0, lengthArray[i] - 1));
57        } else {
58          buf.append(fqClassName.substring(dotIndexesArray[i - 1],
59              dotIndexesArray[i - 1] + lengthArray[i]));
60        }
61        // System.out.println("i=" + i + ", buf=" + buf);
62      }
63  
64      return buf.toString();
65    }
66  
67    static int computeDotIndexes(final String className, int[] dotArray) {
68      int dotCount = 0;
69      int k = 0;
70      while (true) {
71        // ignore the $ separator in our computations. This is both convenient
72        // and sensible.
73        k = className.indexOf(CoreConstants.DOT, k);
74        if (k != -1 && dotCount < ClassicConstants.MAX_DOTS) {
75          dotArray[dotCount] = k;
76          dotCount++;
77          k++;
78        } else {
79          break;
80        }
81      }
82      return dotCount;
83    }
84  
85    void computeLengthArray(final String className, int[] dotArray,
86        int[] lengthArray, int dotCount) {
87      int toTrim = className.length() - targetLength;
88      // System.out.println("toTrim=" + toTrim);
89  
90      // int toTrimAvarage = 0;
91  
92      int len;
93      for (int i = 0; i < dotCount; i++) {
94        int previousDotPosition = -1;
95        if (i > 0) {
96          previousDotPosition = dotArray[i - 1];
97        }
98        int available = dotArray[i] - previousDotPosition - 1;
99        // System.out.println("i=" + i + ", available = " + available);
100 
101       len = (available < 1) ? available : 1;
102       // System.out.println("i=" + i + ", toTrim = " + toTrim);
103 
104       if (toTrim > 0) {
105         len = (available < 1) ? available : 1;
106       } else {
107         len = available;
108       }
109       toTrim -= (available - len);
110       lengthArray[i] = len + 1;
111     }
112 
113     int lastDotIndex = dotCount - 1;
114     lengthArray[dotCount] = className.length() - dotArray[lastDotIndex];
115   }
116 
117   static void printArray(String msg, int[] ia) {
118     System.out.print(msg);
119     for (int i = 0; i < ia.length; i++) {
120       if (i == 0) {
121         System.out.print(ia[i]);
122       } else {
123         System.out.print(", " + ia[i]);
124       }
125     }
126     System.out.println();
127   }
128 }