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;
/**
* Copyright 2010 Guidewire Software, Inc.
*/
class ClassPreParser
{
private ISourceCodeTokenizer _tokenizer;
private File _classFile;
private String _strPackage;
private File _parentOfRootPackage;
private ClassPreParser( String strContent )
{
_tokenizer = GosuShop.createSourceCodeTokenizer( strContent );
}
static ClassPreParser parse( File file )
{
if( file == null )
{
return null;
}
String strContent;
try
{
strContent = StreamUtil.getContent( StreamUtil.getInputStreamReader( new FileInputStream( file ) ) );
}
catch( IOException e )
{
throw new RuntimeException( e );
}
if( strContent == null || strContent.length() == 0 )
{
return null;
}
ClassPreParser parser = new ClassPreParser( strContent );
parser.initTokenizer();
parser.parsePackage();
parser.findParentOfRootPackage( file );
return parser;
}
private void findParentOfRootPackage( File file )
{
if( _strPackage == null )
{
return;
}
_classFile = file.getAbsoluteFile();
File parent = _classFile.getParentFile();
File saveParent = parent;
String[] packages = _strPackage.split( "\\." );
for( int i = packages.length-1; i >= 0; i-- )
{
String strPackage = packages[i];
if( !parent.getName().equalsIgnoreCase( strPackage ) )
{
System.err.println( "Package: " + strPackage + " does not match with directory: " + parent.getAbsolutePath() + " in class: " + file.getAbsolutePath() );
break;
}
parent = parent.getParentFile();
}
_parentOfRootPackage = parent == null ? saveParent : parent;
}
private void initTokenizer()
{
_tokenizer.swallowPragmaIfNecessary();
try
{
_tokenizer.nextToken();
}
catch( IOException e )
{
throw new RuntimeException( e );
}
}
private void parsePackage()
{
if( match( Keyword.KW_package ) )
{
_strPackage = parseDotPathWord();
}
}
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 )
{
return match( token, false );
}
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 File getParentOfRootPackage()
{
return _parentOfRootPackage;
}
public String getClassName()
{
return _strPackage + '.' + getBaseFileName();
}
private String getBaseFileName()
{
return _classFile.getName().substring( 0, _classFile.getName().indexOf( '.' ) );
}
}