FileDocCategorySizeDatePackage
ArgParserImpl.javaAPI DocGlassfish v2 API16253Fri May 04 22:24:52 BST 2007com.sun.cli.jmx.support

ArgParserImpl

public final class ArgParserImpl extends Object implements ArgParser

Fields Summary
boolean
mNamedArgs
String
mInput
int
mCurIndex
ParseChars
mParseChars
Constructors Summary
public ArgParserImpl()

	
	
		
	 
	
		mParseChars	= ParseChars.DEFAULT;
	
public ArgParserImpl(ParseChars parseChars)

		mParseChars	= parseChars;
	
Methods Summary
private booleanIsEscapableChar(int theChar, java.lang.String escapableChars)

		return( escapableChars.indexOf( theChar ) >= 0 || theChar == mParseChars.mEscapeChar );
	
public ParseResult[]Parse(java.lang.String input, boolean namedArgs)

		mNamedArgs	= namedArgs;
		mInput		= input;
		mCurIndex	= 0;
		
		final ArrayList	results	= new ArrayList();
		
		while ( inputRemainingCount() > 0 )
		{
			final ParseResult	nextArg	= ParseArg( );
			assert( nextArg != null );
			
			results.add( nextArg );
		}
		
		
		final ParseResult [] arrayResults 	= new ParseResult [ results.size( ) ];
		results.toArray( arrayResults );
		
		return( arrayResults );
	
private ParseResultParseArg()


		checkInputAvailable();
		
		ParseResult	result	= null;
		
		if ( mNamedArgs )
		{
			result	= ParseNamedArg();
		}
		else
		{
			result	= ParseNonNamedArg( "" + mParseChars.mArgDelim );
		}
		
		return( result );
	
private ParseResultParseArray()

		checkInputAvailable();
		
		// verify that it's an array
		int		theChar	= nextLiteralChar();
		if ( theChar !=  mParseChars.mArrayLeft )
		{
			backup( 1 );
			return( null );
		}
		
		final ArrayList	elems	= new ArrayList();
		
		boolean		endOfArrayFound	= false;
			
		if ( peekNextLiteralChar() == mParseChars.mArrayRight )
		{
			// empty array
			endOfArrayFound	= true;
			advance( 1 );
		}
		else
		{
			while ( (theChar = peekNextLiteralChar( )) > 0 )
			{
				final ParseResult	elem	= ParseNonNamedArg( "" +
						mParseChars.mArrayRight + mParseChars.mArgDelim );
				elems.add( elem );
				
				backup( 1 );
				if ( nextLiteralChar() == mParseChars.mArrayRight)
				{
					endOfArrayFound	= true;
					break;
				}
			}
		}
		
		if ( ! endOfArrayFound )
		{
			throw new ArgParserException( "end of array not found" );
		}
		
		final ParseResult []	resultsArray	= new ParseResult[ elems.size() ];
		elems.toArray( resultsArray );
		
		final ParseResult	result	= new ParseResult( ParseResult.ARRAY, resultsArray );
		
		return( result );
	
	
private ParseResultParseLiteralString()

		checkInputAvailable();
		
		// verify that it's a literal string
		int		theChar	= nextLiteralChar();
		if ( theChar != mParseChars.LITERAL_STRING_DELIM )
		{
			backup( 1 );
			return( null );
		}
		
		final StringBuffer	buf	= new StringBuffer();
		
		boolean		endOfStringFound	= false;
		while ( (theChar = peekNextLiteralChar( )) > 0 )
		{
			if ( theChar == mParseChars.LITERAL_STRING_DELIM )
			{
				endOfStringFound	= true;
				advance( 1 );
				break;
			}
			
			theChar = nextChar( mParseChars.mEscapeChar, mParseChars.mEscapableCharsWithinLiteralString );
			buf.append( (char)theChar );
		}
		
		if ( ! endOfStringFound )
		{
			throw new ArgParserException( "literal string must be terminated by double quote \"" );
		}
		
		
		final String		resultString	= new String( buf );
		
		final ParseResult	result	= new ParseResult( ParseResult.LITERAL_STRING, resultString );
		
		return( result );
	
