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 ch.qos.logback.classic.ClassicConstants;
17 import ch.qos.logback.core.CoreConstants;
18
19 public class TargetLengthBasedClassNameAbbreviator2 implements Abbreviator {
20
21 final int targetLength;
22
23 public TargetLengthBasedClassNameAbbreviator2(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/LOGBACK-437
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 no dots than abbreviation is not possible
48 if (dotCount == 0) {
49 return fqClassName;
50 }
51 // printArray("dotArray: ", dotIndexesArray);
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], dotIndexesArray[i - 1] + lengthArray[i]));
59 }
60 // System.out.println("i=" + i + ", buf=" + buf);
61 }
62
63 return buf.toString();
64 }
65
66 /**
67 * Populate dotArray with the positions of the DOT character in className.
68 * Leftmost dot is placed at index 0 of dotArray.
69 *
70 * @param className
71 * @param dotArray
72 * @return the number of dots found
73 */
74 static int computeDotIndexes(final String className, int[] dotArray) {
75 int dotCount = 0;
76 int k = 0;
77 while (true) {
78 // ignore the $ separator in our computations. This is both convenient
79 // and sensible.
80 k = className.indexOf(CoreConstants.DOT, k);
81 if (k != -1 && dotCount < ClassicConstants.MAX_DOTS) {
82 dotArray[dotCount] = k;
83 dotCount++;
84 k++; // move past the last found DOT
85 } else {
86 break;
87 }
88 }
89 return dotCount;
90 }
91
92 void computeLengthArray(final String className, int[] dotArray, int[] lengthArray, int dotCount) {
93 int toTrim = className.length() - targetLength;
94 // System.out.println("dotCount=" + dotCount);
95
96 int len;
97 for (int i = 0; i < dotCount; i++) {
98 // System.out.println("i=" + i + ", toTrim = " + toTrim);
99
100 // if i==0, previousDotPosition = -1, otherwise dotArray[i - 1]
101 int previousDotPosition = (i == 0) ? -1 : dotArray[i - 1];
102 // System.out.println("i="+i+ " previousDotPosition="+previousDotPosition);
103
104 // number of characters within the segment, i.e/ within the previous dot
105 // position and the current dot position
106 int charactersInSegment = dotArray[i] - previousDotPosition - 1;
107 // System.out.println("i=" + i + ", charactersInSegment = " +
108 // charactersInSegment);
109
110 if (toTrim > 0) {
111 len = (charactersInSegment < 1) ? charactersInSegment : 1;
112 } else {
113 len = charactersInSegment;
114 }
115 // System.out.println("i=" + i + ", len = " + len);
116
117 toTrim -= (charactersInSegment - len);
118 lengthArray[i] = len + 1;
119 }
120
121 int lastDotIndex = dotCount - 1;
122 lengthArray[dotCount] = className.length() - dotArray[lastDotIndex];
123 }
124
125 static void printArray(String msg, int[] ia) {
126 System.out.print(msg);
127 for (int i = 0; i < ia.length; i++) {
128 if (i == 0) {
129 System.out.print(ia[i]);
130 } else {
131 System.out.print(", " + ia[i]);
132 }
133 }
134 System.out.println();
135 }
136 }