KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > JavaConventions


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.core;
12
13 import java.util.StringTokenizer JavaDoc;
14
15 import org.eclipse.core.resources.IResource;
16 import org.eclipse.core.resources.IWorkspace;
17 import org.eclipse.core.resources.ResourcesPlugin;
18 import org.eclipse.core.runtime.IPath;
19 import org.eclipse.core.runtime.IStatus;
20 import org.eclipse.core.runtime.Status;
21 import org.eclipse.jdt.core.compiler.*;
22 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
23 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
24 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
25 import org.eclipse.jdt.internal.compiler.parser.Scanner;
26 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
27 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
28 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
29 import org.eclipse.jdt.internal.core.*;
30 import org.eclipse.jdt.internal.core.util.Messages;
31
32 /**
33  * Provides methods for checking Java-specific conventions such as name syntax.
34  * <p>
35  * This class provides static methods and constants only; it is not intended to be
36  * instantiated or subclassed by clients.
37  * </p>
38  */

39 public final class JavaConventions {
40
41     private static final char DOT= '.';
42     private static final String JavaDoc PACKAGE_INFO = new String JavaDoc(TypeConstants.PACKAGE_INFO_NAME);
43     private static final Scanner SCANNER = new Scanner(false /*comment*/, true /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3 /*sourceLevel*/, null/*taskTag*/, null/*taskPriorities*/, true /*taskCaseSensitive*/);
44     
45     private JavaConventions() {
46         // Not instantiable
47
}
48
49     /**
50      * Returns whether the given package fragment root paths are considered
51      * to overlap.
52      * <p>
53      * Two root paths overlap if one is a prefix of the other, or they point to
54      * the same location. However, a JAR is allowed to be nested in a root.
55      *
56      * @param rootPath1 the first root path
57      * @param rootPath2 the second root path
58      * @return true if the given package fragment root paths are considered to overlap, false otherwise
59      * @deprecated Overlapping roots are allowed in 2.1
60      */

61     public static boolean isOverlappingRoots(IPath rootPath1, IPath rootPath2) {
62         if (rootPath1 == null || rootPath2 == null) {
63             return false;
64         }
65         String JavaDoc extension1 = rootPath1.getFileExtension();
66         String JavaDoc extension2 = rootPath2.getFileExtension();
67         if (extension1 != null && (extension1.equalsIgnoreCase(SuffixConstants.EXTENSION_JAR) || extension1.equalsIgnoreCase(SuffixConstants.EXTENSION_ZIP))) {
68             return false;
69         }
70         if (extension2 != null && (extension2.equalsIgnoreCase(SuffixConstants.EXTENSION_JAR) || extension2.equalsIgnoreCase(SuffixConstants.EXTENSION_ZIP))) {
71             return false;
72         }
73         return rootPath1.isPrefixOf(rootPath2) || rootPath2.isPrefixOf(rootPath1);
74     }
75
76     /*
77      * Returns the current identifier extracted by the scanner (without unicode
78      * escapes) from the given id and for the given source and compliance levels.
79      * Returns <code>null</code> if the id was not valid
80      */

81     private static synchronized char[] scannedIdentifier(String JavaDoc id, String JavaDoc sourceLevel, String JavaDoc complianceLevel) {
82         if (id == null) {
83             return null;
84         }
85         // Set scanner for given source and compliance levels
86
SCANNER.sourceLevel = sourceLevel == null ? ClassFileConstants.JDK1_3 : CompilerOptions.versionToJdkLevel(sourceLevel);
87         SCANNER.complianceLevel = complianceLevel == null ? ClassFileConstants.JDK1_3 : CompilerOptions.versionToJdkLevel(complianceLevel);
88
89         try {
90             SCANNER.setSource(id.toCharArray());
91             int token = SCANNER.scanIdentifier();
92             if (token != TerminalTokens.TokenNameIdentifier) return null;
93             if (SCANNER.currentPosition == SCANNER.eofPosition) { // to handle case where we had an ArrayIndexOutOfBoundsException
94
try {
95                     return SCANNER.getCurrentIdentifierSource();
96                 } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
97                     return null;
98                 }
99             } else {
100                 return null;
101             }
102         }
103         catch (InvalidInputException e) {
104             return null;
105         }
106     }
107
108     /**
109      * Validate the given compilation unit name.
110      * <p>
111      * A compilation unit name must obey the following rules:
112      * <ul>
113      * <li> it must not be null
114      * <li> it must be suffixed by a dot ('.') followed by one of the
115      * {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
116      * <li> its prefix must be a valid identifier
117      * <li> it must not contain any characters or substrings that are not valid
118      * on the file system on which workspace root is located.
119      * </ul>
120      * </p>
121      * @param name the name of a compilation unit
122      * @return a status object with code <code>IStatus.OK</code> if
123      * the given name is valid as a compilation unit name, otherwise a status
124      * object indicating what is wrong with the name
125      * @deprecated Use {@link #validateCompilationUnitName(String id, String sourceLevel, String complianceLevel)} instead
126      */

