001: /**
002: * Redistribution and use of this software and associated documentation
003: * ("Software"), with or without modification, are permitted provided
004: * that the following conditions are met:
005: *
006: * 1. Redistributions of source code must retain copyright
007: * statements and notices. Redistributions must also contain a
008: * copy of this document.
009: *
010: * 2. Redistributions in binary form must reproduce the
011: * above copyright notice, this list of conditions and the
012: * following disclaimer in the documentation and/or other
013: * materials provided with the distribution.
014: *
015: * 3. The name "Exolab" must not be used to endorse or promote
016: * products derived from this Software without prior written
017: * permission of Intalio, Inc. For written permission,
018: * please contact info@exolab.org.
019: *
020: * 4. Products derived from this Software may not be called "Exolab"
021: * nor may "Exolab" appear in their names without prior written
022: * permission of Intalio, Inc. Exolab is a registered
023: * trademark of Intalio, Inc.
024: *
025: * 5. Due credit should be given to the Exolab Project
026: * (http://www.exolab.org/).
027: *
028: * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
029: * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
030: * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
031: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
032: * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
033: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
034: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
035: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
036: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
037: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
038: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
039: * OF THE POSSIBILITY OF SUCH DAMAGE.
040: *
041: * Copyright 1999-2000 (C) Intalio, Inc. All Rights Reserved.
042: */package org.exolab.javasource;
043:
044: /**
045: * A utility class used to validate identifiers and class names.
046: *
047: * @author <a href="mailto:keith AT kvisco DOT com">Keith Visco</a>
048: * @version $Revision: 6669 $ $Date: 2003-03-03 00:05:44 -0700 (Mon, 03 Mar 2003) $
049: */
050: public final class JNaming {
051: //--------------------------------------------------------------------------
052:
053: /**
054: * Reserved keywords in Java as of Java 5.
055: */
056: private static final String[] KEYWORDS = { "abstract", "boolean",
057: "break", "byte", "case", "catch", "char", "class", "const",
058: "continue", "default", "do", "double", "else", "enum",
059: "extends", "false", "final", "finally", "float", "for",
060: "goto", "if", "implements", "import", "instanceof", "int",
061: "interface", "long", "native", "new", "null", "package",
062: "private", "protected", "public", "return", "short",
063: "static", "super", "switch", "synchronized", "this",
064: "throw", "throws", "transient", "true", "try", "void",
065: "volatile", "while" };
066:
067: /**
068: * Collection classes in Java as of Java 5.
069: */
070: private static final String[] COLLECTIONS = { "ArrayList", "List",
071: "Set", "Collection", "Vector", "Hashtable", "Map",
072: "HashMap", "HashSet", "TreeSet", "Enumeration", "Iterator",
073: "ListIterator", "SortedSet", "SortedMap", "Queue",
074: "EnumSet", "EnumMap", "IdentityHashMap", "LinkedHashMap",
075: "LinkedHashSet", "LinkedList", "Stack", "TreeMap",
076: "WeakHashMap" };
077:
078: /**
079: * Classes in java.lang.* as of Java 5.
080: */
081: private static final String[] JAVA_LANG = {
082: // Interfaces in java.lang.*
083: "Appendable",
084: "CharSequence",
085: "Cloneable",
086: "Comparable",
087: "Iterable",
088: "Readable",
089: "Runnable",
090: // Classes in java.lang.*
091: "Boolean", "Byte", "Character", "Class", "ClassLoader",
092: "Compiler", "Double",
093: "Enum",
094: "Float",
095: "InheritableThreadLocal",
096: "Integer",
097: "Long",
098: "Math",
099: "Number",
100: "Object",
101: "Package",
102: "Process",
103: "ProcessBuilder",
104: "Runtime",
105: "RuntimePermission",
106: "SecurityManager",
107: "Short",
108: "StackTraceElement",
109: "StrictMath",
110: "String",
111: "StringBuffer",
112: "StringBuilder",
113: "System",
114: "Thread",
115: "ThreadGroup",
116: "ThreadLocal",
117: "Throwable",
118: "Void",
119: // Exceptions in java.lang.*
120: "ArithmeticException", "ArrayIndexOutOfBoundsException",
121: "ArrayStoreException", "ClassCastException",
122: "ClassNotFoundException", "CloneNotSupportedException",
123: "EnumConstantNotPresentException", "Exception",
124: "IllegalAccessException", "IllegalArgumentException",
125: "IllegalMonitorStateException",
126: "IllegalStateException",
127: "IllegalThreadStateException",
128: "IndexOutOfBoundsException",
129: "InstantiationException",
130: "InterruptedException",
131: "NegativeArraySizeException",
132: "NoSuchFieldException",
133: "NoSuchMethodException",
134: "NullPointerException",
135: "NumberFormatException",
136: "RuntimeException",
137: "SecurityException",
138: "StringIndexOutOfBoundsException",
139: "TypeNotPresentException",
140: "UnsupportedOperationException",
141: // Errors in java.lang.*
142: "AbstractMethodError", "AssertionError",
143: "ClassCircularityError", "ClassFormatError", "Error",
144: "ExceptionInInitializerError", "IllegalAccessError",
145: "IncompatibleClassChangeError", "InstantiationError",
146: "InternalError", "LinkageError", "NoClassDefFoundError",
147: "NoSuchFieldError", "NoSuchMethodError",
148: "OutOfMemoryError", "StackOverflowError", "ThreadDeath",
149: "UnknownError", "UnsatisfiedLinkError",
150: "UnsupportedClassVersionError", "VerifyError",
151: "VirtualMachineError",
152: // Annotation types in java.lang.*
153: "Deprecated", "Override", "SuppressWarnings" };
154:
155: /**
156: * Field names used within Castor that prevent a user from using the same
157: * name as an element without using a mapping file. Some fields that Castor
158: * uses depend on the contents of the schema, so we only warn.
159: * <br/>
160: * Reserved:
161: * <pre>
162: * _items -- might be fetched using getXXXXItems where XXX == class name
163: * _content
164: * _choiceValue
165: * _anyObject
166: * </pre>
167: */
168: private static final String[] CASTOR_RESERVED = { "Content",
169: "MenuItem", };
170:
171: /**
172: * Special reserved names within Windows that prevent a user from using the
173: * same name as an element without using a mapping file. Windows will not
174: * allow the use of any of these names with any case with any extension.
175: * At least, not without contortions.
176: * @see <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/naming_a_file.asp">
177: * The MSDN web page on file naming</a>
178: */
179: private static final String[] WINDOWS_RESERVED = { "CON", "PRN",
180: "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5",
181: "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3",
182: "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", };
183:
184: //--------------------------------------------------------------------------
185:
186: /**
187: * As we're a static utility class, our constructor is private.
188: */
189: private JNaming() {
190: super ();
191: }
192:
193: //--------------------------------------------------------------------------
194:
195: /**
196: * Returns true if the given String is a Java keyword which will cause a
197: * problem when used as a variable name.
198: *
199: * @param name The String to check against the list of keywords.
200: * @return True if the given String is a Java keyword which will cause a
201: * problem when used as a variable name.
202: */
203: public static boolean isKeyword(final String name) {
204: if (name == null) {
205: return false;
206: }
207: for (int i = 0; i < KEYWORDS.length; i++) {
208: if (KEYWORDS[i].equals(name)) {
209: return true;
210: }
211: }
212: return false;
213: }
214:
215: /**
216: * Returns true if the given String is a parameterized Java collection.
217: * object keyword which will cause a problem when used as a variable name
218: *
219: * @param name The String to check as a parameterized Java collection.
220: * @return True if the given String is a parameterized Java collection
221: * object keyword which will cause a problem when used as a variable
222: * name.
223: */
224: public static boolean isParameterizedCollectionsObject(
225: final String name) {
226: if (name == null) {
227: return false;
228: }
229: for (int i = 0; i < COLLECTIONS.length; i++) {
230: if (name.indexOf(COLLECTIONS[i]) != -1) {
231: return true;
232: }
233: }
234: return false;
235: }
236:
237: /**
238: * Returns true if the given String is a Java class in java.lang.* which
239: * will cause a problem when used as a variable name.
240: *
241: * @param name The String to check against the list of keywords.
242: * @return True if the given String is a Java class in java.lang.* which
243: * will cause a problem when used as a variable name.
244: */
245: public static boolean isInJavaLang(final String name) {
246: if (name == null) {
247: return false;
248: }
249: for (int i = 0; i < JAVA_LANG.length; i++) {
250: if (JAVA_LANG[i].equals(name)) {
251: return true;
252: }
253: }
254: return false;
255: }
256:
257: /**
258: * Returns true if the given String is a reserved name by Castor which may
259: * cause a problem when used as a variable name. Some fields that Castor
260: * uses depend on the contents of the schema, so we only warn.
261: *
262: * @param name The String to check against the list of keywords.
263: * @return True if the given String is a reserved name by Castor which may
264: * cause a problem when used as a variable name.
265: */
266: public static boolean isReservedByCastor(final String name) {
267: if (name == null) {
268: return false;
269: }
270: for (int i = 0; i < CASTOR_RESERVED.length; i++) {
271: if (CASTOR_RESERVED[i].equals(name)) {
272: return true;
273: }
274: }
275: return false;
276: }
277:
278: /**
279: * Returns true if the given String is a reserved name by the Windows
280: * filesystem which will cause a problem when used as a class name under
281: * Windows.
282: *
283: * @param name The String to check against the list of keywords.
284: * @return True if the given String is a reserved name by Castor which may
285: * cause a problem when used as a variable name.
286: */
287: public static boolean isReservedByWindows(final String name) {
288: if (name == null) {
289: return false;
290: }
291: for (int i = 0; i < WINDOWS_RESERVED.length; i++) {
292: if (WINDOWS_RESERVED[i].equalsIgnoreCase(name)) {
293: return true;
294: }
295: }
296: return false;
297: }
298:
299: /**
300: * Returns true if the given String matches the production of a valid Java
301: * identifier.
302: *
303: * @param string The String to check the production of.
304: * @return True if the given String matches the production of a valid Java
305: * name, otherwise false.
306: */
307: public static boolean isValidJavaIdentifier(final String string) {
308: if ((string == null) || (string.length() == 0)) {
309: return false;
310: }
311:
312: char[] chars = string.toCharArray();
313:
314: if (isParameterizedCollectionsObject(string)) {
315: return true;
316: }
317:
318: //-- make sure starting character is valid
319: if (!Character.isJavaIdentifierStart(chars[0])) {
320: return false;
321: }
322:
323: for (int i = 1; i < chars.length; i++) {
324: if (!Character.isJavaIdentifierPart(chars[i])) {
325: return false;
326: }
327: }
328: if (isKeyword(string)) {
329: return false;
330: }
331: return true;
332: }
333:
334: /**
335: * Returns the package name from the given class name.
336: *
337: * @param className An arbitrary class name, optionally including a package.
338: * @return The package name from the given class name.
339: */
340: public static String getPackageFromClassName(final String className) {
341: if (className == null) {
342: return null;
343: }
344: int idx = className.lastIndexOf('.');
345: if (idx > 0) {
346: return className.substring(0, idx);
347: }
348: return null;
349: }
350:
351: /**
352: * Returns the local class name from the given fully qualified class name.
353: *
354: * @param className An arbitrary class name, optionally including a package.
355: * @return The local name from the given class name.
356: */
357: public static String getLocalNameFromClassName(
358: final String className) {
359: if (className == null) {
360: return null;
361: }
362: int idx = className.lastIndexOf('.');
363: if (idx > 0) {
364: return className.substring(idx + 1);
365: }
366: return className;
367: }
368:
369: //--------------------------------------------------------------------------
370: }
|