1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.meta;
21
22 import java.io.File;
23 import java.util.List;
24 import java.util.Locale;
25 import java.util.regex.Pattern;
26
27 import javax.xml.XMLConstants;
28 import javax.xml.parsers.DocumentBuilder;
29 import javax.xml.parsers.DocumentBuilderFactory;
30 import javax.xml.parsers.ParserConfigurationException;
31 import javax.xml.transform.OutputKeys;
32 import javax.xml.transform.Transformer;
33 import javax.xml.transform.TransformerException;
34 import javax.xml.transform.TransformerFactory;
35 import javax.xml.transform.dom.DOMSource;
36 import javax.xml.transform.stream.StreamResult;
37
38 import org.w3c.dom.Document;
39 import org.w3c.dom.Element;
40 import org.w3c.dom.Node;
41
42
43
44
45 public final class XmlMetaWriter {
46
47
48 private static final Pattern FILEPATH_CONVERSION = Pattern.compile("\\.");
49
50
51 private static final String XML_TAG_NAME = "name";
52
53
54 private static final String XML_TAG_DESCRIPTION = "description";
55
56
57 private static final String DEFAULT_FILE_SEPARATOR = "/";
58
59
60
61
62 private XmlMetaWriter() {
63 }
64
65
66
67
68
69
70
71
72 public static void write(ModuleDetails moduleDetails) throws TransformerException,
73 ParserConfigurationException {
74 final DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
75 dbFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
76 dbFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
77 final DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
78 final Document doc = dBuilder.newDocument();
79
80 final Element rootElement = doc.createElement("checkstyle-metadata");
81 final Element rootChild = doc.createElement("module");
82 rootElement.appendChild(rootChild);
83
84 doc.appendChild(rootElement);
85
86 final Element checkModule = doc.createElement(moduleDetails.getModuleType().getLabel());
87 rootChild.appendChild(checkModule);
88
89 checkModule.setAttribute(XML_TAG_NAME, moduleDetails.getName());
90 checkModule.setAttribute("fully-qualified-name",
91 moduleDetails.getFullQualifiedName());
92 checkModule.setAttribute("parent", moduleDetails.getParent());
93
94 final Element desc = doc.createElement(XML_TAG_DESCRIPTION);
95 final Node cdataDesc = doc.createCDATASection(moduleDetails.getDescription());
96 desc.appendChild(cdataDesc);
97 checkModule.appendChild(desc);
98 createPropertySection(moduleDetails, checkModule, doc);
99 if (!moduleDetails.getViolationMessageKeys().isEmpty()) {
100 final Element messageKeys = doc.createElement("message-keys");
101 for (String msg : moduleDetails.getViolationMessageKeys()) {
102 final Element messageKey = doc.createElement("message-key");
103 messageKey.setAttribute("key", msg);
104 messageKeys.appendChild(messageKey);
105 }
106 checkModule.appendChild(messageKeys);
107 }
108
109 writeToFile(doc, moduleDetails);
110 }
111
112
113
114
115
116
117
118
119 private static void createPropertySection(ModuleDetails moduleDetails, Element checkModule,
120 Document doc) {
121 final List<ModulePropertyDetails> moduleProperties = moduleDetails.getProperties();
122 if (!moduleProperties.isEmpty()) {
123 final Element properties = doc.createElement("properties");
124 checkModule.appendChild(properties);
125 for (ModulePropertyDetails modulePropertyDetails : moduleProperties) {
126 final Element property = doc.createElement("property");
127 properties.appendChild(property);
128 property.setAttribute(XML_TAG_NAME, modulePropertyDetails.getName());
129 property.setAttribute("type", modulePropertyDetails.getType());
130 final String defaultValue = modulePropertyDetails.getDefaultValue();
131 if (defaultValue != null) {
132 property.setAttribute("default-value", defaultValue);
133 }
134 final String validationType = modulePropertyDetails.getValidationType();
135 if (validationType != null) {
136 property.setAttribute("validation-type", validationType);
137 }
138 final Element propertyDesc = doc.createElement(XML_TAG_DESCRIPTION);
139 propertyDesc.appendChild(doc.createCDATASection(
140 modulePropertyDetails.getDescription()));
141 property.appendChild(propertyDesc);
142 }
143 }
144 }
145
146
147
148
149
150
151
152
153 private static void writeToFile(Document document, ModuleDetails moduleDetails)
154 throws TransformerException {
155 String fileSeparator = DEFAULT_FILE_SEPARATOR;
156 if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("win")) {
157 fileSeparator = "\\" + fileSeparator;
158 }
159 final String modifiedPath;
160 final String xmlExtension = ".xml";
161 final String rootOutputPath = System.getProperty("user.dir") + "/src/main/resources";
162 if (moduleDetails.getFullQualifiedName().startsWith("com.puppycrawl.tools.checkstyle")) {
163 final String moduleFilePath = FILEPATH_CONVERSION
164 .matcher(moduleDetails.getFullQualifiedName())
165 .replaceAll(fileSeparator);
166 final String checkstyleString = "checkstyle";
167 final int indexOfCheckstyle =
168 moduleFilePath.indexOf(checkstyleString) + checkstyleString.length();
169
170 modifiedPath = rootOutputPath + DEFAULT_FILE_SEPARATOR
171 + moduleFilePath.substring(0, indexOfCheckstyle) + "/meta/"
172 + moduleFilePath.substring(indexOfCheckstyle + 1) + xmlExtension;
173 }
174 else {
175 String moduleName = moduleDetails.getName();
176 if (moduleDetails.getModuleType() == ModuleType.CHECK) {
177 moduleName += "Check";
178 }
179 modifiedPath = rootOutputPath + "/checkstylemeta-" + moduleName + xmlExtension;
180 }
181
182 final TransformerFactory transformerFactory = TransformerFactory.newInstance();
183 final Transformer transformer = transformerFactory.newTransformer();
184 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
185 transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
186
187 final DOMSource source = new DOMSource(document);
188 final StreamResult result = new StreamResult(new File(modifiedPath));
189 transformer.transform(source, result);
190
191 }
192 }
193