127     public static IStatus validateCompilationUnitName(String JavaDoc name) {
128         return validateCompilationUnitName(name,CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
129     }
130     
131     /**
132      * Validate the given compilation unit name for the given source and compliance levels.
133      * <p>
134      * A compilation unit name must obey the following rules:
135      * <ul>
136      * <li> it must not be null
137      * <li> it must be suffixed by a dot ('.') followed by one of the
138      * {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
139      * <li> its prefix must be a valid identifier
140      * <li> it must not contain any characters or substrings that are not valid
141      * on the file system on which workspace root is located.
142      * </ul>
143      * </p>
144      * @param name the name of a compilation unit
145      * @param sourceLevel the source level
146      * @param complianceLevel the compliance level
147      * @return a status object with code <code>IStatus.OK</code> if
148      * the given name is valid as a compilation unit name, otherwise a status
149      * object indicating what is wrong with the name
150      * @since 3.3
151      */

152     public static IStatus validateCompilationUnitName(String JavaDoc name, String JavaDoc sourceLevel, String JavaDoc complianceLevel) {
153         if (name == null) {
154             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_nullName, null);
155         }
156         if (!org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(name)) {
157             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_notJavaName, null);
158         }
159         String JavaDoc identifier;
160         int index;
161         index = name.lastIndexOf('.');
162         if (index == -1) {
163             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_notJavaName, null);
164         }
165         identifier = name.substring(0, index);
166         // JSR-175 metadata strongly recommends "package-info.java" as the
167
// file in which to store package annotations and
168
// the package-level spec (replaces package.html)
169
if (!identifier.equals(PACKAGE_INFO)) {
170             IStatus status = validateIdentifier(identifier, sourceLevel, complianceLevel);
171             if (!status.isOK()) {
172                 return status;
173             }
174         }
175         IStatus status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
176         if (!status.isOK()) {
177             return status;
178         }
179         return JavaModelStatus.VERIFIED_OK;
180     }
181
182     /**
183      * Validate the given .class file name.
184      * <p>
185      * A .class file name must obey the following rules:
186      * <ul>
187      * <li> it must not be null
188      * <li> it must include the <code>".class"</code> suffix
189      * <li> its prefix must be a valid identifier
190      * <li> it must not contain any characters or substrings that are not valid
191      * on the file system on which workspace root is located.
192      * </ul>
193      * </p>
194      * @param name the name of a .class file
195      * @return a status object with code <code>IStatus.OK</code> if
196      * the given name is valid as a .class file name, otherwise a status
197      * object indicating what is wrong with the name
198      * @since 2.0
199      * @deprecated Use {@link #validateClassFileName(String id, String sourceLevel, String complianceLevel)} instead
200      */

201     public static IStatus validateClassFileName(String JavaDoc name) {
202         return validateClassFileName(name, CompilerOptions.VERSION_1_3, CompilerOptions.VERSION_1_3);
203     }
204     
205     /**
206      * Validate the given .class file name for the given source and compliance levels.
207      * <p>
208      * A .class file name must obey the following rules:
209      * <ul>
210      * <li> it must not be null
211      * <li> it must include the <code>".class"</code> suffix
212      * <li> its prefix must be a valid identifier
213      * <li> it must not contain any characters or substrings that are not valid
214      * on the file system on which workspace root is located.
215      * </ul>
216      * </p>
217      * @param name the name of a .class file
218      * @param sourceLevel the source level
219      * @param complianceLevel the compliance level
220      * @return a status object with code <code>IStatus.OK</code> if
221      * the given name is valid as a .class file name, otherwise a status
222      * object indicating what is wrong with the name
223      * @since 3.3
224      */

