FileDocCategorySizeDatePackage
DefaultPolicyScanner.javaAPI DocAndroid 1.5 API17828Wed May 06 22:41:06 BST 2009org.apache.harmony.security

DefaultPolicyScanner

public class DefaultPolicyScanner extends Object
This is a basic high-level tokenizer of policy files. It takes in a stream, analyzes data read from it and returns a set of structured tokens.
This implementation recognizes text files, consisting of clauses with the following syntax:

keystore "some_keystore_url", "keystore_type";


grant [SignedBy "signer_names"] [, CodeBase "URL"]
[, Principal [principal_class_name] "principal_name"]
[, Principal [principal_class_name] "principal_name"] ... {
permission permission_class_name [ "target_name" ] [, "action"]
[, SignedBy "signer_names"];
permission ...
};

For semantical details of this format, see the {@link org.apache.harmony.security.fortress.DefaultPolicy default policy description}.
Keywords are case-insensitive in contrast to quoted string literals. Comma-separation rule is quite forgiving, most commas may be just omitted. Whitespaces, line- and block comments are ignored. Symbol-level tokenization is delegated to java.io.StreamTokenizer.

This implementation is effectively thread-safe, as it has no field references to data being processed (that is, passes all the data as method parameters).
see
org.apache.harmony.security.fortress.DefaultPolicyParser

Fields Summary
Constructors Summary
Methods Summary
protected java.lang.StringcomposeStatus(java.io.StreamTokenizer st)
Formats a detailed description of tokenizer status: current token, current line number, etc.

        return st.toString();
    
