View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, 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 static ch.qos.logback.core.CoreConstants.DOT;
17  
18  public class TargetLengthBasedClassNameAbbreviator implements Abbreviator {
19  
20      final int targetLength;
21  
22      public TargetLengthBasedClassNameAbbreviator(int targetLength) {
23          this.targetLength = targetLength;
24      }
25  
26      public String abbreviate(String fqClassName) {
27          if (fqClassName == null) {
28              throw new IllegalArgumentException("Class name may not be null");
29          }
30  
31          int inLen = fqClassName.length();
32          if (inLen < targetLength) {
33              return fqClassName;
34          }
35  
36          StringBuilder buf = new StringBuilder(inLen);
37  
38          int rightMostDotIndex = fqClassName.lastIndexOf(DOT);
39  
40          if (rightMostDotIndex == -1)
41              return fqClassName;
42  
43          // length of last segment including the dot
44          int lastSegmentLength = inLen - rightMostDotIndex;
45  
46          int leftSegments_TargetLen = targetLength - lastSegmentLength;
47          if (leftSegments_TargetLen < 0)
48              leftSegments_TargetLen = 0;
49  
50          int leftSegmentsLen = inLen - lastSegmentLength;
51  
52          // maxPossibleTrim denotes the maximum number of characters we aim to trim
53          // the actual number of character trimmed may be higher since segments, when
54          // reduced, are reduced to just one character
55          int maxPossibleTrim = leftSegmentsLen - leftSegments_TargetLen;
56  
57          int trimmed = 0;
58          boolean inDotState = true;
59  
60          int i = 0;
61          for (; i < rightMostDotIndex; i++) {
62              char c = fqClassName.charAt(i);
63              if (c == DOT) {
64                  // if trimmed too many characters, let us stop
65                  if (trimmed >= maxPossibleTrim)
66                      break;
67                  buf.append(c);
68                  inDotState = true;
69              } else {
70                  if (inDotState) {
71                      buf.append(c);
72                      inDotState = false;
73                  } else {
74                      trimmed++;
75                  }
76              }
77          }
78          // append from the position of i which may include the last seen DOT
79          buf.append(fqClassName.substring(i));
80          return buf.toString();
81      }
82  }