225     public static IStatus validateClassFileName(String JavaDoc name, String JavaDoc sourceLevel, String JavaDoc complianceLevel) {
226         if (name == null) {
227             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_nullName, null); }
228         if (!org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) {
229             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_notClassFileName, null);
230         }
231         String JavaDoc identifier;
232         int index;
233         index = name.lastIndexOf('.');
234         if (index == -1) {
235             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_notClassFileName, null);
236         }
237         identifier = name.substring(0, index);
238         // JSR-175 metadata strongly recommends "package-info.java" as the
239
// file in which to store package annotations and
240
// the package-level spec (replaces package.html)
241
if (!identifier.equals(PACKAGE_INFO)) {
242             IStatus status = validateIdentifier(identifier, sourceLevel, complianceLevel);
243             if (!status.isOK()) {
244                 return status;
245             }
246         }
247         IStatus status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
248         if (!status.isOK()) {
249             return status;
250         }
251         return JavaModelStatus.VERIFIED_OK;
252     }
253
254     /**
255      * Validate the given field name.
256      * <p>
257      * Syntax of a field name corresponds to VariableDeclaratorId (JLS2 8.3).
258      * For example, <code>"x"</code>.
259      *
260      * @param name the name of a field
261      * @return a status object with code <code>IStatus.OK</code> if
262      * the given name is valid as a field name, otherwise a status
263      * object indicating what is wrong with the name
264      * @deprecated Use {@link #validateFieldName(String id, String sourceLevel, String complianceLevel)} instead
265      */

266     public static IStatus validateFieldName(String JavaDoc name) {
267         return validateIdentifier(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
268     }
269     
270     /**
271      * Validate the given field name for the given source and compliance levels.
272      * <p>
273      * Syntax of a field name corresponds to VariableDeclaratorId (JLS2 8.3).
274      * For example, <code>"x"</code>.
275      *
276      * @param name the name of a field
277      * @param sourceLevel the source level
278      * @param complianceLevel the compliance level
279      * @return a status object with code <code>IStatus.OK</code> if
280      * the given name is valid as a field name, otherwise a status
281      * object indicating what is wrong with the name
282      * @since 3.3
283      */

284     public static IStatus validateFieldName(String JavaDoc name, String JavaDoc sourceLevel, String JavaDoc complianceLevel) {
285         return validateIdentifier(name, sourceLevel, complianceLevel);
286     }
287
288     /**
289      * Validate the given Java identifier.
290      * The identifier must not have the same spelling as a Java keyword,
291      * boolean literal (<code>"true"</code>, <code>"false"</code>), or null literal (<code>"null"</code>).
292      * See section 3.8 of the <em>Java Language Specification, Second Edition</em> (JLS2).
293      * A valid identifier can act as a simple type name, method name or field name.
294      *
295      * @param id the Java identifier
296      * @return a status object with code <code>IStatus.OK</code> if
297      * the given identifier is a valid Java identifier, otherwise a status
298      * object indicating what is wrong with the identifier
299      * @deprecated Use {@link #validateIdentifier(String id, String sourceLevel, String complianceLevel)} instead
300      */

301     public static IStatus validateIdentifier(String JavaDoc id) {
302         return validateIdentifier(id,CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
303     }
304     
305     /**
306      * Validate the given Java identifier for the given source and compliance levels
307      * The identifier must not have the same spelling as a Java keyword,
308      * boolean literal (<code>"true"</code>, <code>"false"</code>), or null literal (<code>"null"</code>).
309      * See section 3.8 of the <em>Java Language Specification, Second Edition</em> (JLS2).
310      * A valid identifier can act as a simple type name, method name or field name.
311      *
312      * @param id the Java identifier
313      * @param sourceLevel the source level
314      * @param complianceLevel the compliance level
315      * @return a status object with code <code>IStatus.OK</code> if
316      * the given identifier is a valid Java identifier, otherwise a status
317      * object indicating what is wrong with the identifier
318      * @since 3.3
319      */

320     public static IStatus validateIdentifier(String JavaDoc id, String JavaDoc sourceLevel, String JavaDoc complianceLevel) {
321         if (scannedIdentifier(id, sourceLevel, complianceLevel) != null) {
322             return JavaModelStatus.VERIFIED_OK;
323         } else {
324             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, id), null);
325         }
326     }
327
328     /**
329      * Validate the given import declaration name.
330      * <p>
331      * The name of an import corresponds to a fully qualified type name
332      * or an on-demand package name as defined by ImportDeclaration (JLS2 7.5).
333      * For example, <code>"java.util.*"</code> or <code>"java.util.Hashtable"</code>.
334      *
335      * @param name the import declaration
336      * @return a status object with code <code>IStatus.OK</code> if
337      * the given name is valid as an import declaration, otherwise a status
338      * object indicating what is wrong with the name
339      * @deprecated Use {@link #validateImportDeclaration(String id, String sourceLevel, String complianceLevel)} instead
340      */