private ParseResultParseNamedArg()

		checkInputAvailable();
		
		final String		name	= ParseNamedArgName();
		
		ParseResult	result	= null;
		
		// special case--no more input
		if ( inputRemainingCount() > 0 )
		{
			result	= ParseNonNamedArg( "" + mParseChars.mArgDelim );
		}
		else
		{
			result	= new ParseResult( ParseResult.OTHER, "");
		}
		result.setName( name );
		
		return( result );
	
private java.lang.StringParseNamedArgName()

		checkInputAvailable();
		
		final StringBuffer	buf	= new StringBuffer();
		
		boolean		foundDelim	= false;
		
		int		theChar	= 0;
		while ( (theChar = nextLiteralChar()) > 0 )
		{
			if ( theChar == mParseChars.ARG_VALUE_DELIM )
			{
				foundDelim	= true;
				break;
			}
			
			if ( ! Character.isJavaIdentifierPart( (char)theChar ) )
			{
				break;
			}
			
			buf.append( (char)theChar );
		}
		
		if ( ! foundDelim )
		{
			throw new ArgParserException(
				"named arguments must be of the form name=value: " + buf.toString() );
		}
		
		return( new String( buf ) );
	
public java.lang.String[]ParseNames(java.lang.String input)

		mInput		= input;
		mCurIndex	= 0;
		
		final ArrayList	list	= new ArrayList();
		
		StringBuffer	buf	= new StringBuffer();
		while ( true )
		{
			final int	theChar = nextLiteralChar();
			
			if ( theChar < 0 || theChar == mParseChars.mArgDelim )
			{
				list.add( new String( buf ) );
				buf.setLength( 0 );
				
				if ( theChar < 0 )
					break;
			}
			else
			{
				buf.append( (char)theChar );
			}
		}
		
		
		final String []	results	= (String [])list.toArray( new String [ list.size() ]);
		
		return( results );
	
private ParseResultParseNonNamedArg(java.lang.String delimiters)

		ParseResult	result	= null;
		
		String typeCast = ParseTypeCast();	// may be null--that's OK
		
		if ( isStringTypecast( typeCast ) )
		{
			if ( inputRemainingCount() == 0 )
			{
				// special case--a type cast followed by nothing is OK as an empty string
				result	= new ParseResult( ParseResult.LITERAL_STRING, "" );
				result.setTypeCast( typeCast );
				return( result );
			}
		}
		
		boolean	quotedString	= false;
		
		result = ParseLiteralString();
		if ( result != null )
		{
			// if a string X is quoted as "X" , this is equivalent (shorthand) for (String)X
			typeCast		= "String";
			quotedString	= true;
		}
		else
		{
			result	= ParseArray();
			if ( result == null )
			{
				result	= ParseRegular( delimiters );
			}
		}
		
		result.setTypeCast( typeCast );
		if ( isStringTypecast( typeCast ) && result.getType() != ParseResult.ARRAY )
		{
			result.setType( ParseResult.LITERAL_STRING );
			
			if (  (! quotedString) &&
				result.getData() instanceof String &&
				"null".equalsIgnoreCase( (String)result.getData() ) )
			{
				result.setData( null );
			}
		}
		
		// eat the delimiter
		final int	theChar	= nextLiteralChar();
		
		boolean	validDelimiter	= delimiters.indexOf( theChar ) >= 0 || theChar < 0;
		if ( ! validDelimiter )
		{
			throw new ArgParserException( "Syntax error: parsed this so far: " + mInput.substring( 1, mCurIndex ) );
		}
		
		return( result );
	
private ParseResultParseRegular(java.lang.String delimiters)

		checkInputAvailable();
		
		final StringBuffer	buf	= new StringBuffer();

		int theChar;
		while ( (theChar = peekNextLiteralChar() ) > 0 )
		{
			if ( delimiters.indexOf( theChar ) >= 0 )
			{
				break;
			}
			
			theChar	= nextChar();
			
			buf.append( (char)theChar );
		}
		
		final String		resultString	= new String( buf );
		
		final ParseResult	result	= new ParseResult( ParseResult.OTHER, resultString );
		
		return( result );
	
	
