1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.pattern.parser;
15
16 import java.util.Map;
17 import java.util.function.Supplier;
18
19 import ch.qos.logback.core.pattern.CompositeConverter;
20 import ch.qos.logback.core.pattern.Converter;
21 import ch.qos.logback.core.pattern.DynamicConverter;
22 import ch.qos.logback.core.pattern.LiteralConverter;
23 import ch.qos.logback.core.spi.ContextAwareBase;
24 import ch.qos.logback.core.status.ErrorStatus;
25 import ch.qos.logback.core.util.OptionHelper;
26
27 class Compiler<E> extends ContextAwareBase {
28
29 Converter<E> head;
30 Converter<E> tail;
31 final Node top;
32 final Map<String, Supplier<DynamicConverter>> converterMap;
33
34 Compiler(final Node top, final Map<String, Supplier<DynamicConverter>> converterMap) {
35 this.top = top;
36 this.converterMap = converterMap;
37 }
38
39 Converter<E> compile() {
40 head = tail = null;
41 for (Node n = top; n != null; n = n.next) {
42 switch (n.type) {
43 case Node.LITERAL:
44 addToList(new LiteralConverter<E>((String) n.getValue()));
45 break;
46 case Node.COMPOSITE_KEYWORD:
47 CompositeNode cn = (CompositeNode) n;
48 CompositeConverter<E> compositeConverter = createCompositeConverter(cn);
49 if (compositeConverter == null) {
50 addError("Failed to create converter for [%" + cn.getValue() + "] keyword");
51 addToList(new LiteralConverter<E>("%PARSER_ERROR[" + cn.getValue() + "]"));
52 break;
53 }
54 compositeConverter.setFormattingInfo(cn.getFormatInfo());
55 compositeConverter.setOptionList(cn.getOptions());
56 Compiler<E> childCompiler = new Compiler<E>(cn.getChildNode(), converterMap);
57 childCompiler.setContext(context);
58 Converter<E> childConverter = childCompiler.compile();
59 compositeConverter.setChildConverter(childConverter);
60 addToList(compositeConverter);
61 break;
62 case Node.SIMPLE_KEYWORD:
63 SimpleKeywordNode kn = (SimpleKeywordNode) n;
64 DynamicConverter<E> dynaConverter = createConverter(kn);
65 if (dynaConverter != null) {
66 dynaConverter.setFormattingInfo(kn.getFormatInfo());
67 dynaConverter.setOptionList(kn.getOptions());
68 addToList(dynaConverter);
69 } else {
70
71
72 Converter<E> errConveter = new LiteralConverter<E>("%PARSER_ERROR[" + kn.getValue() + "]");
73 addStatus(new ErrorStatus("[" + kn.getValue() + "] is not a valid conversion word", this));
74 addToList(errConveter);
75 }
76
77 }
78 }
79 return head;
80 }
81
82 private void addToList(Converter<E> c) {
83 if (head == null) {
84 head = tail = c;
85 } else {
86 tail.setNext(c);
87 tail = c;
88 }
89 }
90
91
92
93
94
95
96
97 @SuppressWarnings("unchecked")
98 DynamicConverter<E> createConverter(SimpleKeywordNode kn) {
99 String keyword = (String) kn.getValue();
100 Supplier<DynamicConverter> supplier = converterMap.get(keyword);
101
102 if (supplier != null) {
103 return supplier.get();
104 } else {
105 addError("There is no conversion supplier registered for conversion word [" + keyword + "]");
106 return null;
107 }
108 }
109
110
111
112
113
114
115
116
117 @SuppressWarnings("unchecked")
118 CompositeConverter<E> createCompositeConverter(CompositeNode cn) {
119 String keyword = (String) cn.getValue();
120 Supplier<DynamicConverter> supplier = (Supplier<DynamicConverter>) converterMap.get(keyword);
121
122 if (supplier != null) {
123 try {
124 return (CompositeConverter) supplier.get();
125 } catch(ClassCastException e) {
126 addError("Failed to cast as CompositeConverter for keyword [" + keyword + "]", e);
127 return null;
128 }
129 } else {
130 addError("There is no conversion class registered for composite conversion word [" + keyword + "]");
131 return null;
132 }
133 }
134
135
136
137
138
139
140
141
142
143
144 }