341     public static IStatus validateImportDeclaration(String JavaDoc name) {
342         return validateImportDeclaration(name,CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
343     }
344     
345     /**
346      * Validate the given import declaration name for the given source and compliance levels.
347      * <p>
348      * The name of an import corresponds to a fully qualified type name
349      * or an on-demand package name as defined by ImportDeclaration (JLS2 7.5).
350      * For example, <code>"java.util.*"</code> or <code>"java.util.Hashtable"</code>.
351      *
352      * @param name the import declaration
353      * @param sourceLevel the source level
354      * @param complianceLevel the compliance level
355      * @return a status object with code <code>IStatus.OK</code> if
356      * the given name is valid as an import declaration, otherwise a status
357      * object indicating what is wrong with the name
358      * @since 3.3
359      */

360     public static IStatus validateImportDeclaration(String JavaDoc name, String JavaDoc sourceLevel, String JavaDoc complianceLevel) {
361         if (name == null || name.length() == 0) {
362             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_import_nullImport, null);
363         }
364         if (name.charAt(name.length() - 1) == '*') {
365             if (name.charAt(name.length() - 2) == '.') {
366                 return validatePackageName(name.substring(0, name.length() - 2), sourceLevel, complianceLevel);
367             } else {
368                 return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_import_unqualifiedImport, null);
369             }
370         }
371         return validatePackageName(name, sourceLevel, complianceLevel);
372     }
373
374     /**
375      * Validate the given Java type name, either simple or qualified.
376      * For example, <code>"java.lang.Object"</code>, or <code>"Object"</code>.
377      * <p>
378      *
379      * @param name the name of a type
380      * @return a status object with code <code>IStatus.OK</code> if
381      * the given name is valid as a Java type name,
382      * a status with code <code>IStatus.WARNING</code>
383      * indicating why the given name is discouraged,
384      * otherwise a status object indicating what is wrong with
385      * the name
386      * @deprecated Use {@link #validateJavaTypeName(String id, String sourceLevel, String complianceLevel)} instead
387      */

388     public static IStatus validateJavaTypeName(String JavaDoc name) {
389         return validateJavaTypeName(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
390     }
391     
392     /**
393      * Validate the given Java type name, either simple or qualified, for the given source and compliance levels.
394      * For example, <code>"java.lang.Object"</code>, or <code>"Object"</code>.
395      * <p>
396      *
397      * @param name the name of a type
398      * @param sourceLevel the source level
399      * @param complianceLevel the compliance level
400      * @return a status object with code <code>IStatus.OK</code> if
401      * the given name is valid as a Java type name,
402      * a status with code <code>IStatus.WARNING</code>
403      * indicating why the given name is discouraged,
404      * otherwise a status object indicating what is wrong with
405      * the name
406      * @since 3.3
407      */

408     public static IStatus validateJavaTypeName(String JavaDoc name, String JavaDoc sourceLevel, String JavaDoc complianceLevel) {
409         if (name == null) {
410             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_type_nullName, null);
411         }
412         String JavaDoc trimmed = name.trim();
413         if (!name.equals(trimmed)) {
414             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_type_nameWithBlanks, null);
415         }
416         int index = name.lastIndexOf('.');
417         char[] scannedID;
418         if (index == -1) {
419             // simple name
420
scannedID = scannedIdentifier(name, sourceLevel, complianceLevel);
421         } else {
422             // qualified name
423
String JavaDoc pkg = name.substring(0, index).trim();
424             IStatus status = validatePackageName(pkg, sourceLevel, complianceLevel);
425             if (!status.isOK()) {
426                 return status;
427             }
428             String JavaDoc type = name.substring(index + 1).trim();
429             scannedID = scannedIdentifier(type, sourceLevel, complianceLevel);
430         }
431     
432         if (scannedID != null) {
433             IStatus status = ResourcesPlugin.getWorkspace().validateName(new String JavaDoc(scannedID), IResource.FILE);
434             if (!status.isOK()) {
435                 return status;
436             }
437             if (CharOperation.contains('$', scannedID)) {
438                 return new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_type_dollarName, null);
439             }
440             if ((scannedID.length > 0 && ScannerHelper.isLowerCase(scannedID[0]))) {
441                 return new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_type_lowercaseName, null);
442             }
443             return JavaModelStatus.VERIFIED_OK;
444         } else {
445             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_type_invalidName, name), null);
446         }
447     }
448
449     /**
450      * Validate the given method name.
451      * The special names "&lt;init&gt;" and "&lt;clinit&gt;" are not valid.
452      * <p>
453      * The syntax for a method name is defined by Identifier
454      * of MethodDeclarator (JLS2 8.4). For example "println".
455      *
456      * @param name the name of a method
457      * @return a status object with code <code>IStatus.OK</code> if
458      * the given name is valid as a method name, otherwise a status
459      * object indicating what is wrong with the name
460      * @deprecated Use {@link #validateMethodName(String id, String sourceLevel, String complianceLevel)} instead
461      */

