1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.rolling.helper;
15
16 import java.time.Instant;
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.Map;
20 import java.util.function.Supplier;
21
22 import ch.qos.logback.core.Context;
23 import ch.qos.logback.core.pattern.Converter;
24 import ch.qos.logback.core.pattern.ConverterUtil;
25 import ch.qos.logback.core.pattern.DynamicConverter;
26 import ch.qos.logback.core.pattern.LiteralConverter;
27 import ch.qos.logback.core.pattern.parser.Node;
28 import ch.qos.logback.core.pattern.parser.Parser;
29 import ch.qos.logback.core.spi.ScanException;
30 import ch.qos.logback.core.pattern.util.AlmostAsIsEscapeUtil;
31 import ch.qos.logback.core.spi.ContextAwareBase;
32
33
34
35
36
37
38
39
40
41 public class FileNamePattern extends ContextAwareBase {
42
43 static final Map<String, Supplier<DynamicConverter>> CONVERTER_MAP = new HashMap<>();
44 static {
45 CONVERTER_MAP.put(IntegerTokenConverter.CONVERTER_KEY, IntegerTokenConverter::new);
46 CONVERTER_MAP.put(DateTokenConverter.CONVERTER_KEY, DateTokenConverter::new);
47 }
48
49 String pattern;
50 Converter<Object> headTokenConverter;
51
52 public FileNamePattern(String patternArg, Context contextArg) {
53
54 setPattern(FileFilterUtil.slashify(patternArg));
55 setContext(contextArg);
56 parse();
57 ConverterUtil.startConverters(this.headTokenConverter);
58 }
59
60 void parse() {
61 try {
62
63
64
65
66
67
68 String patternForParsing = escapeRightParantesis(pattern);
69 Parser<Object> p = new Parser<Object>(patternForParsing, new AlmostAsIsEscapeUtil());
70 p.setContext(context);
71 Node t = p.parse();
72 this.headTokenConverter = p.compile(t, CONVERTER_MAP);
73
74 } catch (ScanException sce) {
75 addError("Failed to parse pattern \"" + pattern + "\".", sce);
76 }
77 }
78
79 String escapeRightParantesis(String in) {
80 return pattern.replace(")", "\\)");
81 }
82
83 public String toString() {
84 return pattern;
85 }
86
87 @Override
88 public int hashCode() {
89 final int prime = 31;
90 int result = 1;
91 result = prime * result + ((pattern == null) ? 0 : pattern.hashCode());
92 return result;
93 }
94
95 @Override
96 public boolean equals(Object obj) {
97 if (this == obj)
98 return true;
99 if (obj == null)
100 return false;
101 if (getClass() != obj.getClass())
102 return false;
103 FileNamePattern other = (FileNamePattern) obj;
104 if (pattern == null) {
105 if (other.pattern != null)
106 return false;
107 } else if (!pattern.equals(other.pattern))
108 return false;
109 return true;
110 }
111
112 public DateTokenConverter<Object> getPrimaryDateTokenConverter() {
113 Converter<Object> p = headTokenConverter;
114
115 while (p != null) {
116 if (p instanceof DateTokenConverter) {
117 DateTokenConverter<Object> dtc = (DateTokenConverter<Object>) p;
118
119 if (dtc.isPrimary())
120 return dtc;
121 }
122
123 p = p.getNext();
124 }
125
126 return null;
127 }
128
129 public IntegerTokenConverter getIntegerTokenConverter() {
130 Converter<Object> p = headTokenConverter;
131
132 while (p != null) {
133 if (p instanceof IntegerTokenConverter) {
134 return (IntegerTokenConverter) p;
135 }
136
137 p = p.getNext();
138 }
139 return null;
140 }
141
142 public boolean hasIntegerTokenCOnverter() {
143 IntegerTokenConverter itc = getIntegerTokenConverter();
144 return itc != null;
145 }
146
147 public String convertMultipleArguments(Object... objectList) {
148 StringBuilder buf = new StringBuilder();
149 Converter<Object> c = headTokenConverter;
150 while (c != null) {
151 if (c instanceof MonoTypedConverter) {
152 MonoTypedConverter monoTyped = (MonoTypedConverter) c;
153 for (Object o : objectList) {
154 if (monoTyped.isApplicable(o)) {
155 buf.append(c.convert(o));
156 }
157 }
158 } else {
159 buf.append(c.convert(objectList));
160 }
161 c = c.getNext();
162 }
163 return buf.toString();
164 }
165
166 public String convert(Object o) {
167 StringBuilder buf = new StringBuilder();
168 Converter<Object> p = headTokenConverter;
169 while (p != null) {
170 buf.append(p.convert(o));
171 p = p.getNext();
172 }
173 return buf.toString();
174 }
175
176 public String convertInt(int i) {
177 return convert(i);
178 }
179
180 public void setPattern(String pattern) {
181 if (pattern != null) {
182
183 this.pattern = pattern.trim();
184 }
185 }
186
187 public String getPattern() {
188 return pattern;
189 }
190
191
192
193
194
195
196
197
198
199 public String toRegexForFixedDate(Date date) {
200 StringBuilder buf = new StringBuilder();
201 Converter<Object> p = headTokenConverter;
202 while (p != null) {
203 if (p instanceof LiteralConverter) {
204 buf.append(p.convert(null));
205 } else if (p instanceof IntegerTokenConverter) {
206 buf.append("(\\d+)");
207 } else if (p instanceof DateTokenConverter) {
208 buf.append(p.convert(date));
209 }
210 p = p.getNext();
211 }
212 return buf.toString();
213 }
214
215
216
217
218
219
220
221
222
223
224 public String toRegexForFixedDate(Instant instant) {
225 StringBuilder buf = new StringBuilder();
226 Converter<Object> p = headTokenConverter;
227 while (p != null) {
228 if (p instanceof LiteralConverter) {
229 buf.append(p.convert(null));
230 } else if (p instanceof IntegerTokenConverter) {
231 buf.append("(\\d+)");
232 } else if (p instanceof DateTokenConverter) {
233 buf.append(p.convert(instant));
234 }
235 p = p.getNext();
236 }
237 return buf.toString();
238 }
239
240
241
242
243
244 public String toRegex() {
245 StringBuilder buf = new StringBuilder();
246 Converter<Object> p = headTokenConverter;
247 while (p != null) {
248 if (p instanceof LiteralConverter) {
249 buf.append(p.convert(null));
250 } else if (p instanceof IntegerTokenConverter) {
251 buf.append("\\d+");
252 } else if (p instanceof DateTokenConverter) {
253 DateTokenConverter<Object> dtc = (DateTokenConverter<Object>) p;
254 buf.append(dtc.toRegex());
255 }
256 p = p.getNext();
257 }
258 return buf.toString();
259 }
260 }