-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
437 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
187 changes: 187 additions & 0 deletions
187
src/main/java/com/github/checkstyle/regression/configuration/ConfigGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
//////////////////////////////////////////////////////////////////////////////// | ||
// checkstyle: Checks Java source code for adherence to a set of rules. | ||
// Copyright (C) 2001-2017 the original author or authors. | ||
// | ||
// This library is free software; you can redistribute it and/or | ||
// modify it under the terms of the GNU Lesser General Public | ||
// License as published by the Free Software Foundation; either | ||
// version 2.1 of the License, or (at your option) any later version. | ||
// | ||
// This library is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
// Lesser General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU Lesser General Public | ||
// License along with this library; if not, write to the Free Software | ||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
package com.github.checkstyle.regression.configuration; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.io.StringWriter; | ||
import java.util.List; | ||
|
||
import javax.xml.parsers.DocumentBuilderFactory; | ||
import javax.xml.parsers.ParserConfigurationException; | ||
import javax.xml.transform.OutputKeys; | ||
import javax.xml.transform.Transformer; | ||
import javax.xml.transform.TransformerConfigurationException; | ||
import javax.xml.transform.TransformerException; | ||
import javax.xml.transform.TransformerFactory; | ||
import javax.xml.transform.dom.DOMSource; | ||
import javax.xml.transform.stream.StreamResult; | ||
|
||
import org.w3c.dom.Document; | ||
import org.w3c.dom.Element; | ||
import org.w3c.dom.Node; | ||
import org.w3c.dom.NodeList; | ||
import org.xml.sax.SAXException; | ||
|
||
import com.github.checkstyle.regression.data.ModuleInfo; | ||
|
||
/** | ||
* Generates the config XML and output it to a specific file. | ||
* @author LuoLiangchen | ||
*/ | ||
public final class ConfigGenerator { | ||
/** The parent name "Checker". */ | ||
private static final String PARENT_CHECKER = "Checker"; | ||
|
||
/** The parent name "TreeWalker". */ | ||
private static final String PARENT_TREE_WALKER = "TreeWalker"; | ||
|
||
/** The name of a module element. */ | ||
private static final String ELEMENT_MODULE = "module"; | ||
|
||
/** The attribute name "name". */ | ||
private static final String ATTR_NAME = "name"; | ||
|
||
/** The "doctype-public" value of the config. */ | ||
private static final String DOCTYPE_PUBLIC = | ||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"; | ||
|
||
/** The "doctype-system" value of the config. */ | ||
private static final String DOCTYPE_SYSTEM = | ||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd"; | ||
|
||
/** Prevents instantiation. */ | ||
private ConfigGenerator() { | ||
} | ||
|
||
/** | ||
* Creates a new {@link Document} instance from the {@code BASE_CONFIG}. | ||
* @return a new {@link Document} instance | ||
*/ | ||
private static Document createXmlDocument() { | ||
final Document document; | ||
|
||
try { | ||
final File baseConfig = new File("src/main/resources/com/github/checkstyle/regression/" | ||
+ "configuration/base_config.xml"); | ||
document = DocumentBuilderFactory.newInstance().newDocumentBuilder() | ||
.parse(baseConfig); | ||
} | ||
catch (ParserConfigurationException | SAXException | IOException ex) { | ||
throw new IllegalStateException("cannot instantiate Document instance", ex); | ||
} | ||
|
||
return document; | ||
} | ||
|
||
/** | ||
* Creates a new {@link Transformer} instance and do initialization. | ||
* @return a new {@link Transformer} instance | ||
*/ | ||
private static Transformer createXmlTransformer() { | ||
final Transformer transformer; | ||
|
||
try { | ||
transformer = TransformerFactory.newInstance().newTransformer(); | ||
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); | ||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); | ||
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, DOCTYPE_PUBLIC); | ||
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, DOCTYPE_SYSTEM); | ||
} | ||
catch (TransformerConfigurationException ex) { | ||
throw new IllegalStateException("cannot instantiate Transformer instance", ex); | ||
} | ||
|
||
return transformer; | ||
} | ||
|
||
/** | ||
* Generates the plain text of the config XML from the given module infos. | ||
* @param moduleInfos the given module infos | ||
* @return the generated plain text of the config | ||
* @throws TransformerException failure of transforming the XML document | ||
*/ | ||
public static String generateConfigText(List<ModuleInfo> moduleInfos) | ||
throws TransformerException { | ||
final Document document = createXmlDocument(); | ||
|
||
final Node checkerNode = getCheckerModuleNode(document); | ||
final Node treeWalkerNode = getTreeWalkerModuleNode(document); | ||
for (ModuleInfo moduleInfo : moduleInfos) { | ||
final Node moduleNode = createModuleNode(document, moduleInfo); | ||
final String parent = moduleInfo.moduleExtractInfo().parent(); | ||
if (PARENT_CHECKER.equals(parent)) { | ||
checkerNode.appendChild(moduleNode); | ||
} | ||
else if (PARENT_TREE_WALKER.equals(parent)) { | ||
treeWalkerNode.appendChild(moduleNode); | ||
} | ||
} | ||
|
||
final Transformer transformer = createXmlTransformer(); | ||
final StringWriter writer = new StringWriter(); | ||
transformer.transform(new DOMSource(document), new StreamResult(writer)); | ||
return writer.getBuffer().toString().replaceAll("\r\n", "\n"); | ||
} | ||
|
||
/** | ||
* Creates a XML element node which represents the settings of a checkstyle module. | ||
* The information to create the node is grabbed from the given module info. | ||
* @param document the XML document to create element | ||
* @param moduleInfo the given module info | ||
* @return a checkstyle module node | ||
*/ | ||
private static Node createModuleNode(Document document, ModuleInfo moduleInfo) { | ||
final Element moduleNode = document.createElement(ELEMENT_MODULE); | ||
moduleNode.setAttribute(ATTR_NAME, moduleInfo.name()); | ||
return moduleNode; | ||
} | ||
|
||
/** | ||
* Gets the "TreeWalker" element node of the config document. | ||
* @param document the XML document to search | ||
* @return the "TreeWalker" element node | ||
*/ | ||
private static Node getTreeWalkerModuleNode(Document document) { | ||
Node returnValue = null; | ||
final NodeList nodeList = document.getDocumentElement() | ||
.getElementsByTagName(ELEMENT_MODULE); | ||
|
||
for (int i = 0; i < nodeList.getLength(); ++i) { | ||
final Node node = nodeList.item(i); | ||
final Node nameAttr = node.getAttributes().getNamedItem(ATTR_NAME); | ||
if (PARENT_TREE_WALKER.equals(nameAttr.getNodeValue())) { | ||
returnValue = node; | ||
break; | ||
} | ||
} | ||
|
||
return returnValue; | ||
} | ||
|
||
/** | ||
* Gets the "Checker" element node of the config document. | ||
* @param document the XML document to search | ||
* @return the "Checker" element node | ||
*/ | ||
private static Node getCheckerModuleNode(Document document) { | ||
return document.getDocumentElement(); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/com/github/checkstyle/regression/configuration/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//////////////////////////////////////////////////////////////////////////////// | ||
// checkstyle: Checks Java source code for adherence to a set of rules. | ||
// Copyright (C) 2001-2017 the original author or authors. | ||
// | ||
// This library is free software; you can redistribute it and/or | ||
// modify it under the terms of the GNU Lesser General Public | ||
// License as published by the Free Software Foundation; either | ||
// version 2.1 of the License, or (at your option) any later version. | ||
// | ||
// This library is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
// Lesser General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU Lesser General Public | ||
// License along with this library; if not, write to the Free Software | ||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
/** | ||
* Contains the config XML generation classes. | ||
* @author LuoLiangchen | ||
*/ | ||
package com.github.checkstyle.regression.configuration; |
14 changes: 14 additions & 0 deletions
14
src/main/resources/com/github/checkstyle/regression/configuration/base_config.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<module name="Checker"> | ||
<property name="charset" value="UTF-8"/> | ||
<!-- do not change severity to 'error', as that will hide errors caused by exceptions --> | ||
<property name="severity" value="warning"/> | ||
<!-- haltOnException is required for exception fixes and reporting of all exceptions --> | ||
<property name="haltOnException" value="false"/> | ||
<!-- BeforeExecutionFileFilters is required for sources of java9 --> | ||
<module name="BeforeExecutionExclusionFileFilter"> | ||
<property name="fileNamePattern" value="module\-info\.java$"/> | ||
</module> | ||
|
||
<!-- Contents below are generated by regression-tool. --> | ||
<module name="TreeWalker"/></module> |
131 changes: 131 additions & 0 deletions
131
src/test/java/com/github/checkstyle/regression/configuration/ConfigGeneratorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
//////////////////////////////////////////////////////////////////////////////// | ||
// checkstyle: Checks Java source code for adherence to a set of rules. | ||
// Copyright (C) 2001-2017 the original author or authors. | ||
// | ||
// This library is free software; you can redistribute it and/or | ||
// modify it under the terms of the GNU Lesser General Public | ||
// License as published by the Free Software Foundation; either | ||
// version 2.1 of the License, or (at your option) any later version. | ||
// | ||
// This library is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
// Lesser General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU Lesser General Public | ||
// License along with this library; if not, write to the Free Software | ||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
package com.github.checkstyle.regression.configuration; | ||
|
||
import static com.github.checkstyle.regression.internal.TestUtils.assertUtilsClassHasPrivateConstructor; | ||
import static org.junit.Assert.assertEquals; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.StringWriter; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
|
||
import org.apache.commons.io.IOUtils; | ||
import org.junit.Test; | ||
|
||
import com.github.checkstyle.regression.data.ImmutableModuleExtractInfo; | ||
import com.github.checkstyle.regression.data.ImmutableModuleInfo; | ||
import com.github.checkstyle.regression.data.ModuleExtractInfo; | ||
import com.github.checkstyle.regression.data.ModuleInfo; | ||
|
||
public class ConfigGeneratorTest { | ||
private static final String BASE_PACKAGE = "com.puppycrawl.tools.checkstyle"; | ||
|
||
@Test | ||
public void testIsProperUtilsClass() throws Exception { | ||
assertUtilsClassHasPrivateConstructor(ConfigGenerator.class); | ||
} | ||
|
||
@Test | ||
public void testDtdVersion() throws Exception { | ||
} | ||
|
||
@Test | ||
public void testGenerateConfigTextWithEmptyModuleInfos() throws Exception { | ||
final String excepted = getExpectedXml("expected_empty_module_infos.xml"); | ||
|
||
final String actual = ConfigGenerator.generateConfigText(Collections.emptyList()); | ||
assertEquals("Config is not as expected", excepted, actual); | ||
} | ||
|
||
@Test | ||
public void testGenerateConfigTextWithCheckerParentModule() throws Exception { | ||
final String excepted = getExpectedXml("expected_checker_parent_module.xml"); | ||
|
||
final ModuleExtractInfo extractInfo = ImmutableModuleExtractInfo.builder() | ||
.name("FileLengthCheck") | ||
.packageName(BASE_PACKAGE + ".checks.sizes") | ||
.parent("Checker") | ||
.build(); | ||
final ModuleInfo moduleInfo = ImmutableModuleInfo.builder() | ||
.moduleExtractInfo(extractInfo) | ||
.build(); | ||
|
||
final String actual = ConfigGenerator.generateConfigText( | ||
Collections.singletonList(moduleInfo)); | ||
assertEquals("Config is not as expected", excepted, actual); | ||
} | ||
|
||
@Test | ||
public void testGenerateConfigTextWithTreeWalkerParentModule() throws Exception { | ||
final String excepted = getExpectedXml("expected_tree_walker_parent_module.xml"); | ||
|
||
final ModuleExtractInfo extractInfo = ImmutableModuleExtractInfo.builder() | ||
.name("HiddenFieldCheck") | ||
.packageName(BASE_PACKAGE + ".checks.coding") | ||
.parent("TreeWalker") | ||
.build(); | ||
final ModuleInfo moduleInfo = ImmutableModuleInfo.builder() | ||
.moduleExtractInfo(extractInfo) | ||
.build(); | ||
|
||
final String actual = ConfigGenerator.generateConfigText( | ||
Collections.singletonList(moduleInfo)); | ||
assertEquals("Config is not as expected", excepted, actual); | ||
} | ||
|
||
@Test | ||
public void testGenerateConfigTextWithMiscModuleInfos() throws Exception { | ||
final String excepted = | ||
getExpectedXml("expected_misc_module_infos.xml"); | ||
|
||
final ModuleExtractInfo extractInfo1 = ImmutableModuleExtractInfo.builder() | ||
.name("NewlineAtEndOfFileCheck") | ||
.packageName(BASE_PACKAGE + ".checks") | ||
.parent("Checker") | ||
.build(); | ||
final ModuleInfo moduleInfo1 = ImmutableModuleInfo.builder() | ||
.moduleExtractInfo(extractInfo1) | ||
.build(); | ||
|
||
final ModuleExtractInfo extractInfo2 = ImmutableModuleExtractInfo.builder() | ||
.name("EmptyStatementCheck") | ||
.packageName(BASE_PACKAGE + ".checks.coding") | ||
.parent("TreeWalker") | ||
.build(); | ||
final ModuleInfo moduleInfo2 = ImmutableModuleInfo.builder() | ||
.moduleExtractInfo(extractInfo2) | ||
.build(); | ||
|
||
final String actual = ConfigGenerator.generateConfigText( | ||
Arrays.asList(moduleInfo1, moduleInfo2)); | ||
assertEquals("Config is not as expected", excepted, actual); | ||
} | ||
|
||
private static String getExpectedXml(String fileName) throws IOException { | ||
try (InputStream stream = ConfigGeneratorTest.class.getClassLoader().getResourceAsStream( | ||
"com/github/checkstyle/regression/configuration/" + fileName)) { | ||
final StringWriter writer = new StringWriter(); | ||
IOUtils.copy(stream, writer, "UTF-8"); | ||
return writer.toString(); | ||
} | ||
} | ||
} |
Oops, something went wrong.