View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang;
5   
6   import java.util.ArrayList;
7   import java.util.Collections;
8   import java.util.List;
9   
10  import net.sourceforge.pmd.lang.cpp.CppHandler;
11  import net.sourceforge.pmd.lang.ecmascript.Ecmascript3Handler;
12  import net.sourceforge.pmd.lang.java.Java13Handler;
13  import net.sourceforge.pmd.lang.java.Java14Handler;
14  import net.sourceforge.pmd.lang.java.Java15Handler;
15  import net.sourceforge.pmd.lang.java.Java16Handler;
16  import net.sourceforge.pmd.lang.java.Java17Handler;
17  import net.sourceforge.pmd.lang.java.Java18Handler;
18  import net.sourceforge.pmd.lang.jsp.JspHandler;
19  import net.sourceforge.pmd.lang.plsql.PLSQLHandler;
20  import net.sourceforge.pmd.lang.vm.VmHandler;
21  import net.sourceforge.pmd.lang.xml.XmlHandler;
22  
23  /**
24   * This is an enumeration of the Language versions of which PMD is aware.  The
25   * primary use of a LanguageVersion is for Rules, but they are also used by
26   * utilities such as CPD.
27   * <p>
28   * The following are key components of a LanguageVersion in PMD:
29   * <ul>
30   *     <li>Language - The Language with which this version is associated</li>
31   *     <li>Short name - The common short form of the Language</li>
32   *     <li>Terse name - The shortest and simplest possible form of the Language
33   *         name, generally used for Rule configuration</li>
34   *     <li>Extensions - File extensions associated with the Language</li>
35   *     <li>Rule Chain Visitor - The RuleChainVisitor implementation used for this
36   *         Language</li>
37   *     <li>Versions - The LanguageVersions associated with the Language</li>
38   * </ul>
39   *
40   * @see LanguageVersion
41   * @see LanguageVersionDiscoverer
42   */
43  public enum LanguageVersion {
44  
45      //ANY(Language.ANY, "", null, true),
46      //UNKNOWN(Language.UNKNOWN, "", null, true),
47      CPP(Language.CPP, "", new CppHandler(), true),
48      FORTRAN(Language.FORTRAN, "", null, true),
49      ECMASCRIPT(Language.ECMASCRIPT, "3", new Ecmascript3Handler(), true),
50      JAVA_13(Language.JAVA, "1.3", new Java13Handler(), false),
51      JAVA_14(Language.JAVA, "1.4", new Java14Handler(), false),
52      JAVA_15(Language.JAVA, "1.5", new Java15Handler(), false),
53      JAVA_16(Language.JAVA, "1.6", new Java16Handler(), false),
54      JAVA_17(Language.JAVA, "1.7", new Java17Handler(), false),
55      JAVA_18(Language.JAVA, "1.8", new Java18Handler(), true),
56      JSP(Language.JSP, "", new JspHandler(), true),
57      PHP(Language.PHP, "", null, true),
58      RUBY(Language.RUBY, "", null, true),
59      PLSQL(Language.PLSQL, "", new PLSQLHandler(), true),
60      XSL(Language.XSL, "", new XmlHandler(), true),
61      XML(Language.XML, "", new XmlHandler(), true),
62      VM(Language.VM, "", new VmHandler(), true);
63  
64      private final Language language;
65      private final String version;
66      private final LanguageVersionHandler languageVersionHandler;
67      private final boolean defaultVersion;
68  
69      /**
70       * LanguageVersion constructor.  The LanguageVersion will add itself as a
71       * version of its Language.
72       *
73       * @param language The Language of this LanguageVersion.
74       * @param version The version String for this LanguageVersion.
75       * Must not be <code>null</code>, but may be an empty String.
76       * @param languageVersionHandler The LanguageVersionHandler for this
77       * LanguageVersion.   May be <code>null</code>.
78       * @param defaultVersion If <code>true</code> then this is the default
79       * version for the Language, otherwise this is not the default version.
80       */
81      private LanguageVersion(Language language, String version, LanguageVersionHandler languageVersionHandler,
82          boolean defaultVersion) {
83      if (language == null) {
84          throw new IllegalArgumentException("Language must not be null.");
85      }
86      if (version == null) {
87          throw new IllegalArgumentException("Version must not be null.");
88      }
89      this.language = language;
90      this.version = version;
91      this.languageVersionHandler = languageVersionHandler;
92      this.defaultVersion = defaultVersion;
93  
94      // Sanity check: There can only be a single default version per Language
95      if (defaultVersion) {
96          for (LanguageVersion languageVersion : language.getVersions()) {
97          if (languageVersion.isDefaultVersion()) {
98              throw new IllegalArgumentException(languageVersion.getLanguage() + " already has default "
99                  + languageVersion + ", not " + version);
100         }
101         }
102     }
103     language.getVersions().add(this);
104     // Make sure they are sorted (likely already are due to enum initialization order, but just in case)
105     Collections.sort(language.getVersions());
106     }
107 
108     /**
109      * Get the Language for this LanguageVersion.
110      * @return The Language for this LanguageVersion.
111      */
112     public Language getLanguage() {
113     return language;
114     }
115 
116     /**
117      * Get the version String for this LanguageVersion.
118      * @return The version String for this LanguageVersion.
119      */
120     public String getVersion() {
121     return version;
122     }
123 
124     /**
125      * Get the name of this LanguageVersion.  This is Language name
126      * appended with the LanguageVersion version if not an empty String.
127      * @return The name of this LanguageVersion.
128      */
129     public String getName() {
130     return version.length() > 0 ? language.getName() + ' ' + version : language.getName();
131     }
132 
133     /**
134      * Get the short name of this LanguageVersion.  This is Language short name
135      * appended with the LanguageVersion version if not an empty String.
136      * @return The short name of this LanguageVersion.
137      */
138     public String getShortName() {
139     return version.length() > 0 ? language.getShortName() + ' ' + version : language.getShortName();
140     }
141 
142     /**
143      * Get the terse name of this LanguageVersion.  This is Language terse name
144      * appended with the LanguageVersion version if not an empty String.
145      * @return The terse name of this LanguageVersion.
146      */
147     public String getTerseName() {
148     return version.length() > 0 ? language.getTerseName() + ' ' + version : language.getTerseName();
149     }
150 
151     /**
152      * Get the LanguageVersionHandler for this LanguageVersion.
153      * @return The LanguageVersionHandler for this LanguageVersion.
154      */
155     public LanguageVersionHandler getLanguageVersionHandler() {
156     return languageVersionHandler;
157     }
158 
159     /**
160      * Returns if this LanguageVersion is the default version for the Language.
161      * @return <code>true</code> if this is the default version for the Language,
162      * <code>false</code> otherwise.
163      */
164     public boolean isDefaultVersion() {
165     return defaultVersion;
166     }
167 
168     /**
169      * A friendly String form of the LanguageVersion.
170      */
171     @Override
172     public String toString() {
173     return "LanguageVersion[" + language.getName() + " " + version + ']';
174     }
175 
176     /**
177      * A utility method to find the LanguageVersion associated with the given
178      * terse name.
179      * @param terseName The LanguageVersion terse name.
180      * @return The LanguageVersion with this terse name, <code>null</code> if there is
181      * no LanguageVersion with this terse name.
182      */
183     public static LanguageVersion findByTerseName(String terseName) {
184     for (LanguageVersion languageVersion : LanguageVersion.values()) {
185         if (terseName.equals(languageVersion.getTerseName())) {
186         return languageVersion;
187         }
188     }
189     return null;
190     }
191 
192 
193     /**
194      * A utility method to find the all version associated with the given
195      * terse name.
196      * @param languageTerseName The LanguageVersion terse name.
197      * @return A list of versions associated with the terse name.
198      */
199     public static List<LanguageVersion> findVersionsForLanguageTerseName(String languageTerseName) {
200         List<LanguageVersion> versionsAvailable = new ArrayList<LanguageVersion>(0);
201         for (LanguageVersion languageVersion : LanguageVersion.values()) {
202             if (languageVersion.getLanguage().getTerseName().equals(languageTerseName)) {
203             versionsAvailable.add(languageVersion);
204             }
205         }
206         return versionsAvailable;
207     }
208 
209     /**
210      * A utility method to retrieve the appropriate enum, given the provided parameters
211      *
212      * @param languageTerseName The LanguageVersion terse name.
213      * @param languageVersion The version of the language requested.
214      * @return A list of versions associated with the terse name.
215      */
216     public static LanguageVersion findVersionsForLanguageTerseName(String languageTerseName, String languageVersion) {
217         List<LanguageVersion> versionsAvailable = findVersionsForLanguageTerseName(languageTerseName);
218         for ( LanguageVersion version : versionsAvailable ) {
219         	if ( version.getVersion().equalsIgnoreCase(languageVersion) )
220         		return version;
221         }
222         return null;
223     }
224 
225 
226     /**
227      * Return a comma-separated list of LanguageVersion terse names.
228      * @param languageVersions The language versions.
229      * @return Comma-separated terse names.
230      */
231     public static String commaSeparatedTerseNames(List<LanguageVersion> languageVersions) {
232 
233         if (languageVersions == null || languageVersions.isEmpty()) {
234             return "";
235         }
236 
237         StringBuilder builder = new StringBuilder();
238         builder.append(languageVersions.get(0).getTerseName());
239         for (int i=1; i<languageVersions.size(); i++) {
240             builder.append(", ").append(languageVersions.get(i).getTerseName());
241         }
242         return builder.toString();
243     }
244 
245     /**
246      * Return the default version for PMD.
247      *
248      * @return the proper instance of LanguageVersion
249      */
250     public static LanguageVersion getDefaultVersion() {
251         return LanguageVersion.JAVA_15;
252     }
253 }