View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.internal.utils;
21  
22  import java.io.IOException;
23  import java.nio.file.DirectoryStream;
24  import java.nio.file.Files;
25  import java.nio.file.Path;
26  import java.nio.file.Paths;
27  import java.util.HashSet;
28  import java.util.Set;
29  
30  import javax.xml.parsers.DocumentBuilder;
31  import javax.xml.parsers.DocumentBuilderFactory;
32  import javax.xml.parsers.ParserConfigurationException;
33  
34  import org.w3c.dom.Document;
35  import org.w3c.dom.Element;
36  import org.w3c.dom.Node;
37  import org.w3c.dom.NodeList;
38  import org.xml.sax.SAXException;
39  
40  /**
41   * XdocUtil.
42   * @noinspection ClassOnlyUsedInOnePackage
43   */
44  public final class XdocUtil {
45      public static final String DIRECTORY_PATH = "src/xdocs";
46  
47      private XdocUtil() {
48      }
49  
50      /**
51       * Gets xdocs file paths.
52       * @return a list of xdocs file paths.
53       * @throws IOException if an I/O error occurs.
54       */
55      public static Set<Path> getXdocsFilePaths() throws IOException {
56          final Path directory = Paths.get(DIRECTORY_PATH);
57          try (DirectoryStream<Path> stream = Files.newDirectoryStream(directory, "*.xml")) {
58              final Set<Path> xdocs = new HashSet<>();
59              for (Path entry : stream) {
60                  xdocs.add(entry);
61              }
62              return xdocs;
63          }
64      }
65  
66      /**
67       * Gets xdocs documentation file paths.
68       * @param files list of all xdoc files
69       * @return a list of xdocs config file paths.
70       */
71      public static Set<Path> getXdocsConfigFilePaths(Set<Path> files) {
72          final Set<Path> xdocs = new HashSet<>();
73          for (Path entry : files) {
74              final String fileName = entry.getFileName().toString();
75              if (fileName.startsWith("config_")) {
76                  xdocs.add(entry);
77              }
78          }
79          return xdocs;
80      }
81  
82      /**
83       * Gets xdocs style file paths.
84       * @param files list of all xdoc files
85       * @return a list of xdocs style file paths.
86       */
87      public static Set<Path> getXdocsStyleFilePaths(Set<Path> files) {
88          final Set<Path> xdocs = new HashSet<>();
89          for (Path entry : files) {
90              final String fileName = entry.getFileName().toString();
91              if (fileName.endsWith("_style.xml")) {
92                  xdocs.add(entry);
93              }
94          }
95          return xdocs;
96      }
97  
98      /**
99       * Gets names of checkstyle's modules which are documented in xdocs.
100      * @return a set of checkstyle's modules which have xdoc documentation.
101      * @throws ParserConfigurationException if a DocumentBuilder cannot be created which satisfies
102      *              the configuration requested.
103      * @throws IOException if any IO errors occur.
104      * @throws SAXException if any parse errors occur.
105      */
106     public static Set<String> getModulesNamesWhichHaveXdoc() throws Exception {
107         final DocumentBuilderFactory factory = DocumentBuilderFactory
108                 .newInstance();
109 
110         // Validations of XML file make parsing too slow, that is why we disable
111         // all validations.
112         factory.setNamespaceAware(false);
113         factory.setValidating(false);
114         factory.setFeature("http://xml.org/sax/features/namespaces", false);
115         factory.setFeature("http://xml.org/sax/features/validation", false);
116         factory.setFeature(
117                 "http://apache.org/xml/features/nonvalidating/load-dtd-grammar",
118                 false);
119         factory.setFeature(
120                 "http://apache.org/xml/features/nonvalidating/load-external-dtd",
121                 false);
122 
123         final Set<String> modulesNamesWhichHaveXdoc = new HashSet<>();
124 
125         for (Path path : getXdocsConfigFilePaths(getXdocsFilePaths())) {
126             final DocumentBuilder builder = factory.newDocumentBuilder();
127             final Document document = builder.parse(path.toFile());
128 
129             // optional, but recommended
130             // FYI:
131             // http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-
132             // java-how-does-it-work
133             document.getDocumentElement().normalize();
134 
135             final NodeList nodeList = document.getElementsByTagName("section");
136 
137             for (int i = 0; i < nodeList.getLength(); i++) {
138                 final Node currentNode = nodeList.item(i);
139                 if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
140                     final Element module = (Element) currentNode;
141                     final String moduleName = module.getAttribute("name");
142                     if (!"Content".equals(moduleName)
143                             && !"Overview".equals(moduleName)) {
144                         modulesNamesWhichHaveXdoc.add(moduleName);
145                     }
146                 }
147             }
148         }
149         return modulesNamesWhichHaveXdoc;
150     }
151 }