blob: be13c70dcf7c3722d81a696a5b8c41a5b36dd245 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0, which accompanies this distribution
* and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.utility.internal;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
/**
* Various helper methods for generating names.
*/
public final class NameTools {
/**
* Given a "root" name and a set of existing names, generate a unique,
* Java-legal name that is either the "root" name or some variation on
* the "root" name (e.g. "root2", "root3",...).
* The names are case-sensitive.
*/
public static String uniqueJavaNameFor(String rootName, Iterator<String> existingNames) {
Collection<String> existingNames2 = CollectionTools.set(existingNames);
existingNames2.addAll(JAVA_RESERVED_WORDS_SET);
return uniqueNameFor(rootName, existingNames2, rootName);
}
/**
* Given a "root" name and a set of existing names, generate a unique,
* Java-legal name that is either the "root" name or some variation on
* the "root" name (e.g. "root2", "root3",...).
* The names are case-sensitive.
*/
public static String uniqueJavaNameFor(String rootName, Collection<String> existingNames) {
Collection<String> existingNames2 = new HashSet<String>(existingNames);
existingNames2.addAll(JAVA_RESERVED_WORDS_SET);
return uniqueNameFor(rootName, existingNames2, rootName);
}
/**
* Given a "root" name and a set of existing names, generate a unique
* name that is either the "root" name or some variation on the "root"
* name (e.g. "root2", "root3",...). The names are case-sensitive.
*/
public static String uniqueNameFor(String rootName, Iterator<String> existingNames) {
return uniqueNameFor(rootName, CollectionTools.set(existingNames));
}
/**
* Given a "root" name and a set of existing names, generate a unique
* name that is either the "root" name or some variation on the "root"
* name (e.g. "root2", "root3",...). The names are case-sensitive.
*/
public static String uniqueNameFor(String rootName, Collection<String> existingNames) {
return uniqueNameFor(rootName, existingNames, rootName);
}
/**
* Given a "root" name and a set of existing names, generate a unique
* name that is either the "root" name or some variation on the "root"
* name (e.g. "root2", "root3",...). The names are NOT case-sensitive.
*/
public static String uniqueNameForIgnoreCase(String rootName, Iterator<String> existingNames) {
return uniqueNameForIgnoreCase(rootName, CollectionTools.set(existingNames));
}
/**
* Given a "root" name and a set of existing names, generate a unique
* name that is either the "root" name or some variation on the "root"
* name (e.g. "root2", "root3",...). The names are NOT case-sensitive.
*/
public static String uniqueNameForIgnoreCase(String rootName, Collection<String> existingNames) {
return uniqueNameFor(rootName, convertToLowerCase(existingNames), rootName.toLowerCase());
}
/**
* use the suffixed "template" name to perform the comparisons, but RETURN
* the suffixed "root" name; this allows case-insensitive comparisons
* (i.e. the "template" name has been morphed to the same case as
* the "existing" names, while the "root" name has not, but the "root" name
* is what the client wants morphed to be unique)
*/
private static String uniqueNameFor(String rootName, Collection<String> existingNames, String templateName) {
if ( ! existingNames.contains(templateName)) {
return rootName;
}
String uniqueName = templateName;
for (int suffix = 2; true; suffix++) {
if ( ! existingNames.contains(uniqueName + suffix)) {
return rootName.concat(String.valueOf(suffix));
}
}
}
/**
* Convert the specified collection of strings to a collection of the same
* strings converted to lower case.
*/
private static Collection<String> convertToLowerCase(Collection<String> strings) {
Collection<String> result = new HashBag<String>(strings.size());
for (String string : strings) {
result.add(string.toLowerCase());
}
return result;
}
/**
* Build a fully-qualified name for the specified database object.
* Variations:
* catalog.schema.name
* catalog..name
* schema.name
* name
*/
public static String buildQualifiedDatabaseObjectName(String catalog, String schema, String name) {
if (name == null) {
throw new IllegalArgumentException();
}
if ((catalog == null) && (schema == null)) {
return name;
}
StringBuffer sb = new StringBuffer(100);
if (catalog != null) {
sb.append(catalog);
sb.append('.');
}
if (schema != null) {
sb.append(schema);
}
sb.append('.');
sb.append(name);
return sb.toString();
}
/**
* The set of reserved words in the Java programming language.
* These words cannot be used as identifiers (i.e. names).
* http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
*/
public static final String[] JAVA_RESERVED_WORDS = new String[] {
"abstract",
"assert", // jdk 1.4
"boolean",
"break",
"byte",
"case",
"catch",
"char",
"class",
"const", // unused
"continue",
"default",
"do",
"double",
"else",
"enum", // jdk 5.0
"extends",
"false",
"final",
"finally",
"float",
"for",
"goto", // unused
"if",
"implements",
"import",
"instanceof",
"int",
"interface",
"long",
"native",
"new",
"null",
"package",
"private",
"protected",
"public",
"return",
"short",
"static",
"strictfp", // jdk 1.2
"super",
"switch",
"synchronized",
"this",
"throw",
"throws",
"transient",
"true",
"try",
"void",
"volatile",
"while"
};
/**
* The set of reserved words in the Java programming language.
* These words cannot be used as identifiers (i.e. names).
* http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
*/
public static final Set<String> JAVA_RESERVED_WORDS_SET = CollectionTools.set(JAVA_RESERVED_WORDS);
/**
* Return the set of Java programming language reserved words.
* These words cannot be used as identifiers (i.e. names).
* http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
*/
public static Iterator<String> javaReservedWords() {
return new ArrayIterator<String>(JAVA_RESERVED_WORDS);
}
/**
* Convert the specified string to a valid Java identifier
* by substituting an underscore '_' for any invalid characters
* in the string and capitalizing the string if it is a Java
* reserved word.
*/
public static String convertToJavaIdentifier(String string) {
return convertToJavaIdentifier(string, '_');
}
/**
* Convert the specified string to a valid Java identifier
* by substituting the specified character for any invalid characters
* in the string and capitalizing the string if it is a Java
* reserved word.
*/
public static String convertToJavaIdentifier(String string, char c) {
if (string.length() == 0) {
return string;
}
if (JAVA_RESERVED_WORDS_SET.contains(string)) {
// a reserved words is a valid identifier, we just need to tweak it a bit
return StringTools.capitalize(string);
}
return new String(convertToJavaIdentifierInternal(string.toCharArray(), c));
}
/**
* Convert the specified string to a valid Java identifier
* by substituting an underscore '_' for any invalid characters
* in the string and capitalizing the string if it is a Java
* reserved word.
*/
public static char[] convertToJavaIdentifier(char[] string) {
return convertToJavaIdentifier(string, '_');
}
/**
* Convert the specified string to a valid Java identifier
* by substituting the specified character for any invalid characters
* in the string and capitalizing the string if it is a Java
* reserved word.
*/
public static char[] convertToJavaIdentifier(char[] string, char c) {
int length = string.length;
if (length == 0) {
return string;
}
if (JAVA_RESERVED_WORDS_SET.contains(new String(string))) {
// a reserved words is a valid identifier, we just need to tweak it a bit
return StringTools.capitalize(string);
}
return convertToJavaIdentifierInternal(string, c);
}
private static char[] convertToJavaIdentifierInternal(char[] string, char c) {
if ( ! Character.isJavaIdentifierStart(string[0])) {
if ( ! Character.isJavaIdentifierStart(c)) {
throw new IllegalArgumentException("invalid Java identifier start char: '" + c + "'");
}
string[0] = c;
}
if ( ! Character.isJavaIdentifierPart(c)) {
throw new IllegalArgumentException("invalid Java identifier part char: '" + c + "'");
}
for (int i = string.length; i-- > 1; ) { // NB: end with 1
if ( ! Character.isJavaIdentifierPart(string[i])) {
string[i] = c;
}
}
return string;
}
// ********** constructor **********
/**
* Suppress default constructor, ensuring non-instantiability.
*/
private NameTools() {
super();
throw new UnsupportedOperationException();
}
}