1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.subst;
15
16 import ch.qos.logback.core.CoreConstants;
17 import ch.qos.logback.core.spi.ScanException;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 public class Tokenizer {
23
24 enum TokenizerState {
25 LITERAL_STATE, START_STATE, DEFAULT_VAL_STATE
26 }
27
28 final String pattern;
29 final int patternLength;
30
31 public Tokenizer(String pattern) {
32 this.pattern = pattern;
33 patternLength = pattern.length();
34 }
35
36 TokenizerState state = TokenizerState.LITERAL_STATE;
37 int pointer = 0;
38
39 List<Token> tokenize() throws ScanException {
40 List<Token> tokenList = new ArrayList<Token>();
41 StringBuilder buf = new StringBuilder();
42
43 while (pointer < patternLength) {
44 char c = pattern.charAt(pointer);
45 pointer++;
46
47 switch (state) {
48 case LITERAL_STATE:
49 handleLiteralState(c, tokenList, buf);
50 break;
51 case START_STATE:
52 handleStartState(c, tokenList, buf);
53 break;
54 case DEFAULT_VAL_STATE:
55 handleDefaultValueState(c, tokenList, buf);
56 default:
57 }
58 }
59
60 switch (state) {
61 case LITERAL_STATE:
62 addLiteralToken(tokenList, buf);
63 break;
64 case DEFAULT_VAL_STATE:
65
66 buf.append(CoreConstants.COLON_CHAR);
67 addLiteralToken(tokenList, buf);
68 break;
69 case START_STATE:
70
71 buf.append(CoreConstants.DOLLAR);
72 addLiteralToken(tokenList, buf);
73 break;
74 }
75 return tokenList;
76 }
77
78 private void handleDefaultValueState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
79 switch (c) {
80 case CoreConstants.DASH_CHAR:
81 tokenList.add(Token.DEFAULT_SEP_TOKEN);
82 state = TokenizerState.LITERAL_STATE;
83 break;
84 case CoreConstants.DOLLAR:
85 stringBuilder.append(CoreConstants.COLON_CHAR);
86 addLiteralToken(tokenList, stringBuilder);
87 stringBuilder.setLength(0);
88 state = TokenizerState.START_STATE;
89 break;
90 case CoreConstants.CURLY_LEFT:
91 stringBuilder.append(CoreConstants.COLON_CHAR);
92 addLiteralToken(tokenList, stringBuilder);
93 stringBuilder.setLength(0);
94 tokenList.add(Token.CURLY_LEFT_TOKEN);
95 state = TokenizerState.LITERAL_STATE;
96
97 break;
98 default:
99 stringBuilder.append(CoreConstants.COLON_CHAR).append(c);
100 state = TokenizerState.LITERAL_STATE;
101 break;
102 }
103 }
104
105 private void handleStartState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
106 if (c == CoreConstants.CURLY_LEFT) {
107 tokenList.add(Token.START_TOKEN);
108 } else {
109 stringBuilder.append(CoreConstants.DOLLAR).append(c);
110 }
111 state = TokenizerState.LITERAL_STATE;
112 }
113
114 private void handleLiteralState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
115 switch (c) {
116 case CoreConstants.DOLLAR:
117 addLiteralToken(tokenList, stringBuilder);
118 stringBuilder.setLength(0);
119 state = TokenizerState.START_STATE;
120 break;
121 case CoreConstants.COLON_CHAR:
122 addLiteralToken(tokenList, stringBuilder);
123 stringBuilder.setLength(0);
124 state = TokenizerState.DEFAULT_VAL_STATE;
125 break;
126 case CoreConstants.CURLY_LEFT:
127 addLiteralToken(tokenList, stringBuilder);
128 tokenList.add(Token.CURLY_LEFT_TOKEN);
129 stringBuilder.setLength(0);
130 break;
131 case CoreConstants.CURLY_RIGHT:
132 addLiteralToken(tokenList, stringBuilder);
133 tokenList.add(Token.CURLY_RIGHT_TOKEN);
134 stringBuilder.setLength(0);
135 break;
136 default:
137 stringBuilder.append(c);
138 }
139
140 }
141
142 private void addLiteralToken(List<Token> tokenList, StringBuilder stringBuilder) {
143 if (stringBuilder.length() == 0)
144 return;
145 tokenList.add(new Token(Token.Type.LITERAL, stringBuilder.toString()));
146 }
147
148 }