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