package gw.lang.shell;
import gw.lang.GosuShop;
import gw.lang.parser.ISourceCodeTokenizer;
import gw.lang.parser.Keyword;
import gw.util.StreamUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Copyright 2010 Guidewire Software, Inc.
*/
class ProgramDirectiveParser
{
private ISourceCodeTokenizer _tokenizer;
private ProgramDirectiveInfo _directiveInfo;
private ProgramDirectiveParser( String strContent )
{
_tokenizer = GosuShop.createSourceCodeTokenizer( strContent );
_directiveInfo = new ProgramDirectiveInfo();
}
static ProgramDirectiveInfo parse( File file )
{
try
{
if( file == null )
{
return null;
}
String strContent = StreamUtil.getContent( StreamUtil.getInputStreamReader( new FileInputStream( file ) ) );
return parse( strContent );
}
catch( IOException e )
{
throw new RuntimeException( e );
}
}
static ProgramDirectiveInfo parse( String strContent )
{
if( strContent == null || strContent.length() == 0 )
{
return null;
}
ProgramDirectiveParser parser = new ProgramDirectiveParser( strContent );
parser.initTokenizer();
parser.parseClasspaths();
parser.parseTypeLoaders();
return parser.getDirectiveInfo();
}
private void initTokenizer()
{
_tokenizer.swallowPragmaIfNecessary();
try
{
_tokenizer.nextToken();
}
catch( IOException e )
{
throw new RuntimeException( e );
}
}
private void parseClasspaths()
{
List<String> paths = new ArrayList<String>();
while( match( Keyword.KW_classpath, false ) )
{
String strClasspath = _tokenizer.getStringValue();
if( !match( null, (int)'"', false ) )
{
throw new IllegalStateException( "Expecting classpath as string" );
}
paths.addAll( Arrays.asList( strClasspath.split( "," ) ) );
}
_directiveInfo.setClasspaths( paths );
}
private void parseTypeLoaders()
{
List<String> loaders = new ArrayList<String>();
while( match( Keyword.KW_typeloader, false ) )
{
String strLoader = parseDotPathWord();
loaders.add( strLoader );
}
_directiveInfo.setTypeLoaders( loaders );
}
String parseDotPathWord()
{
StringBuilder sb = new StringBuilder( _tokenizer.getStringValue() );
if( match( null, ISourceCodeTokenizer.TT_WORD, false ) )
{
while( match( null, '.', false ) )
{
sb.append( '.' );
sb.append( _tokenizer.getStringValue() );
match( null, ISourceCodeTokenizer.TT_WORD, false );
}
}
return sb.toString();
}
private boolean match( Keyword token, boolean bPeek )
{
boolean bMatch = false;
if( ISourceCodeTokenizer.TT_KEYWORD == _tokenizer.getType() )
{
bMatch = token.toString().equalsIgnoreCase( _tokenizer.getStringValue() );
}
if( bMatch && !bPeek )
{
try
{
_tokenizer.nextToken();
}
catch( IOException e )
{
// ignore
}
}
return bMatch;
}
private boolean match( String token, int iType, boolean bPeek )
{
boolean bMatch = false;
if( token != null )
{
if( (iType == _tokenizer.getType()) || ((iType == 0) && (_tokenizer.getType() == ISourceCodeTokenizer.TT_WORD)) )
{
bMatch = token.equalsIgnoreCase( _tokenizer.getStringValue() );
}
}
else
{
bMatch = (_tokenizer.getType() == iType) || isValueKeyword( iType );
}
if( bMatch && !bPeek )
{
try
{
_tokenizer.nextToken();
}
catch( IOException e )
{
// ignore
}
}
return bMatch;
}
private boolean isValueKeyword( int iType )
{
return iType == ISourceCodeTokenizer.TT_WORD &&
_tokenizer.getType() == ISourceCodeTokenizer.TT_KEYWORD &&
Keyword.isReservedValue( _tokenizer.getStringValue() );
}
public ProgramDirectiveInfo getDirectiveInfo()
{
return _directiveInfo;
}
}