/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.common.namedobject; import java.text.CharacterIterator; import java.text.StringCharacterIterator; import org.teiid.designer.common.util.ErrorMessageKeys; /** * This class contains several helper methods that check the validity of BaseID instances. * <p> * A BaseID is considered valid only if <i>all</i> of the following conditions are met: * <li>The full name is at least one character long;</li> * <li>The first character of the full name is a letter; and</li> * <li>Each of the remaining characters of the full name is either is a letter, the MetadataID.DELIMITER_CHARACTER, a decimal * digit, or the underscore character ('_'). * * @since 8.0 */ public class IDVerifier { /** * The underscore character allowed in full names anywhere except for the first character. */ public static final char UNDERSCORE_CHARACTER = '_'; /** * The private character (in the form of char) that delimits the atomic components of the name */ public static final char DELIMITER_CHARACTER = '.'; /** * The result of a <code>performCheck</code> signifying that the full name is valid. */ public static final int NONE = 0; /** * The result of a <code>performCheck</code> signifying that the full name was zero-length. */ public static final int ZERO_LENGTH_FULL_NAME = 1; /** * The result of a <code>performCheck</code> signifying that the first character of the full name is not a letter. */ public static final int FIRST_CHARACTER_IS_NOT_A_LETTER = 2; /** * The result of a <code>performCheck</code> signifying that a character (other than the first character) contained a * character that wasn't a letter, digit, underscore, space, or delimiter. */ public static final int CONTAINS_INVALID_CHARACTER = 4; /** * The result of a <code>performCheck</code> signifying that a character (other than the first character) contained a * character that was a space. */ public static final int CONTAINS_SPACE = 8; /** * The result of a <code>performCheck</code> signifying that a character (other than the first character) contained a * character that was a space. */ public static final int ALL = 15; /** * Method to determine whether a BaseID has a valid full name. This method is primarily a utility method used within the * Configuration Service; it is anticipated that this method does not need to be used by other components, since all * components (other than those within Metadata Service) are able to create only valid IDs. * * @param id the BaseID that is to be checked for validity * @return true if the specified BaseID is valid, or false otherwise * @throws IllegalArgumentException if the BaseID reference is null. */ public static boolean isValid( BaseID id ) { if (id == null) { throw new IllegalArgumentException(ErrorMessageKeys.NAMEDOBJECT_ERR_0006); } return IDVerifier.performCheck(id.getFullName()) == NONE; } /** * Method to determine whether a MetadataID has a valid full name, and, if not valid, to identify why it is invalid. This * method is primarily a utility method used within the Metadata Service; it is anticipated that this method does not need to * be used by other components, since all components (other than those within Metadata Service) are able to create only valid * IDs. * * @param id the BaseID that is to be checked for validity * @return true if the specified MetadataID is valid, or false otherwise * @throws IllegalArgumentException if the MetadataID reference is null. */ public static int performCheck( BaseID id ) { if (id == null) { throw new IllegalArgumentException(ErrorMessageKeys.NAMEDOBJECT_ERR_0007); } return IDVerifier.performCheck(id.getFullName()); } public static int performCheck( String fullName ) { return performCheck(fullName, ALL); } public static int performCheck( String fullName, int levels ) { // This method is somewhat optimized to reduce recurrent checks, // and is therefore more complicated ... if (fullName.length() == 0 && (levels & ZERO_LENGTH_FULL_NAME) != 0) { return ZERO_LENGTH_FULL_NAME; } StringCharacterIterator iter = new StringCharacterIterator(fullName); char c = iter.first(); // If the first character should be a letter ... if ((levels & FIRST_CHARACTER_IS_NOT_A_LETTER) != 0 && !Character.isLetter(c)) { return FIRST_CHARACTER_IS_NOT_A_LETTER; } // If the spaces are to be exclued ... if ((levels & CONTAINS_SPACE) != 0) { // No spaces allowed and no invalid characters allowed ... if ((levels & CONTAINS_INVALID_CHARACTER) != 0) { do { if (Character.isSpaceChar(c)) { return CONTAINS_SPACE; } else if (!Character.isLetterOrDigit(c) && c != UNDERSCORE_CHARACTER && c != DELIMITER_CHARACTER) { return CONTAINS_INVALID_CHARACTER; } } while ((c = iter.next()) != CharacterIterator.DONE); } // Otherwise only spaces are not allowed ... else { return (fullName.indexOf(' ') != -1) ? CONTAINS_SPACE : NONE; } } // Therefore spaces are allowed, but if invalid characters are not else if ((levels & CONTAINS_INVALID_CHARACTER) != 0) { do { if (!Character.isLetterOrDigit(c) && !Character.isSpaceChar(c) && c != UNDERSCORE_CHARACTER && c != DELIMITER_CHARACTER) { return CONTAINS_INVALID_CHARACTER; } } while ((c = iter.next()) != CharacterIterator.DONE); } // Otherwise, spaces are allowed and invalid characters are as well return NONE; } }