* };
* </pre>
* @throws InvalidPolicyTextException thrown if invalid grant entry syntax is detected
*/
private void parseGrantEntry() throws InvalidPolicyTextException {
final GrantEntry grantEntry = new GrantEntry();
newIndex = firstLastTokenIndices[ 1 ];
boolean firstIteration = true;
char nextChar;
// First we parse the grant parameters such as signedBy, codeBase and the principals.
while ( ( nextChar = peekNextNonWhiteSpaceChar( newIndex ) ) != '{' ) {
if ( firstIteration )
firstIteration = false;
else
if ( nextChar != ',' )
throw new InvalidPolicyTextException( "Was expecting comma but found something else!" );
else
newIndex = skipWhiteSpaces( newIndex ) + 1;
final int[] paramNameIndices = peekTokenAhead( newIndex );
if ( paramNameIndices == null )
throw new InvalidPolicyTextException( "Incomplete grant entry!" );
final String loweredParamName = policyText.substring( paramNameIndices[ 0 ], paramNameIndices[ 1 ] ).toLowerCase();
if ( loweredParamName.equals( "signedby" ) ) {
final int[] paramValueIndices = peekQuotedStringAhead( paramNameIndices[ 1 ] );
if ( paramValueIndices == null )
throw new InvalidPolicyTextException( "Incomplete keystore entry, found no quoted string for signedBy!" );
if ( grantEntry.getSignedBy() != null )
throw new InvalidPolicyTextException( "Invalid keystore entry, only 1 signedBy allowed!" );
if ( grantEntry.getCodeBase() != null || !grantEntry.getPrincipalList().isEmpty() )
throw new InvalidPolicyTextException( "Invalid keystore entry, signedBy cannot be after codeBase or principals!" );
grantEntry.setSignedBy( policyText.substring( paramValueIndices[ 0 ] + 1, paramValueIndices[ 1 ] - 1 ) );
newIndex = paramValueIndices[ 1 ];
}
else if ( loweredParamName.equals( "codebase" ) ) {
final int[] firstLastParamValueIndices = peekQuotedStringAhead( paramNameIndices[ 1 ] );
if ( firstLastParamValueIndices == null )
throw new InvalidPolicyTextException( "Incomplete keystore entry, found no quoted string for codeBase!" );
if ( grantEntry.getCodeBase() != null )
throw new InvalidPolicyTextException( "Invalid keystore entry, only 1 codeBase allowed!" );
if ( !grantEntry.getPrincipalList().isEmpty() )
throw new InvalidPolicyTextException( "Invalid keystore entry, signedBy cannot be after principals!" );
grantEntry.setCodeBase( policyText.substring( firstLastParamValueIndices[ 0 ] + 1, firstLastParamValueIndices[ 1 ] - 1 ) );
newIndex = firstLastParamValueIndices[ 1 ];
}
else if ( loweredParamName.equals( "principal" ) ) {
final int[] classNameIndices = peekTokenAhead( paramNameIndices[ 1 ] );
if ( classNameIndices == null || policyTextChars[ classNameIndices[ 0 ] ] == '{' )
throw new InvalidPolicyTextException( "Invalid grant entry, found no class name for principal!" );
final int[] principalNameIndices = peekQuotedStringAhead( classNameIndices[ 1 ] );
if ( principalNameIndices == null )
throw new InvalidPolicyTextException( "Invalid grant entry, found no name for principal!" );
final Principal principal = new Principal();
principal.setType( policyText.substring( classNameIndices[ 0 ], classNameIndices[ 1 ] ) );
principal.setName( policyText.substring( principalNameIndices[ 0 ] + 1, principalNameIndices[ 1 ] - 1 ) );
grantEntry.getPrincipalList().add( principal );
newIndex = principalNameIndices[ 1 ];
}
}
newIndex = policyText.indexOf( '{', newIndex ) + 1;
// Now permissions what we have left
while ( ( nextChar = peekNextNonWhiteSpaceChar( newIndex ) ) != '}' ) {
final int[] keywordIndices = peekTokenAhead( newIndex );
if ( keywordIndices == null )
throw new InvalidPolicyTextException( "Incomplete grant entry!" );
final String loweredKeyword = policyText.substring( keywordIndices[ 0 ], keywordIndices[ 1 ] ).toLowerCase();
if ( !loweredKeyword.equals( "permission" ) )
throw new InvalidPolicyTextException( "Incomplete grant entry, was expecting permission but found something else!" );
final int[] classNameIndices = peekTokenAhead( keywordIndices[ 1 ] );
if ( classNameIndices == null || policyTextChars[ classNameIndices[ 0 ] ] == '}' )
throw new InvalidPolicyTextException( "Invalid grant entry, found no class name for permission!" );
if ( classNameIndices[ 1 ] - classNameIndices[ 0 ] == 0 ) {
if ( policyTextChars[ classNameIndices[ 0 ] ] == ',' || policyTextChars[ classNameIndices[ 0 ] ] == PolicyEntry.TERMINATOR_CHAR ) // Class name is only a comma or a semicolon
throw new InvalidPolicyTextException( "Invalid grant entry, found no class name for permission!" );
}
else {
if ( policyTextChars[ classNameIndices[ 1 ] - 1 ] == ',' || policyTextChars[ classNameIndices[ 1 ] - 1 ] == PolicyEntry.TERMINATOR_CHAR )
classNameIndices[ 1 ]--; // Class name is more than 1 character long and comma or semicolon is at its end; we step back from it
}
int[] targetNameIndices = null;
int[] actionsIndices = null;
int[] signedByIndices = null;
nextChar = peekNextNonWhiteSpaceChar( classNameIndices[ 1 ] );
if ( nextChar != PolicyEntry.TERMINATOR_CHAR ) {
if ( nextChar != ',' ) {
// There must be a target name here!
targetNameIndices = peekQuotedStringAhead( classNameIndices[ 1 ] );
if ( targetNameIndices == null )
throw new InvalidPolicyTextException( "Invalid grant entry, found no name for permission!" );
}
newIndex = targetNameIndices == null ? classNameIndices[ 1 ] : targetNameIndices[ 1 ];
nextChar = peekNextNonWhiteSpaceChar( newIndex );
if ( nextChar != PolicyEntry.TERMINATOR_CHAR ) {
if ( nextChar != ',' )
throw new InvalidPolicyTextException( "Was expecting semicolon but found something else!" );
newIndex = skipWhiteSpaces( newIndex );
nextChar = peekNextNonWhiteSpaceChar( newIndex + 1 );
if ( nextChar == '"' ) { // actions are specified
actionsIndices = peekQuotedStringAhead( newIndex + 1 );
if ( actionsIndices == null )
throw new InvalidPolicyTextException( "Incomplete keystore entry, found no quoted string for permission actions!" );
newIndex = actionsIndices[ 1 ];
}
nextChar = peekNextNonWhiteSpaceChar( newIndex );
if ( nextChar != PolicyEntry.TERMINATOR_CHAR ) {
if ( nextChar != ',' )
throw new InvalidPolicyTextException( "Was expecting semicolon but found something else!" );
final int[] signedByKeywordIndices = peekTokenAhead( skipWhiteSpaces( newIndex ) + 1 );
final String loweredSignedByKeyword = policyText.substring( signedByKeywordIndices[ 0 ], signedByKeywordIndices[ 1 ] ).toLowerCase();
if ( !loweredSignedByKeyword.equals( "signedby" ) )
throw new InvalidPolicyTextException( "Incomplete grant entry, was expecting signedBy but found something else!" );
signedByIndices = peekQuotedStringAhead( signedByKeywordIndices[ 1 ] );
if ( signedByIndices == null )
throw new InvalidPolicyTextException( "Incomplete keystore entry, found no quoted string for permission signedBy!" );
if ( peekNextNonWhiteSpaceChar( signedByIndices[ 1 ] ) != PolicyEntry.TERMINATOR_CHAR )
throw new InvalidPolicyTextException( "Was expecting semicolon but found something else!" );
else
newIndex = skipWhiteSpaces( signedByIndices[ 1 ] ) + 1;
}
else
newIndex = skipWhiteSpaces( newIndex ) + 1;
}
else
newIndex = skipWhiteSpaces( newIndex ) + 1;
}
else
newIndex = skipWhiteSpaces( classNameIndices[ 1 ] ) + 1;
final Permission permission = new Permission();
permission.setClassName( policyText.substring( classNameIndices[ 0 ], classNameIndices[ 1 ] ) );
if ( targetNameIndices != null )
permission.setTargetName( policyText.substring( targetNameIndices[ 0 ] + 1, targetNameIndices[ 1 ] - 1 ) );
if ( actionsIndices != null )
permission.setActions( policyText.substring( actionsIndices[ 0 ] + 1, actionsIndices[ 1 ] - 1 ) );
if ( signedByIndices != null )
permission.setSignedBy( policyText.substring( signedByIndices[ 0 ] + 1, signedByIndices[ 1 ] - 1 ) );
grantEntry.getPermissionList().add( permission );
}
newIndex = skipWhiteSpaces( newIndex ) + 1; // index of '}' + 1 (comments skipped)
if ( peekNextNonWhiteSpaceChar( newIndex ) != PolicyEntry.TERMINATOR_CHAR )
throw new InvalidPolicyTextException( "Was expecting semicolon but found something else!" );