001: /*
002: * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package javax.lang.model;
027:
028: import java.util.Collections;
029: import java.util.Set;
030: import java.util.HashSet;
031:
032: /**
033: * Source versions of the Java™ programming language.
034: *
035: * See <a
036: * href="http://java.sun.com/docs/books/jls/">http://java.sun.com/docs/books/jls/</a>
037: * for information on editions of <i>The Java™ Language
038: * Specification</i>, including updates and clarifications.
039: *
040: * <p>Note that additional source version constants will be added to
041: * model future releases of the language.
042: *
043: * @author Joseph D. Darcy
044: * @author Scott Seligman
045: * @author Peter von der Ahé
046: * @version 1.14 07/05/05
047: * @since 1.6
048: */
049: public enum SourceVersion {
050: /*
051: * Summary of language evoluation
052: * 1.1: nested classes
053: * 1.2: strictfp
054: * 1.3: no changes
055: * 1.4: assert
056: * 1.5: annotations, generics, autoboxing, var-args...
057: * 1.6: no changes
058: */
059:
060: /**
061: * The original version.
062: *
063: * The language described in the first edition of <i>The
064: * Java™ Language Specification</i>.
065: */
066: RELEASE_0,
067:
068: /**
069: * The version recognized by the Java Platform 1.1.
070: *
071: * The language is {@code RELEASE_0} <a
072: * href="http://java.sun.com/docs/books/jls/first_edition/html/1.1Update.html">augmented</a>
073: * with nested classes.
074: */
075: RELEASE_1,
076:
077: /**
078: * The version recognized by the Java 2 Platform, Standard Edition,
079: * v 1.2.
080: *
081: * The language described in <i>The Java™ Language
082: * Specification, Second Edition</i>, which includes the {@code
083: * strictfp} modifier.
084: */
085: RELEASE_2,
086:
087: /**
088: * The version recognized by the Java 2 Platform, Standard Edition,
089: * v 1.3.
090: *
091: * No major changes from {@code RELEASE_2}.
092: */
093: RELEASE_3,
094:
095: /**
096: * The version recognized by the Java 2 Platform, Standard Edition,
097: * v 1.4.
098: *
099: * Added a simple assertion facility.
100: */
101: RELEASE_4,
102:
103: /**
104: * The version recognized by the Java 2 Platform, Standard
105: * Edition 5.0.
106: *
107: * The language described in <i>The Java™ Language
108: * Specification, Third Edition</i>. First release to support
109: * generics, annotations, autoboxing, var-args, enhanced {@code
110: * for} loop, and hexadecimal floating-point literals.
111: */
112: RELEASE_5,
113:
114: /**
115: * The version recognized by the Java Platform, Standard Edition
116: * 6.
117: *
118: * No major changes from {@code RELEASE_5}.
119: */
120: RELEASE_6,
121:
122: /**
123: * The version recognized by the Java Platform, Standard Edition
124: * 7.
125: *
126: * @since 1.7
127: */
128: RELEASE_7;
129:
130: // Note that when adding constants for newer releases, the
131: // behavior of latest() and latestSupported() must be updated too.
132:
133: /**
134: * Returns the latest source version that can be modeled.
135: *
136: * @return the latest source version that can be modeled
137: */
138: public static SourceVersion latest() {
139: return RELEASE_7;
140: }
141:
142: private static final SourceVersion latestSupported = getLatestSupported();
143:
144: private static SourceVersion getLatestSupported() {
145: try {
146: String specVersion = System
147: .getProperty("java.specification.version");
148: if ("1.7".equals(specVersion))
149: return RELEASE_7;
150: else if ("1.6".equals(specVersion))
151: return RELEASE_6;
152: } catch (SecurityException se) {
153: }
154:
155: return RELEASE_5;
156: }
157:
158: /**
159: * Returns the latest source version fully supported by the
160: * current execution environment. {@code RELEASE_5} or later must
161: * be returned.
162: *
163: * @return the latest source version that is fully supported
164: */
165: public static SourceVersion latestSupported() {
166: return latestSupported;
167: }
168:
169: /**
170: * Returns whether or not {@code name} is a syntactically valid
171: * identifier (simple name) or keyword in the latest source
172: * version. The method returns {@code true} if the name consists
173: * of an initial character for which {@link
174: * Character#isJavaIdentifierStart(int)} returns {@code true},
175: * followed only by characters for which {@link
176: * Character#isJavaIdentifierPart(int)} returns {@code true}.
177: * This pattern matches regular identifiers, keywords, and the
178: * literals {@code "true"}, {@code "false"}, and {@code "null"}.
179: * The method returns {@code false} for all other strings.
180: *
181: * @param name the string to check
182: * @return {@code true} if this string is a
183: * syntactically valid identifier or keyword, {@code false}
184: * otherwise.
185: */
186: public static boolean isIdentifier(CharSequence name) {
187: String id = name.toString();
188:
189: if (id.length() == 0) {
190: return false;
191: }
192: int cp = id.codePointAt(0);
193: if (!Character.isJavaIdentifierStart(cp)) {
194: return false;
195: }
196: for (int i = Character.charCount(cp); i < id.length(); i += Character
197: .charCount(cp)) {
198: cp = id.codePointAt(i);
199: if (!Character.isJavaIdentifierPart(cp)) {
200: return false;
201: }
202: }
203: return true;
204: }
205:
206: /**
207: * Returns whether or not {@code name} is a syntactically valid
208: * qualified name in the latest source version. Unlike {@link
209: * #isIdentifier isIdentifier}, this method returns {@code false}
210: * for keywords and literals.
211: *
212: * @param name the string to check
213: * @return {@code true} if this string is a
214: * syntactically valid name, {@code false} otherwise.
215: * @jls3 6.2 Names and Identifiers
216: */
217: public static boolean isName(CharSequence name) {
218: String id = name.toString();
219:
220: for (String s : id.split("\\.", -1)) {
221: if (!isIdentifier(s) || isKeyword(s))
222: return false;
223: }
224: return true;
225: }
226:
227: private final static Set<String> keywords;
228: static {
229: Set<String> s = new HashSet<String>();
230: String[] kws = { "abstract", "continue", "for", "new",
231: "switch", "assert", "default", "if", "package",
232: "synchronized", "boolean", "do", "goto", "private",
233: "this", "break", "double", "implements", "protected",
234: "throw", "byte", "else", "import", "public", "throws",
235: "case", "enum", "instanceof", "return", "transient",
236: "catch", "extends", "int", "short", "try", "char",
237: "final", "interface", "static", "void", "class",
238: "finally", "long", "strictfp", "volatile", "const",
239: "float", "native", "super", "while",
240: // literals
241: "null", "true", "false" };
242: for (String kw : kws)
243: s.add(kw);
244: keywords = Collections.unmodifiableSet(s);
245: }
246:
247: /**
248: * Returns whether or not {@code s} is a keyword or literal in the
249: * latest source version.
250: *
251: * @param s the string to check
252: * @return {@code true} if {@code s} is a keyword or literal, {@code false} otherwise.
253: */
254: public static boolean isKeyword(CharSequence s) {
255: String keywordOrLiteral = s.toString();
256: return keywords.contains(keywordOrLiteral);
257: }
258: }
|