462     public static IStatus validateMethodName(String JavaDoc name) {
463         return validateMethodName(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
464     }
465     
466     /**
467      * Validate the given method name for the given source and compliance levels.
468      * The special names "&lt;init&gt;" and "&lt;clinit&gt;" are not valid.
469      * <p>
470      * The syntax for a method name is defined by Identifier
471      * of MethodDeclarator (JLS2 8.4). For example "println".
472      *
473      * @param name the name of a method
474      * @param sourceLevel the source level
475      * @param complianceLevel the compliance level
476      * @return a status object with code <code>IStatus.OK</code> if
477      * the given name is valid as a method name, otherwise a status
478      * object indicating what is wrong with the name
479      * @since 3.3
480      */

481     public static IStatus validateMethodName(String JavaDoc name, String JavaDoc sourceLevel, String JavaDoc complianceLevel) {
482         return validateIdentifier(name, sourceLevel,complianceLevel);
483     }
484
485     /**
486      * Validate the given package name.
487      * <p>
488      * The syntax of a package name corresponds to PackageName as
489      * defined by PackageDeclaration (JLS2 7.4). For example, <code>"java.lang"</code>.
490      * <p>
491      * Note that the given name must be a non-empty package name (that is, attempting to
492      * validate the default package will return an error status.)
493      * Also it must not contain any characters or substrings that are not valid
494      * on the file system on which workspace root is located.
495      *
496      * @param name the name of a package
497      * @return a status object with code <code>IStatus.OK</code> if
498      * the given name is valid as a package name, otherwise a status
499      * object indicating what is wrong with the name
500      * @deprecated Use {@link #validatePackageName(String id, String sourceLevel, String complianceLevel)} instead
501      */

502     public static IStatus validatePackageName(String JavaDoc name) {
503         return validatePackageName(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
504     }
505     
506     /**
507      * Validate the given package name for the given source and compliance levels.
508      * <p>
509      * The syntax of a package name corresponds to PackageName as
510      * defined by PackageDeclaration (JLS2 7.4). For example, <code>"java.lang"</code>.
511      * <p>
512      * Note that the given name must be a non-empty package name (that is, attempting to
513      * validate the default package will return an error status.)
514      * Also it must not contain any characters or substrings that are not valid
515      * on the file system on which workspace root is located.
516      *
517      * @param name the name of a package
518      * @param sourceLevel the source level
519      * @param complianceLevel the compliance level
520      * @return a status object with code <code>IStatus.OK</code> if
521      * the given name is valid as a package name, otherwise a status
522      * object indicating what is wrong with the name
523      * @since 3.3
524      */

525     public static IStatus validatePackageName(String JavaDoc name, String JavaDoc sourceLevel, String JavaDoc complianceLevel) {
526
527         if (name == null) {
528             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_nullName, null);
529         }
530         int length;
531         if ((length = name.length()) == 0) {
532             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_emptyName, null);
533         }
534         if (name.charAt(0) == DOT || name.charAt(length-1) == DOT) {
535             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_dotName, null);
536         }
537         if (CharOperation.isWhitespace(name.charAt(0)) || CharOperation.isWhitespace(name.charAt(name.length() - 1))) {
538             return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_nameWithBlanks, null);
539         }
540         int dot = 0;
541         while (dot != -1 && dot < length-1) {
542             if ((dot = name.indexOf(DOT, dot+1)) != -1 && dot < length-1 && name.charAt(dot+1) == DOT) {
543                 return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_consecutiveDotsName, null);
544                 }
545         }
546         IWorkspace workspace = ResourcesPlugin.getWorkspace();
547         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(name, "."); //$NON-NLS-1$
548
boolean firstToken = true;
549         IStatus warningStatus = null;
550         while (st.hasMoreTokens()) {
551             String JavaDoc typeName = st.nextToken();
552             typeName = typeName.trim(); // grammar allows spaces
553
char[] scannedID = scannedIdentifier(typeName, sourceLevel, complianceLevel);
554             if (scannedID == null) {
555                 return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, typeName), null);
556             }
557             IStatus status = workspace.validateName(new String JavaDoc(scannedID), IResource.FOLDER);
558             if (!status.isOK()) {
559                 return status;
560             }
561             if (firstToken && scannedID.length > 0 && ScannerHelper.isUpperCase(scannedID[0])) {
562                 if (warningStatus == null) {
563                     warningStatus = new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_package_uppercaseName, null);
564                 }
565             }
566             firstToken = false;
567         }
568         if (warningStatus != null) {
569             return warningStatus;
570         }
571         return JavaModelStatus.VERIFIED_OK;
572     }
573     
574     /**
575      * Validate a given classpath and output location for a project, using the following rules:
576      * <ul>
577      * <li> Classpath entries cannot collide with each other; that is, all entry paths must be unique.
578      * <li> The project output location path cannot be null, must be absolute and located inside the project.
579      * <li> Specific output locations (specified on source entries) can be null, if not they must be located inside the project,
580      * <li> A project entry cannot refer to itself directly (that is, a project cannot prerequisite itself).
581      * <li> Classpath entries or output locations cannot coincidate or be nested in each other, except for the following scenarii listed below:
582      * <ul><li> A source folder can coincidate with its own output location, in which case this output can then contain library archives.
583      * However, a specific output location cannot coincidate with any library or a distinct source folder than the one referring to it. </li>
584      * <li> A source/library folder can be nested in any source folder as long as the nested folder is excluded from the enclosing one. </li>
585      * <li> An output location can be nested in a source folder, if the source folder coincidates with the project itself, or if the output
586      * location is excluded from the source folder.
587      * </ul>
588      * </ul>
589      *
590      * Note that the classpath entries are not validated automatically. Only bound variables or containers are considered
591      * in the checking process (this allows to perform a consistency check on a classpath which has references to
592      * yet non existing projects, folders, ...).
593      * <p>
594      * This validation is intended to anticipate classpath issues prior to assigning it to a project. In particular, it will automatically
595      * be performed during the classpath setting operation (if validation fails, the classpath setting will not complete).
596      * <p>
597      * @param javaProject the given java project
598      * @param rawClasspath the given classpath
599      * @param projectOutputLocation the given output location
600      * @return a status object with code <code>IStatus.OK</code> if
601      * the given classpath and output location are compatible, otherwise a status
602      * object indicating what is wrong with the classpath or output location
603      * @since 2.0
604      */

