1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.generator.config.xml;
17
18 import static org.mybatis.generator.internal.util.messages.Messages.getString;
19
20 import java.io.File;
21 import java.io.FileReader;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.Reader;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Properties;
28
29 import javax.xml.XMLConstants;
30 import javax.xml.parsers.DocumentBuilder;
31 import javax.xml.parsers.DocumentBuilderFactory;
32 import javax.xml.parsers.ParserConfigurationException;
33
34 import org.mybatis.generator.codegen.XmlConstants;
35 import org.mybatis.generator.config.Configuration;
36 import org.mybatis.generator.exception.XMLParserException;
37 import org.w3c.dom.Document;
38 import org.w3c.dom.DocumentType;
39 import org.w3c.dom.Element;
40 import org.w3c.dom.Node;
41 import org.xml.sax.InputSource;
42 import org.xml.sax.SAXException;
43 import org.xml.sax.SAXParseException;
44
45 public class ConfigurationParser {
46
47 private final List<String> warnings;
48 private final List<String> parseErrors;
49 private final Properties extraProperties;
50
51 public ConfigurationParser(List<String> warnings) {
52 this(null, warnings);
53 }
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 public ConfigurationParser(Properties extraProperties, List<String> warnings) {
76 super();
77 this.extraProperties = extraProperties;
78
79 if (warnings == null) {
80 this.warnings = new ArrayList<>();
81 } else {
82 this.warnings = warnings;
83 }
84
85 parseErrors = new ArrayList<>();
86 }
87
88 public Configuration parseConfiguration(File inputFile) throws IOException,
89 XMLParserException {
90
91 FileReader fr = new FileReader(inputFile);
92
93 return parseConfiguration(fr);
94 }
95
96 public Configuration parseConfiguration(Reader reader) throws IOException,
97 XMLParserException {
98
99 InputSource is = new InputSource(reader);
100
101 return parseConfiguration(is);
102 }
103
104 public Configuration parseConfiguration(InputStream inputStream)
105 throws IOException, XMLParserException {
106
107 InputSource is = new InputSource(inputStream);
108
109 return parseConfiguration(is);
110 }
111
112 private Configuration parseConfiguration(InputSource inputSource)
113 throws IOException, XMLParserException {
114 parseErrors.clear();
115 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
116 factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
117 factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
118 factory.setValidating(true);
119
120 try {
121 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
122 DocumentBuilder builder = factory.newDocumentBuilder();
123 builder.setEntityResolver(new ParserEntityResolver());
124
125 ParserErrorHandler handler = new ParserErrorHandler(warnings,
126 parseErrors);
127 builder.setErrorHandler(handler);
128
129 Document document = null;
130 try {
131 document = builder.parse(inputSource);
132 } catch (SAXParseException e) {
133 throw new XMLParserException(parseErrors);
134 } catch (SAXException e) {
135 if (e.getException() == null) {
136 parseErrors.add(e.getMessage());
137 } else {
138 parseErrors.add(e.getException().getMessage());
139 }
140 }
141
142 if (document == null || !parseErrors.isEmpty()) {
143 throw new XMLParserException(parseErrors);
144 }
145
146 Configuration config;
147 Element rootNode = document.getDocumentElement();
148 DocumentType docType = document.getDoctype();
149 if (rootNode.getNodeType() == Node.ELEMENT_NODE
150 && docType.getPublicId().equals(
151 XmlConstants.MYBATIS_GENERATOR_CONFIG_PUBLIC_ID)) {
152 config = parseMyBatisGeneratorConfiguration(rootNode);
153 } else {
154 throw new XMLParserException(getString("RuntimeError.5"));
155 }
156
157 if (!parseErrors.isEmpty()) {
158 throw new XMLParserException(parseErrors);
159 }
160
161 return config;
162 } catch (ParserConfigurationException e) {
163 parseErrors.add(e.getMessage());
164 throw new XMLParserException(parseErrors);
165 }
166 }
167
168 private Configuration parseMyBatisGeneratorConfiguration(Element rootNode)
169 throws XMLParserException {
170 MyBatisGeneratorConfigurationParser parser = new MyBatisGeneratorConfigurationParser(
171 extraProperties);
172 return parser.parseConfiguration(rootNode);
173 }
174 }