LanguageVersion.java
001 /**
002  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003  */
004 package net.sourceforge.pmd.lang;
005 
006 import java.util.ArrayList;
007 import java.util.Collections;
008 import java.util.List;
009 
010 import net.sourceforge.pmd.lang.cpp.CppHandler;
011 import net.sourceforge.pmd.lang.ecmascript.Ecmascript3Handler;
012 import net.sourceforge.pmd.lang.java.Java13Handler;
013 import net.sourceforge.pmd.lang.java.Java14Handler;
014 import net.sourceforge.pmd.lang.java.Java15Handler;
015 import net.sourceforge.pmd.lang.java.Java16Handler;
016 import net.sourceforge.pmd.lang.java.Java17Handler;
017 import net.sourceforge.pmd.lang.jsp.JspHandler;
018 import net.sourceforge.pmd.lang.xml.XmlHandler;
019 
020 /**
021  * This is an enumeration of the Language versions of which PMD is aware.  The
022  * primary use of a LanguageVersion is for Rules, but they are also used by
023  * utilities such as CPD.
024  <p>
025  * The following are key components of a LanguageVersion in PMD:
026  <ul>
027  *   <li>Language - The Language with which this version is associated</li>
028  *   <li>Short name - The common short form of the Language</li>
029  *   <li>Terse name - The shortest and simplest possible form of the Language
030  *     name, generally used for Rule configuration</li>
031  *   <li>Extensions - File extensions associated with the Language</li>
032  *   <li>Rule Chain Visitor - The RuleChainVisitor implementation used for this
033  *     Language</li>
034  *   <li>Versions - The LanguageVersions associated with the Language</li>
035  </ul>
036  *
037  @see LanguageVersion
038  @see LanguageVersionDiscoverer
039  */
040 public enum LanguageVersion {
041 
042     //ANY(Language.ANY, "", null, true),
043     //UNKNOWN(Language.UNKNOWN, "", null, true),
044     CPP(Language.CPP, ""new CppHandler()true),
045     FORTRAN(Language.FORTRAN, "", null, true),
046     ECMASCRIPT(Language.ECMASCRIPT, "3"new Ecmascript3Handler()true),
047     JAVA_13(Language.JAVA, "1.3"new Java13Handler()false),
048     JAVA_14(Language.JAVA, "1.4"new Java14Handler()false),
049     JAVA_15(Language.JAVA, "1.5"new Java15Handler()true),
050     JAVA_16(Language.JAVA, "1.6"new Java16Handler()false),
051     JAVA_17(Language.JAVA, "1.7"new Java17Handler()false),
052     JSP(Language.JSP, ""new JspHandler()true),
053     PHP(Language.PHP, "", null, true),
054     RUBY(Language.RUBY, "", null, true),
055     XML(Language.XML, ""new XmlHandler()true);
056 
057     private final Language language;
058     private final String version;
059     private final LanguageVersionHandler languageVersionHandler;
060     private final boolean defaultVersion;
061 
062     /**
063      * LanguageVersion constructor.  The LanguageVersion will add itself as a
064      * version of its Language.
065      
066      @param language The Language of this LanguageVersion.
067      @param version The version String for this LanguageVersion.
068      * Must not be <code>null</code>, but may be an empty String.
069      @param languageVersionHandler The LanguageVersionHandler for this
070      * LanguageVersion.   May be <code>null</code>.
071      @param defaultVersion If <code>true</code> then this is the default
072      * version for the Language, otherwise this is not the default version.
073      */
074     private LanguageVersion(Language language, String version, LanguageVersionHandler languageVersionHandler,
075       boolean defaultVersion) {
076   if (language == null) {
077       throw new IllegalArgumentException("Language must not be null.");
078   }
079   if (version == null) {
080       throw new IllegalArgumentException("Version must not be null.");
081   }
082   this.language = language;
083   this.version = version;
084   this.languageVersionHandler = languageVersionHandler;
085   this.defaultVersion = defaultVersion;
086 
087   // Sanity check: There can only be a single default version per Language
088   if (defaultVersion) {
089       for (LanguageVersion languageVersion : language.getVersions()) {
090     if (languageVersion.isDefaultVersion()) {
091         throw new IllegalArgumentException(languageVersion.getLanguage() " already has default "
092           + languageVersion + ", not " + version);
093     }
094       }
095   }
096   language.getVersions().add(this);
097   // Make sure they are sorted (likely already are due to enum initialization order, but just in case)
098   Collections.sort(language.getVersions());
099     }
100 
101     /**
102      * Get the Language for this LanguageVersion.
103      @return The Language for this LanguageVersion.
104      */
105     public Language getLanguage() {
106   return language;
107     }
108 
109     /**
110      * Get the version String for this LanguageVersion.
111      @return The version String for this LanguageVersion.
112      */
113     public String getVersion() {
114   return version;
115     }
116 
117     /**
118      * Get the name of this LanguageVersion.  This is Language name
119      * appended with the LanguageVersion version if not an empty String.
120      @return The name of this LanguageVersion.
121      */
122     public String getName() {
123   return version.length() ? language.getName() ' ' + version : language.getName();
124     }
125 
126     /**
127      * Get the short name of this LanguageVersion.  This is Language short name
128      * appended with the LanguageVersion version if not an empty String.
129      @return The short name of this LanguageVersion.
130      */
131     public String getShortName() {
132   return version.length() ? language.getShortName() ' ' + version : language.getShortName();
133     }
134 
135     /**
136      * Get the terse name of this LanguageVersion.  This is Language terse name
137      * appended with the LanguageVersion version if not an empty String.
138      @return The terse name of this LanguageVersion.
139      */
140     public String getTerseName() {
141   return version.length() ? language.getTerseName() ' ' + version : language.getTerseName();
142     }
143 
144     /**
145      * Get the LanguageVersionHandler for this LanguageVersion.
146      @return The LanguageVersionHandler for this LanguageVersion.
147      */
148     public LanguageVersionHandler getLanguageVersionHandler() {
149   return languageVersionHandler;
150     }
151 
152     /**
153      * Returns if this LanguageVersion is the default version for the Language.
154      @return <code>true<code> if this is the default version for the Language,
155      <code>false</code> otherwise.
156      */
157     public boolean isDefaultVersion() {
158   return defaultVersion;
159     }
160 
161     /**
162      * A friendly String form of the LanguageVersion.
163      */
164     @Override
165     public String toString() {
166   return "LanguageVersion[" + language.getName() " " + version + ']';
167     }
168 
169     /**
170      * A utility method to find the LanguageVersion associated with the given
171      * terse name.
172      @param terseName The LanguageVersion terse name.
173      @return The LanguageVersion with this terse name, <code>null</code> if there is
174      * no LanguageVersion with this terse name.
175      */
176     public static LanguageVersion findByTerseName(String terseName) {
177   for (LanguageVersion languageVersion : LanguageVersion.values()) {
178       if (terseName.equals(languageVersion.getTerseName())) {
179     return languageVersion;
180       }
181   }
182   return null;
183     }
184 
185     
186     /**
187      * A utility method to find the all version associated with the given
188      * terse name.
189      @param languageTerseName The LanguageVersion terse name.
190      @return A list of versions associated with the terse name.
191      */
192     public static List<LanguageVersion> findVersionsForLanguageTerseName(String languageTerseName) {
193   List<LanguageVersion> versionsAvailable = new ArrayList<LanguageVersion>(0);
194   for (LanguageVersion languageVersion : LanguageVersion.values()) {      
195       if (languageVersion.getLanguage().getTerseName().equals(languageTerseName)) {
196     versionsAvailable.add(languageVersion);
197       }
198   }
199   return versionsAvailable;
200     }
201     
202 
203     /**
204      * Return a comma-separated list of LanguageVersion terse names.
205      @param languageVersions The language versions.
206      @return Comma-separated terse names.
207      */
208     public static String commaSeparatedTerseNames(List<LanguageVersion> languageVersions) {
209       
210       if (languageVersions == null || languageVersions.isEmpty()) {
211         return "";
212       }
213       
214       StringBuilder builder = new StringBuilder();
215       builder.append(languageVersions.get(0).getTerseName());
216       for (int i=1; i<languageVersions.size(); i++) {
217         builder.append(", ").append(languageVersions.get(i).getTerseName());
218       }
219       return builder.toString();
220     }
221 
222     /**
223      * Return the default version for PMD.
224      *
225      @return the proper instance of LanguageVersion 
226      */
227     public static LanguageVersion getDefaultVersion() {
228   return LanguageVersion.JAVA_15;
229     }
230 }