1
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 default:
91 stringBuilder.append(CoreConstants.COLON_CHAR).append(c);
92 state = TokenizerState.LITERAL_STATE;
93 break;
94 }
95 }
96
97 private void handleStartState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
98 if (c == CoreConstants.CURLY_LEFT) {
99 tokenList.add(Token.START_TOKEN);
100 } else {
101 stringBuilder.append(CoreConstants.DOLLAR).append(c);
102 }
103 state = TokenizerState.LITERAL_STATE;
104 }
105
106 private void handleLiteralState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
107 if (c == CoreConstants.DOLLAR) {
108 addLiteralToken(tokenList, stringBuilder);
109 stringBuilder.setLength(0);
110 state = TokenizerState.START_STATE;
111 } else if (c == CoreConstants.COLON_CHAR) {
112 addLiteralToken(tokenList, stringBuilder);
113 stringBuilder.setLength(0);
114 state = TokenizerState.DEFAULT_VAL_STATE;
115 } else if (c == CoreConstants.CURLY_LEFT) {
116 addLiteralToken(tokenList, stringBuilder);
117 tokenList.add(Token.CURLY_LEFT_TOKEN);
118 stringBuilder.setLength(0);
119 } else if (c == CoreConstants.CURLY_RIGHT) {
120 addLiteralToken(tokenList, stringBuilder);
121 tokenList.add(Token.CURLY_RIGHT_TOKEN);
122 stringBuilder.setLength(0);
123 } else {
124 stringBuilder.append(c);
125 }
126
127 }
128
129 private void addLiteralToken(List<Token> tokenList, StringBuilder stringBuilder) {
130 if (stringBuilder.length() == 0)
131 return;
132 tokenList.add(new Token(Token.Type.LITERAL, stringBuilder.toString()));
133 }
134
135 }
136