private java.lang.StringParseTypeCast()

		int		theChar	= nextLiteralChar();
		if ( theChar != mParseChars.TYPECAST_BEGIN )
		{
			backup( 1 );
			return( null );
		}
		
		final StringBuffer	buf	= new StringBuffer();
		
		theChar	= nextLiteralChar();
		if ( ! Character.isJavaIdentifierStart( (char)theChar ) )
		{
			final String	msg	= "type cast must contain a legal Java " +
			"identifier start character: " + peekRemaining();
			throw new ArgParserException( msg  );
		}
		buf.append( (char)theChar );
		
		boolean		foundDelim	= false;
		while ( (theChar = nextLiteralChar( )) > 0 )
		{
			if ( theChar == mParseChars.TYPECAST_END )
			{
				foundDelim	= true;
				break;
			}
			
			if ( theChar != '." && ! Character.isJavaIdentifierPart( (char)theChar ) )
			{
				throw new ArgParserException( "type cast must contain a legal Java identifier part: " +
							(char)theChar );
			}
			
			buf.append( (char)theChar );
		}
		
		if ( ! foundDelim )
		{
			throw new ArgParserException( "type cast must be terminated by the ) character" );
		}
		
		final String		result	= new String( buf );
		
		if ( result.length() == 0 )
		{
			throw new ArgParserException( "type cast must contain a type" );
		}
		
		return( result );
	
private voidadvance(int count)

		assert( count <= inputRemainingCount() );
		
		mCurIndex	+= count;
	
private voidbackup(int count)

		assert( count <= mCurIndex );
		
		mCurIndex	-= count;
	
private voidcheckInputAvailable()

		if ( inputRemainingCount() == 0 )
		{
			throw new ArgParserException( "expecting additional input" );
		}
	
private intescapeCharToChar(int theChar)

		int	result	= -1;
		
		if ( theChar == 'n" )
			result	= '\n";
		else if ( theChar == 'r"  )
			result	= '\r";
		else if ( theChar == 't"  )
			result	= '\t";
		else
			result	= theChar;
		
		return( result );
	
private intinputRemainingCount()

		return( mInput.length() - mCurIndex );
	
private static booleanisDigit(int theChar)

		return( (theChar >= '0" && theChar <= '9") );
	
private static booleanisHexDigit(int theChar)

		return( isDigit( theChar ) || (theChar >= 'a" && theChar <= 'f") || 
			(theChar >= 'A" && theChar <= 'F") );
	
booleanisStringTypecast(java.lang.String typecast)

		return( typecast != null &&
			(typecast.equals( "String" ) || typecast.equals( "java.lang.String" ) ) );
	
private intnextChar(int escapeChar, java.lang.String escapableChars)

		int	result	= -1;
		
		final int	theChar	= nextLiteralChar();
		if ( theChar == escapeChar )
		{
			final int	theNextChar	= nextLiteralChar();
			if ( IsEscapableChar( theNextChar, escapableChars )  )
			{
				result	= escapeCharToChar( theNextChar );
			}
			else
			{
				// if valid hexadecimal, convert two hex digits to a number
				// otherwise emit the escape char and restart
				// should we allow unicode?
				result	= escapeChar;
				if ( isHexDigit( theNextChar ) && peekNextLiteralChar() > 0 )
				{
					final int theNextNextChar	= nextLiteralChar();
					if ( isHexDigit( theNextNextChar ) )
					{
						result	= (((int)theNextChar) << 4) + (int)theNextNextChar;
					}
				}
				else
				{
					backup( 1 );
				}
			}
		}
		else
		{
			result	= theChar;
		}
		
		return( result );
	
private intnextChar()

		return( nextChar( mParseChars.mEscapeChar, mParseChars.mEscapableChars ) );
	
private intnextLiteralChar()

		final int	result	= peekNextLiteralChar();
		if ( result >  0 )
		{
			advance( 1 );
		}
		
		return( result );
	
private static voidp(java.lang.Object o)

		System.out.println( o.toString() );
	
private intpeekNextLiteralChar()

		if ( inputRemainingCount() <= 0 )
			return( -1 );
			
		final char	result	= mInput.charAt( mCurIndex );
		
		return( result );
	
private java.lang.StringpeekRemaining()

		if ( inputRemainingCount() <= 0 )
			return( "" );
		
		return( mInput.substring( mCurIndex, mInput.length() ) );