protected java.io.StreamTokenizerconfigure(java.io.StreamTokenizer st)
Configures passed tokenizer accordingly to supported syntax.

        st.slashSlashComments(true);
        st.slashStarComments(true);
        st.wordChars('_", '_");
        st.wordChars('$", '$");
        return st;
    
protected final voidhandleUnexpectedToken(java.io.StreamTokenizer st, java.lang.String message)
Throws InvalidFormatException with detailed diagnostics.

param
st a tokenizer holding the erroneous token
param
message a user-friendly comment, probably explaining expected syntax. Should not be null- use the overloaded single-parameter method instead.

        throw new InvalidFormatException(Messages.getString("security.8F", //$NON-NLS-1$
                composeStatus(st), message));
    
protected final voidhandleUnexpectedToken(java.io.StreamTokenizer st)
Throws InvalidFormatException with error status: which token is unexpected on which line.

param
st a tokenizer holding the erroneous token

        throw new InvalidFormatException(Messages.getString("security.90", //$NON-NLS-1$
                composeStatus(st)));
    
protected org.apache.harmony.security.DefaultPolicyScanner$GrantEntryreadGrantEntry(java.io.StreamTokenizer st)
Tries to read grant clause.
First, it reads codebase , signedby , principal entries till the '{' (opening curly brace) symbol. Then it calls readPermissionEntries() method to read the permissions of this clause.
Principal entries (if any) are read by invoking readPrincipalEntry() method, obtained PrincipalEntries are accumulated.
The expected syntax is

[ [codebase "url"] | [signedby "name1,...,nameN"] |
principal ...] ]* { ... }

return
successfully parsed GrantEntry
throws
IOException if stream reading failed
throws
InvalidFormatException if unexpected or unknown token encountered

        GrantEntry ge = new GrantEntry();
        parsing: while (true) {
            switch (st.nextToken()) {

            case StreamTokenizer.TT_WORD:
                if ("signedby".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
                    if (st.nextToken() == '"") {
                        ge.signers = st.sval;
                    } else {
                        handleUnexpectedToken(st, Messages.getString("security.8B")); //$NON-NLS-1$
                    }
                } else if ("codebase".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
                    if (st.nextToken() == '"") {
                        ge.codebase = st.sval;
                    } else {
                        handleUnexpectedToken(st, Messages.getString("security.8C")); //$NON-NLS-1$
                    }
                } else if ("principal".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
                    ge.addPrincipal(readPrincipalEntry(st));
                } else {
                    handleUnexpectedToken(st);
                }
                break;

            case ',": //just delimiter of entries
                break;

            case '{":
                ge.permissions = readPermissionEntries(st);
                break parsing;

            default: // handle token in the main loop
                st.pushBack();
                break parsing;
            }
        }

        return ge;
    
protected org.apache.harmony.security.DefaultPolicyScanner$KeystoreEntryreadKeystoreEntry(java.io.StreamTokenizer st)
Tries to read keystore clause fields. The expected syntax is

"some_keystore_url"[, "keystore_type"];

return
successfully parsed KeystoreEntry
throws
IOException if stream reading failed
throws
InvalidFormatException if unexpected or unknown token encountered

        KeystoreEntry ke = new KeystoreEntry();
        if (st.nextToken() == '"") {
            ke.url = st.sval;
            if ((st.nextToken() == '"")
                    || ((st.ttype == ',") && (st.nextToken() == '""))) {
                ke.type = st.sval;
            } else { // handle token in the main loop
                st.pushBack();
            }
        } else {
            handleUnexpectedToken(st, Messages.getString("security.8A")); //$NON-NLS-1$
        }
        return ke;
    
protected java.util.CollectionreadPermissionEntries(java.io.StreamTokenizer st)
Tries to read a list of permission entries. The expected syntax is

permission permission_class_name
[ "target_name" ] [, "action_list"]
[, signedby "name1,name2,..."];

List is terminated by '}' (closing curly brace) symbol.

return
collection of successfully parsed PermissionEntries
throws
IOException if stream reading failed
throws
InvalidFormatException if unexpected or unknown token encountered

        Collection<PermissionEntry> permissions = new HashSet<PermissionEntry>();
        parsing: while (true) {
            switch (st.nextToken()) {

            case StreamTokenizer.TT_WORD:
                if ("permission".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
                    PermissionEntry pe = new PermissionEntry();
                    if (st.nextToken() == StreamTokenizer.TT_WORD) {
                        pe.klass = st.sval;
                        if (st.nextToken() == '"") {
                            pe.name = st.sval;
                            st.nextToken();
                        }
                        if (st.ttype == ',") {
                            st.nextToken();
                        }
                        if (st.ttype == '"") {
                            pe.actions = st.sval;
                            if (st.nextToken() == ',") {
                                st.nextToken();
                            }
                        }
                        if (st.ttype == StreamTokenizer.TT_WORD
                                && "signedby".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
                            if (st.nextToken() == '"") {
                                pe.signers = st.sval;
                            } else {
                                handleUnexpectedToken(st);
                            }
                        } else { // handle token in the next iteration
                            st.pushBack();
                        }
                        permissions.add(pe);
                        continue parsing;
                    }
                }
                handleUnexpectedToken(st, Messages.getString("security.8E")); //$NON-NLS-1$
                break;

            case ';": //just delimiter of entries
                break;

            case '}": //end of list
                break parsing;

            default: // invalid token
                handleUnexpectedToken(st);
                break;
            }
        }

        return permissions;
    
protected org.apache.harmony.security.DefaultPolicyScanner$PrincipalEntryreadPrincipalEntry(java.io.StreamTokenizer st)
Tries to read Principal entry fields. The expected syntax is

[ principal_class_name ] "principal_name"

Both class and name may be wildcards, wildcard names should not surrounded by quotes.

return
successfully parsed PrincipalEntry
throws
IOException if stream reading failed
throws
InvalidFormatException if unexpected or unknown token encountered

        PrincipalEntry pe = new PrincipalEntry();
        if (st.nextToken() == StreamTokenizer.TT_WORD) {
            pe.klass = st.sval;
            st.nextToken();
        } else if (st.ttype == '*") {
            pe.klass = PrincipalEntry.WILDCARD;
            st.nextToken();
        }
        if (st.ttype == '"") {
            pe.name = st.sval;
        } else if (st.ttype == '*") {
            pe.name = PrincipalEntry.WILDCARD;
        } else {
            handleUnexpectedToken(st, Messages.getString("security.8D")); //$NON-NLS-1$
        }
        return pe;
    
public voidscanStream(java.io.Reader r, java.util.Collection grantEntries, java.util.List keystoreEntries)
Performs the main parsing loop. Starts with creating and configuring a StreamTokenizer instance; then tries to recognize keystore or grant keyword. When found, invokes read method corresponding to the clause and collects result to the passed collection.

param
r policy stream reader
param
grantEntries a collection to accumulate parsed GrantEntries
param
keystoreEntries a collection to accumulate parsed KeystoreEntries
throws
IOException if stream reading failed
throws
InvalidFormatException if unexpected or unknown token encountered

        StreamTokenizer st = configure(new StreamTokenizer(r));
        //main parsing loop
        parsing: while (true) {
            switch (st.nextToken()) {
            case StreamTokenizer.TT_EOF: //we've done the job
                break parsing;

            case StreamTokenizer.TT_WORD:
                if ("keystore".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
                    keystoreEntries.add(readKeystoreEntry(st));
                } else if ("grant".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
                    grantEntries.add(readGrantEntry(st));
                } else {
                    handleUnexpectedToken(st, Messages.getString("security.89")); //$NON-NLS-1$
                }
                break;

            case ';": //just delimiter of entries
                break;

            default:
                handleUnexpectedToken(st);
                break;
            }
        }