/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.directory.studio.schemaeditor.model.alias;
public class AliasesStringScanner
{
private static final char CHAR_COMMA = ',';
private static final char CHAR_EOF = '\u0000';
/** The aliases to scan */
private String aliases;
/** The current position */
private int pos;
/** The last token type. */
private int lastTokenType;
/**
* Creates a new instance of LdapFilterScanner.
*/
public AliasesStringScanner()
{
super();
aliases = ""; //$NON-NLS-1$
}
/**
* Resets this scanner.
*
* @param aliases the new aliases to scan
*/
public void reset( String aliases )
{
this.aliases = aliases;
pos = -1;
lastTokenType = AliasesStringToken.START;
}
/**
* Gets the character at the current position.
*
* @return the character at the current position
*/
private char currentChar()
{
return 0 <= pos && pos < aliases.length() ? aliases.charAt( pos ) : CHAR_EOF;
}
/**
* Increments the position counter and gets
* the character at that positon.
*
* @return the character at the next position
*/
private char nextChar()
{
pos++;
return currentChar();
}
/**
* Decrements the position counter and gets
* the character at that positon.
*
* @return the character at the previous position
*/
private char prevChar()
{
pos--;
return currentChar();
}
/**
* Gets the next token.
*
* @return the next token
*/
public AliasesStringToken nextToken()
{
char c;
// check for EOF
c = nextChar();
if ( c == CHAR_EOF )
{
lastTokenType = AliasesStringToken.EOF;
return new AliasesStringToken( lastTokenType, "", pos ); //$NON-NLS-1$
}
prevChar();
// check the substring if there was an error
c = nextChar();
if ( lastTokenType == AliasesStringToken.ERROR_ALIAS_PART
|| lastTokenType == AliasesStringToken.ERROR_ALIAS_START )
{
StringBuffer sb = new StringBuffer();
while ( c != CHAR_COMMA && c != CHAR_EOF )
{
sb.append( c );
c = nextChar();
}
lastTokenType = AliasesStringToken.ERROR_ALIAS_SUBSTRING;
return new AliasesStringToken( lastTokenType, sb.toString(), pos - sb.length() + 1 );
}
prevChar();
// check for ignorable whitespaces
c = nextChar();
if ( Character.isWhitespace( c ) )
{
StringBuffer sb = new StringBuffer();
while ( Character.isWhitespace( c ) )
{
sb.append( c );
c = nextChar();
}
prevChar();
lastTokenType = AliasesStringToken.WHITESPACE;
return new AliasesStringToken( lastTokenType, sb.toString(), pos - sb.length() + 1 );
}
prevChar();
// check special characters
c = nextChar();
if ( c == CHAR_COMMA )
{
lastTokenType = AliasesStringToken.COMMA;
return new AliasesStringToken( lastTokenType, ",", pos ); //$NON-NLS-1$
}
prevChar();
// check Alias
c = nextChar();
if ( isAliasSafeCharStart( c ) )
{
StringBuffer sb = new StringBuffer();
boolean hasError = false;
sb.append( c );
c = nextChar();
while ( c != CHAR_COMMA && c != CHAR_EOF )
{
sb.append( c );
if ( !isAliasSafeCharPart( c ) )
{
hasError = true;
break;
}
c = nextChar();
}
if ( hasError )
{
lastTokenType = AliasesStringToken.ERROR_ALIAS_PART;
return new AliasesStringToken( lastTokenType, sb.toString(), pos - sb.length() + 1 );
}
else
{
prevChar();
lastTokenType = AliasesStringToken.ALIAS;
return new AliasesStringToken( lastTokenType, sb.toString(), pos - sb.length() + 1 );
}
}
else
{
lastTokenType = AliasesStringToken.ERROR_ALIAS_START;
return new AliasesStringToken( lastTokenType, c + "", pos ); //$NON-NLS-1$
}
}
/**
* Determines if the specified character is
* permissible as the first character in an attribute type or object class
* alias.
* <p>
* A character may start an attribute type or object class alias if and
* only if one of the following conditions is true:
* <ul>
* <li> it is a letter between 'a' to 'z' and between 'A' to 'Z'
* </ul>
*
* <p><b>Note:</b> This method cannot handle <a
* href="#supplementary"> supplementary characters</a>. To support
* all Unicode characters, including supplementary characters, use
* the {@link #isJavaIdentifierStart(int)} method.
*
* @param c the character to be tested.
* @return <code>true</code> if the character may start an attribute type
* or object class alias.; <code>false</code> otherwise.
*/
private boolean isAliasSafeCharStart( char c )
{
return ( c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f' || c == 'g' || c == 'h'
|| c == 'i' || c == 'j' || c == 'k' || c == 'l' || c == 'm' || c == 'n' || c == 'o' || c == 'p' || c == 'q'
|| c == 'r' || c == 's' || c == 't' || c == 'u' || c == 'v' || c == 'w' || c == 'x' || c == 'y' || c == 'z'
|| c == 'A' || c == 'B' || c == 'C' || c == 'D' || c == 'E' || c == 'F' || c == 'G' || c == 'H' || c == 'I'
|| c == 'J' || c == 'K' || c == 'L' || c == 'M' || c == 'N' || c == 'O' || c == 'P' || c == 'Q' || c == 'R'
|| c == 'S' || c == 'T' || c == 'U' || c == 'V' || c == 'W' || c == 'X' || c == 'Y' || c == 'Z' );
}
/**
* Determines if the specified character may be part of an attribute type or
* object class alias as other than the first character.
* <p>
* A character may be part of an attribute type or object class alias if any
* of the following are true:
* <ul>
* <li> it is a letter between 'a' to 'z' and between 'A' to 'Z'
* <li> it is a digit
* <li> it is a hyphen ('-')
* <li> it is a semi-colon (';')
* </ul>
*
* @param c the character to be tested.
* @return <code>true</code> if the character may be part of an attribute
* type or object class alias; <code>false</code> otherwise.
*/
private boolean isAliasSafeCharPart( char c )
{
return ( c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f' || c == 'g' || c == 'h'
|| c == 'i' || c == 'j' || c == 'k' || c == 'l' || c == 'm' || c == 'n' || c == 'o' || c == 'p' || c == 'q'
|| c == 'r' || c == 's' || c == 't' || c == 'u' || c == 'v' || c == 'w' || c == 'x' || c == 'y' || c == 'z'
|| c == 'A' || c == 'B' || c == 'C' || c == 'D' || c == 'E' || c == 'F' || c == 'G' || c == 'H' || c == 'I'
|| c == 'J' || c == 'K' || c == 'L' || c == 'M' || c == 'N' || c == 'O' || c == 'P' || c == 'Q' || c == 'R'
|| c == 'S' || c == 'T' || c == 'U' || c == 'V' || c == 'W' || c == 'X' || c == 'Y' || c == 'Z' || c == '0'
|| c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9' || c == '-' );
}
}