View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 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.checks.javadoc;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.Set;
25  import java.util.concurrent.ConcurrentHashMap;
26  
27  import com.puppycrawl.tools.checkstyle.GlobalStatefulCheck;
28  import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
29  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
30  import com.puppycrawl.tools.checkstyle.api.FileText;
31  
32  /**
33   * <p>
34   * Checks that each Java package has a Javadoc file used for commenting.
35   * By default, it only allows a {@code package-info.java} file,
36   * but can be configured to allow a {@code package.html} file.
37   * </p>
38   * <p>
39   * A violation will be reported if both files exist as this is not allowed by the Javadoc tool.
40   * </p>
41   * <ul>
42   * <li>
43   * Property {@code allowLegacy} - Allow legacy {@code package.html} file to be used.
44   * Type is {@code boolean}.
45   * Default value is {@code false}.
46   * </li>
47   * <li>
48   * Property {@code fileExtensions} - Specify the file extensions of the files to process.
49   * Type is {@code java.lang.String[]}.
50   * Default value is {@code .java}.
51   * </li>
52   * </ul>
53   * <p>
54   * Parent is {@code com.puppycrawl.tools.checkstyle.Checker}
55   * </p>
56   * <p>
57   * Violation Message Keys:
58   * </p>
59   * <ul>
60   * <li>
61   * {@code javadoc.legacyPackageHtml}
62   * </li>
63   * <li>
64   * {@code javadoc.packageInfo}
65   * </li>
66   * </ul>
67   *
68   * @since 5.0
69   */
70  @GlobalStatefulCheck
71  public class JavadocPackageCheck extends AbstractFileSetCheck {
72  
73      /**
74       * A key is pointing to the warning message text in "messages.properties"
75       * file.
76       */
77      public static final String MSG_LEGACY_PACKAGE_HTML = "javadoc.legacyPackageHtml";
78  
79      /**
80       * A key is pointing to the warning message text in "messages.properties"
81       * file.
82       */
83      public static final String MSG_PACKAGE_INFO = "javadoc.packageInfo";
84  
85      /** The directories checked. */
86      private final Set<File> directoriesChecked = ConcurrentHashMap.newKeySet();
87  
88      /** Allow legacy {@code package.html} file to be used. */
89      private boolean allowLegacy;
90  
91      /**
92       * Creates a new instance.
93       */
94      public JavadocPackageCheck() {
95          // java, not html!
96          // The rule is: Every JAVA file should have a package.html sibling
97          setFileExtensions("java");
98      }
99  
100     @Override
101     protected void processFiltered(File file, FileText fileText) throws CheckstyleException {
102         // Check if already processed directory
103         final File dir;
104         try {
105             dir = file.getCanonicalFile().getParentFile();
106         }
107         catch (IOException ex) {
108             throw new CheckstyleException(
109                     "Exception while getting canonical path to file " + file.getPath(), ex);
110         }
111         final boolean isDirChecked = !directoriesChecked.add(dir);
112         if (!isDirChecked) {
113             // Check for the preferred file.
114             final File packageInfo = new File(dir, "package-info.java");
115             final File packageHtml = new File(dir, "package.html");
116 
117             if (packageInfo.exists()) {
118                 if (packageHtml.exists()) {
119                     log(1, MSG_LEGACY_PACKAGE_HTML);
120                 }
121             }
122             else if (!allowLegacy || !packageHtml.exists()) {
123                 log(1, MSG_PACKAGE_INFO);
124             }
125         }
126     }
127 
128     /**
129      * Setter to allow legacy {@code package.html} file to be used.
130      *
131      * @param allowLegacy whether to allow support.
132      * @since 5.0
133      */
134     public void setAllowLegacy(boolean allowLegacy) {
135         this.allowLegacy = allowLegacy;
136     }
137 
138 }