605     public static IJavaModelStatus validateClasspath(IJavaProject javaProject, IClasspathEntry[] rawClasspath, IPath projectOutputLocation) {
606
607         return ClasspathEntry.validateClasspath(javaProject, rawClasspath, projectOutputLocation);
608     }
609
610     /**
611      * Returns a Java model status describing the problem related to this classpath entry if any,
612      * a status object with code <code>IStatus.OK</code> if the entry is fine (that is, if the
613      * given classpath entry denotes a valid element to be referenced onto a classpath).
614      *
615      * @param project the given java project
616      * @param entry the given classpath entry
617      * @param checkSourceAttachment a flag to determine if source attachement should be checked
618      * @return a java model status describing the problem related to this classpath entry if any, a status object with code <code>IStatus.OK</code> if the entry is fine
619      * @since 2.0
620      */

621     public static IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry entry, boolean checkSourceAttachment){
622         IJavaModelStatus status = ClasspathEntry.validateClasspathEntry(project, entry, checkSourceAttachment, true/*recurse in container*/);
623         if (status.getCode() == IJavaModelStatusConstants.INVALID_CLASSPATH && ((ClasspathEntry) entry).isOptional())
624             return JavaModelStatus.VERIFIED_OK;
625         return status;
626     }
627     
628     /**
629      * Validate the given type variable name.
630      * <p>
631      * Syntax of a type variable name corresponds to a Java identifier (JLS3 4.3).
632      * For example, <code>"E"</code>.
633      *
634      * @param name the name of a type variable
635      * @return a status object with code <code>IStatus.OK</code> if
636      * the given name is valid as a type variable name, otherwise a status
637      * object indicating what is wrong with the name
638      * @since 3.1
639      * @deprecated Use {@link #validateTypeVariableName(String id, String sourceLevel, String complianceLevel)} instead
640      */

