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() > 0 ? 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() > 0 ? 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() > 0 ? 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 }
|