1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package ch.qos.logback.core.model.processor;
16
17 import ch.qos.logback.core.Context;
18 import ch.qos.logback.core.joran.GenericXMLConfigurator;
19 import ch.qos.logback.core.joran.event.SaxEvent;
20 import ch.qos.logback.core.joran.event.SaxEventRecorder;
21 import ch.qos.logback.core.joran.spi.JoranException;
22 import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
23 import ch.qos.logback.core.model.IncludeModel;
24 import ch.qos.logback.core.model.Model;
25 import ch.qos.logback.core.spi.ContextAwarePropertyContainer;
26 import ch.qos.logback.core.spi.ErrorCodes;
27 import ch.qos.logback.core.util.Loader;
28 import ch.qos.logback.core.util.OptionHelper;
29
30 import java.io.File;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.net.MalformedURLException;
34 import java.net.URI;
35 import java.net.URL;
36 import java.util.List;
37 import java.util.function.Supplier;
38
39 import static ch.qos.logback.core.joran.JoranConstants.CONFIGURATION_TAG;
40 import static ch.qos.logback.core.joran.JoranConstants.INCLUDED_TAG;
41
42
43
44
45 public class IncludeModelHandler extends ResourceHandlerBase {
46 boolean inError = false;
47
48 public IncludeModelHandler(Context context) {
49 super(context);
50 }
51
52 static public IncludeModelHandler makeInstance(Context context, ModelInterpretationContext mic) {
53 return new IncludeModelHandler(context);
54 }
55
56 @Override
57 protected Class<IncludeModel> getSupportedModelClass() {
58 return IncludeModel.class;
59 }
60
61 @Override
62 public void handle(ModelInterpretationContext mic, Model model) throws ModelHandlerException {
63 IncludeModel includeModel = (IncludeModel) model;
64 Model modelFromIncludedFile = buildModelFromIncludedFile(mic, includeModel);
65 if (modelFromIncludedFile == null) {
66 warnIfRequired("Failed to build include model from included file");
67 return;
68 }
69 processModelFromIncludedFile(includeModel, modelFromIncludedFile);
70 }
71
72
73
74
75
76
77
78
79
80 public Model buildModelFromIncludedFile(ContextAwarePropertyContainer capc, IncludeModel includeModel) throws ModelHandlerException {
81
82 this.optional = OptionHelper.toBoolean(includeModel.getOptional(), false);
83
84 if (!checkAttributes(includeModel)) {
85 inError = true;
86 return null;
87 }
88
89 InputStream in = getInputStream(capc, includeModel);
90 if (in == null) {
91 inError = true;
92 return null;
93 }
94
95 SaxEventRecorder recorder = null;
96
97 try {
98 recorder = populateSaxEventRecorder(in);
99
100 List<SaxEvent> saxEvents = recorder.getSaxEventList();
101 if (saxEvents.isEmpty()) {
102 addWarn("Empty sax event list");
103 return null;
104 }
105
106 Supplier<? extends GenericXMLConfigurator> jcSupplier = capc.getConfiguratorSupplier();
107 if (jcSupplier == null) {
108 addError("null configurator supplier. Abandoning inclusion of [" + attributeInUse + "]");
109 inError = true;
110 return null;
111 }
112
113 GenericXMLConfigurator genericXMLConfigurator = jcSupplier.get();
114 genericXMLConfigurator.getRuleStore().addPathPathMapping(INCLUDED_TAG, CONFIGURATION_TAG);
115
116 Model modelFromIncludedFile = genericXMLConfigurator.buildModelFromSaxEventList(recorder.getSaxEventList());
117 return modelFromIncludedFile;
118 } catch (JoranException e) {
119 inError = true;
120 addError("Error processing XML data in [" + attributeInUse + "]", e);
121 return null;
122 }
123 }
124
125 private void processModelFromIncludedFile(IncludeModel includeModel, Model modelFromIncludedFile) {
126 includeModel.getSubModels().addAll(modelFromIncludedFile.getSubModels());
127 }
128
129 public SaxEventRecorder populateSaxEventRecorder(final InputStream inputStream) throws JoranException {
130 SaxEventRecorder recorder = new SaxEventRecorder(context);
131 recorder.recordEvents(inputStream);
132 return recorder;
133 }
134
135 private InputStream getInputStream(ContextAwarePropertyContainer capc, IncludeModel includeModel) {
136 URL inputURL = getInputURL(capc, includeModel);
137 if (inputURL == null)
138 return null;
139 ConfigurationWatchListUtil.addToWatchList(context, inputURL);
140 return openURL(inputURL);
141 }
142
143 }