641     public static IStatus validateTypeVariableName(String JavaDoc name) {
642         return validateIdentifier(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
643     }
644     
645     /**
646      * Validate the given type variable name for the given source and compliance levels.
647      * <p>
648      * Syntax of a type variable name corresponds to a Java identifier (JLS3 4.3).
649      * For example, <code>"E"</code>.
650      *
651      * @param name the name of a type variable
652      * @param sourceLevel the source level
653      * @param complianceLevel the compliance level
654      * @return a status object with code <code>IStatus.OK</code> if
655      * the given name is valid as a type variable name, otherwise a status
656      * object indicating what is wrong with the name
657      * @since 3.3
658      */

659     public static IStatus validateTypeVariableName(String JavaDoc name, String JavaDoc sourceLevel, String JavaDoc complianceLevel) {
660         return validateIdentifier(name, sourceLevel, complianceLevel);
661     }
662     
663     /**
664      * Validate that all compiler options of the given project match keys and values
665      * described in {@link JavaCore#getDefaultOptions()} method.
666      *
667      * @param javaProject the given java project
668      * @param inheritJavaCoreOptions inherit project options from JavaCore or not.
669      * @return a status object with code <code>IStatus.OK</code> if all project
670      * compiler options are valid, otherwise a status object indicating what is wrong
671      * with the keys and their value.
672      * @since 3.1
673      * TODO (frederic) finalize for all possible options (JavaCore, DefaultCodeFormatterOptions, AssistOptions) and open to API
674      */

675     /*
676     public static IStatus validateCompilerOptions(IJavaProject javaProject, boolean inheritJavaCoreOptions) {
677         return validateCompilerOptions(javaProject.getOptions(inheritJavaCoreOptions));
678     }
679     */

680     
681     /**
682      * Validate that all compiler options of the given project match keys and values
683      * described in {@link JavaCore#getDefaultOptions()} method.
684      *
685      * @param compilerOptions Map of options
686      * @return a status object with code <code>IStatus.OK</code> if all
687      * compiler options are valid, otherwise a status object indicating what is wrong
688      * with the keys and their value.
689      * @since 3.1
690      */

691     /*
692     public static IStatus validateCompilerOptions(Map compilerOptions) {
693
694         // Get current options
695         String compliance = (String) compilerOptions.get(JavaCore.COMPILER_COMPLIANCE);
696         String source = (String) compilerOptions.get(JavaCore.COMPILER_SOURCE);
697         String target = (String) compilerOptions.get(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM);
698         if (compliance == null && source == null && target == null) {
699             return JavaModelStatus.VERIFIED_OK; // default is OK
700         }
701         
702         // Initialize multi-status
703         List errors = new ArrayList();
704         
705         // Set default for compliance if necessary (not set on project and not inherited...)
706         if (compliance == null) {
707             compliance = JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE);
708         }
709         
710         // Verify compliance level value and set source and target default if necessary
711         long complianceLevel = 0;
712         long sourceLevel = 0;
713         long targetLevel = 0;
714         if (JavaCore.VERSION_1_3.equals(compliance)) {
715             complianceLevel = ClassFileConstants.JDK1_3;
716             if (source == null) {
717                 source = JavaCore.VERSION_1_3;
718                 sourceLevel = ClassFileConstants.JDK1_3;
719             }
720             if (target == null) {
721                 target = JavaCore.VERSION_1_1;
722                 targetLevel = ClassFileConstants.JDK1_1;
723             }
724         } else if (JavaCore.VERSION_1_4.equals(compliance)) {
725             complianceLevel = ClassFileConstants.JDK1_4;
726             if (source == null) {
727                 source = JavaCore.VERSION_1_3;
728                 sourceLevel = ClassFileConstants.JDK1_3;
729             }
730             if (target == null) {
731                 target = JavaCore.VERSION_1_2;
732                 targetLevel = ClassFileConstants.JDK1_2;
733             }
734         } else if (JavaCore.VERSION_1_5.equals(compliance)) {
735             complianceLevel = ClassFileConstants.JDK1_5;
736             if (source == null) {
737                 source = JavaCore.VERSION_1_5;
738                 sourceLevel = ClassFileConstants.JDK1_5;
739             }
740             if (target == null) {
741                 target = JavaCore.VERSION_1_5;
742                 targetLevel = ClassFileConstants.JDK1_5;
743             }
744         } else {
745             // compliance is not valid
746             errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.invalidCompilerOption", compliance==null?"":compliance, JavaCore.COMPILER_COMPLIANCE))); //$NON-NLS-1$ //$NON-NLS-2$
747         }
748
749         // Verify source value and set default for target if necessary
750          if (JavaCore.VERSION_1_4.equals(source)) {
751             sourceLevel = ClassFileConstants.JDK1_4;
752             if (target == null) {
753                 target = JavaCore.VERSION_1_4;
754                 targetLevel = ClassFileConstants.JDK1_4;
755             }
756         } else if (JavaCore.VERSION_1_5.equals(source)) {
757             sourceLevel = ClassFileConstants.JDK1_5;
758             if (target == null) {
759                 target = JavaCore.VERSION_1_5;
760                 targetLevel = ClassFileConstants.JDK1_5;
761             }
762         } else if (JavaCore.VERSION_1_3.equals(source)) {
763             sourceLevel = ClassFileConstants.JDK1_3;
764         } else {
765             // source is not valid
766             errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.invalidCompilerOption", source==null?"":source, JavaCore.COMPILER_SOURCE))); //$NON-NLS-1$ //$NON-NLS-2$
767         }
768
769         // Verify target value
770          if (targetLevel == 0) {
771              targetLevel = CompilerOptions.versionToJdkLevel(target);
772              if (targetLevel == 0) {
773                 // target is not valid
774                 errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.invalidCompilerOption", target==null?"":target, JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM))); //$NON-NLS-1$ //$NON-NLS-2$
775              }
776         }
777
778         // Check and set compliance/source/target compatibilities (only if they have valid values)
779         if (complianceLevel != 0 && sourceLevel != 0 && targetLevel != 0) {
780             // target must be 1.5 if source is 1.5
781             if (sourceLevel >= ClassFileConstants.JDK1_5 && targetLevel < ClassFileConstants.JDK1_5) {
782                 errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleTargetForSource", target, JavaCore.VERSION_1_5))); //$NON-NLS-1$
783             }
784             else
785                 // target must be 1.4 if source is 1.4
786                 if (sourceLevel >= ClassFileConstants.JDK1_4 && targetLevel < ClassFileConstants.JDK1_4) {
787                     errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleTargetForSource", target, JavaCore.VERSION_1_4))); //$NON-NLS-1$
788             }
789             // target cannot be greater than compliance level
790             if (complianceLevel < targetLevel){
791                 errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleComplianceForTarget", compliance, JavaCore.VERSION_1_4))); //$NON-NLS-1$
792             }
793             // compliance must be 1.5 if source is 1.5
794             if (source.equals(JavaCore.VERSION_1_5) && complianceLevel < ClassFileConstants.JDK1_5) {
795                 errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleComplianceForSource", compliance, JavaCore.VERSION_1_5))); //$NON-NLS-1$
796             } else
797                 // compliance must be 1.4 if source is 1.4
798                 if (source.equals(JavaCore.VERSION_1_4) && complianceLevel < ClassFileConstants.JDK1_4) {
799                     errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleComplianceForSource", compliance, JavaCore.VERSION_1_4))); //$NON-NLS-1$
800             }
801         }
802
803         // Return status
804         int size = errors.size();
805         switch (size) {
806             case 0:
807                 return JavaModelStatus.VERIFIED_OK;
808             case 1:
809                 return (IStatus) errors.get(0);
810             default:
811                 IJavaModelStatus[] allStatus = new IJavaModelStatus[size];
812                 errors.toArray(allStatus);
813                 return JavaModelStatus.newMultiStatus(allStatus);
814         }
815     }
816     */

817 }
818
Popular Tags