Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 39401 invoked from network); 8 Aug 2006 21:13:22 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 8 Aug 2006 21:13:22 -0000 Received: (qmail 84052 invoked by uid 500); 8 Aug 2006 21:13:22 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 84016 invoked by uid 500); 8 Aug 2006 21:13:22 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 84005 invoked by uid 99); 8 Aug 2006 21:13:22 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 08 Aug 2006 14:13:22 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 08 Aug 2006 14:13:21 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 068BD1A981D; Tue, 8 Aug 2006 14:13:01 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r429815 - /incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/FilePermission.java Date: Tue, 08 Aug 2006 21:13:00 -0000 To: harmony-commits@incubator.apache.org From: tellison@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20060808211301.068BD1A981D@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: tellison Date: Tue Aug 8 14:13:00 2006 New Revision: 429815 URL: http://svn.apache.org/viewvc?rev=429815&view=rev Log: Code tidy-up and fix minor compiler warnings. Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/FilePermission.java Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/FilePermission.java URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/FilePermission.java?rev=429815&r1=429814&r2=429815&view=diff ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/FilePermission.java (original) +++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/FilePermission.java Tue Aug 8 14:13:00 2006 @@ -15,11 +15,13 @@ package java.io; - import java.security.AccessController; import java.security.Permission; +import java.security.PermissionCollection; import java.security.PrivilegedAction; +import org.apache.harmony.luni.util.Msg; + /** * The class FilePermission is responsible for granting access to files or * directories. The FilePermission is made up of a pathname and a set of actions @@ -34,304 +36,330 @@ * */ public final class FilePermission extends Permission implements Serializable { - private static final long serialVersionUID = 7930732926638008763L; + private static final long serialVersionUID = 7930732926638008763L; - // canonical path of this permission - private transient String canonPath; + // canonical path of this permission + private transient String canonPath; - // list of actions permitted for socket permission in order - private static final String[] actionList = { "read", "write", "execute", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - "delete" }; //$NON-NLS-1$ - - // "canonicalized" action list - private String actions; - - // the numeric representation of this action list - // for implies() to check if one action list is the subset of another. - transient int mask = -1; - - // global include all permission? - private transient boolean includeAll = false; - - private transient boolean allDir = false; - - private transient boolean allSubdir = false; - - /** - * Constructs a new FilePermission with the path and actions specified. - * - * - * @param path - * the path to apply the actions to. - * @param actions - * the actions for the path. May be any - * combination of read, write, execute, or delete. - */ - public FilePermission(String path, String actions) { - super(path); - init(path, actions); - } - - private void init(final String path, String pathActions) { - if (pathActions != null && pathActions != "") { //$NON-NLS-1$ - if (path != null) { - if (path.equals("<>")) { //$NON-NLS-1$ - includeAll = true; - } else { - canonPath = AccessController - .doPrivileged(new PrivilegedAction() { - public String run() { - try { - return new File(path) - .getCanonicalPath(); - } catch (IOException e) { - return path; - } - } - }); - if (path.equals("*") || path.endsWith(File.separator + "*")) - allDir = true; - if (path.equals("-") || path.endsWith(File.separator + "-")) - allSubdir = true; - } - this.actions = toCanonicalActionString(pathActions); - } else - throw new NullPointerException(org.apache.harmony.luni.util.Msg - .getString("K006e")); //$NON-NLS-1$ - } else - throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg - .getString("K006d")); //$NON-NLS-1$ - } - - /** - * Answer the string representing this permissions actions. It must be of - * the form "read,write,execute,delete", all lower case and in the correct - * order if there is more than one action. - * - * @param action - * the action name - * @return the string representing this permission's actions - */ - private String toCanonicalActionString(String action) { - actions = action.trim().toLowerCase(); - - // get the numerical representation of the action list - mask = getMask(actions); - - // convert the mask to a canonical action list. - int len = actionList.length; - // the test mask - shift the 1 to the leftmost position of the - // actionList - int highestBitMask = 1 << (len - 1); + // list of actions permitted for socket permission in order + private static final String[] actionList = { "read", "write", "execute", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "delete" }; //$NON-NLS-1$ + + // "canonicalized" action list + private String actions; + + // the numeric representation of this action list + // for implies() to check if one action list is the subset of another. + transient int mask = -1; + + // global include all permission? + private transient boolean includeAll = false; + + private transient boolean allDir = false; + + private transient boolean allSubdir = false; + + /** + * Constructs a new FilePermission with the path and actions specified. + * + * + * @param path + * the path to apply the actions to. + * @param actions + * the actions for the path. May be any + * combination of read, write, execute, or delete. + */ + public FilePermission(String path, String actions) { + super(path); + init(path, actions); + } + + private void init(final String path, String pathActions) { + if (pathActions != null && pathActions != "") { //$NON-NLS-1$ + if (path != null) { + if (path.equals("<>")) { //$NON-NLS-1$ + includeAll = true; + } else { + canonPath = AccessController + .doPrivileged(new PrivilegedAction() { + public String run() { + try { + return new File(path) + .getCanonicalPath(); + } catch (IOException e) { + return path; + } + } + }); + if (path.equals("*") || path.endsWith(File.separator + "*")) { //$NON-NLS-1$ //$NON-NLS-2$ + allDir = true; + } + if (path.equals("-") || path.endsWith(File.separator + "-")) { //$NON-NLS-1$ //$NON-NLS-2$ + allSubdir = true; + } + } + this.actions = toCanonicalActionString(pathActions); + } else { + throw new NullPointerException(Msg.getString("K006e")); //$NON-NLS-1$ + } + } else { + throw new IllegalArgumentException(Msg.getString("K006d")); //$NON-NLS-1$ + } + } + + /** + * Answer the string representing this permissions actions. It must be of + * the form "read,write,execute,delete", all lower case and in the correct + * order if there is more than one action. + * + * @param action + * the action name + * @return the string representing this permission's actions + */ + private String toCanonicalActionString(String action) { + actions = action.trim().toLowerCase(); + + // get the numerical representation of the action list + mask = getMask(actions); + + // convert the mask to a canonical action list. + int len = actionList.length; + // the test mask - shift the 1 to the leftmost position of the + // actionList + int highestBitMask = 1 << (len - 1); - // if a bit of mask is set, append the corresponding action to result + // if a bit of mask is set, append the corresponding action to result StringBuilder result = new StringBuilder(); - boolean addedItem = false; - for (int i = 0; i < len; i++) { - if ((highestBitMask & mask) != 0) { - if (addedItem) - result.append(","); //$NON-NLS-1$ - result.append(actionList[i]); - addedItem = true; - } - highestBitMask = highestBitMask >> 1; - } - return result.toString(); - } - - /** - * Answers the numerical representation of the argument. - * - * @param actionNames - * the action names - * @return the action mask - */ - private int getMask(String actionNames) { - int actionInt = 0, head = 0, tail = 0; - do { - tail = actionNames.indexOf(",", head); //$NON-NLS-1$ - String action = tail > 0 ? actionNames.substring(head, tail).trim() - : actionNames.substring(head).trim(); - if (action.equals("read")) //$NON-NLS-1$ - actionInt |= 8; - else if (action.equals("write")) //$NON-NLS-1$ - actionInt |= 4; - else if (action.equals("execute")) //$NON-NLS-1$ - actionInt |= 2; - else if (action.equals("delete")) //$NON-NLS-1$ - actionInt |= 1; - else - throw new java.lang.IllegalArgumentException( - org.apache.harmony.luni.util.Msg.getString("K006f", action)); //$NON-NLS-1$ - head = tail + 1; - } while (tail > 0); - return actionInt; - } - - /** - * Answers the actions associated with the receiver. - * - * @return the actions associated with the receiver. - */ - public String getActions() { - return actions; - } - - /** - * Check to see if this permission is equal to another. The two are equal if - * obj is a FilePermission, they have the same path, and they - * have the same actions. - * - * @param obj - * the object to check equality with. - * @return true if the two are equal, false - * otherwise. - */ - public boolean equals(Object obj) { - if (obj instanceof FilePermission) { - FilePermission fp = (FilePermission) obj; - if (fp.actions != actions) - if (fp.actions == null || !fp.actions.equals(actions)) - return false; - - /* Matching actions and both are <> ? */ - if (fp.includeAll || includeAll) - return fp.includeAll == includeAll; - return fp.canonPath.equals(canonPath); - } - return false; - } - - /** - * Indicates whether the argument permission is implied by the receiver. - * - * @param p - * java.security.Permission the permission to check. - * @return true if the argument permission is implied by the - * receiver, and false if it is not. - */ - public boolean implies(Permission p) { - int match = impliesMask(p); - return match != 0 && match == ((FilePermission) p).mask; - } - - /** - * Answers an int describing what masks are implied by a specific - * permission. - * - * @param p - * the permission - * @return the mask applied to the given permission - */ - int impliesMask(Permission p) { - if (!(p instanceof FilePermission)) - return 0; - FilePermission fp = (FilePermission) p; - int matchedMask = mask & fp.mask; - // Can't match any bits? - if (matchedMask == 0) - return 0; - - // Is this permission <> - if (includeAll) - return matchedMask; - - // We can't imply all files - if (fp.includeAll) - return 0; - - // Scan the length of p checking all match possibilities - // \- implies everything except \ - int thisLength = canonPath.length(); - if (allSubdir && thisLength == 2 - && !fp.canonPath.equals(File.separator)) - return matchedMask; - // need /- to imply /- - if (fp.allSubdir && !allSubdir) - return 0; - // need /- or /* to imply /* - if (fp.allDir && !allSubdir && !allDir) - return 0; - - boolean includeDir = false; - int pLength = fp.canonPath.length(); - // do not compare the * or - - if (allDir || allSubdir) - thisLength--; - if (fp.allDir || fp.allSubdir) - pLength--; - for (int i = 0; i < pLength; i++) { - char pChar = fp.canonPath.charAt(i); - // Is p longer than this permissions canonLength? - if (i >= thisLength) { - if (i == thisLength) { - // Is this permission include all? (must have matched up - // until this point). - if (allSubdir) - return matchedMask; - // Is this permission include a dir? Continue the check - // afterwards. - if (allDir) - includeDir = true; - } - // If not includeDir then is has to be a mismatch. - if (!includeDir) - return 0; - /** - * If we have * for this and find a separator it is invalid. IE: - * this is '/a/*' and p is '/a/b/c' we should fail on the - * separator after the b. Except for root, canonical paths do - * not end in a separator. - */ - if (pChar == File.separatorChar) - return 0; - } else { - // Are the characters matched? - if (canonPath.charAt(i) != pChar) - return 0; - } - } - // Must have matched upto this point or it's a valid file in an include - // all directory - if (pLength == thisLength) { - if (allSubdir) { - // /- implies /- or /* - return fp.allSubdir || fp.allDir ? matchedMask : 0; - } else { - return allDir == fp.allDir ? matchedMask : 0; - } - } - return includeDir ? matchedMask : 0; -} - - /** - * Answers a new PermissionCollection in which to place FilePermission - * Objects. - * - * @return A new PermissionCollection suitable for storing FilePermission - * objects. - */ - public java.security.PermissionCollection newPermissionCollection() { - return new FilePermissionCollection(); - } - - /** - * Answers an int representing the hash code value for this FilePermission. - * - * @return int the hash code value for this FilePermission. - */ - public int hashCode() { - return (canonPath == null ? getName().hashCode() : canonPath.hashCode()) - + mask; - } - - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - } - - private void readObject(ObjectInputStream stream) throws IOException, - ClassNotFoundException { - stream.defaultReadObject(); - init(getName(), actions); - } + boolean addedItem = false; + for (int i = 0; i < len; i++) { + if ((highestBitMask & mask) != 0) { + if (addedItem) { + result.append(","); //$NON-NLS-1$ + } + result.append(actionList[i]); + addedItem = true; + } + highestBitMask = highestBitMask >> 1; + } + return result.toString(); + } + + /** + * Answers the numerical representation of the argument. + * + * @param actionNames + * the action names + * @return the action mask + */ + private int getMask(String actionNames) { + int actionInt = 0, head = 0, tail = 0; + do { + tail = actionNames.indexOf(",", head); //$NON-NLS-1$ + String action = tail > 0 ? actionNames.substring(head, tail).trim() + : actionNames.substring(head).trim(); + if (action.equals("read")) { //$NON-NLS-1$ + actionInt |= 8; + } else if (action.equals("write")) { //$NON-NLS-1$ + actionInt |= 4; + } else if (action.equals("execute")) { //$NON-NLS-1$ + actionInt |= 2; + } else if (action.equals("delete")) { //$NON-NLS-1$ + actionInt |= 1; + } else { + throw new java.lang.IllegalArgumentException(Msg.getString( + "K006f", action)); //$NON-NLS-1$ + } + head = tail + 1; + } while (tail > 0); + return actionInt; + } + + /** + * Answers the actions associated with the receiver. + * + * @return the actions associated with the receiver. + */ + @Override + public String getActions() { + return actions; + } + + /** + * Check to see if this permission is equal to another. The two are equal if + * obj is a FilePermission, they have the same path, and they + * have the same actions. + * + * @param obj + * the object to check equality with. + * @return true if the two are equal, false + * otherwise. + */ + @Override + public boolean equals(Object obj) { + if (obj instanceof FilePermission) { + FilePermission fp = (FilePermission) obj; + if (fp.actions != actions) { + if (fp.actions == null || !fp.actions.equals(actions)) { + return false; + } + } + + /* Matching actions and both are <> ? */ + if (fp.includeAll || includeAll) { + return fp.includeAll == includeAll; + } + return fp.canonPath.equals(canonPath); + } + return false; + } + + /** + * Indicates whether the argument permission is implied by the receiver. + * + * @param p + * java.security.Permission the permission to check. + * @return true if the argument permission is implied by the + * receiver, and false if it is not. + */ + @Override + public boolean implies(Permission p) { + int match = impliesMask(p); + return match != 0 && match == ((FilePermission) p).mask; + } + + /** + * Answers an int describing what masks are implied by a specific + * permission. + * + * @param p + * the permission + * @return the mask applied to the given permission + */ + int impliesMask(Permission p) { + if (!(p instanceof FilePermission)) { + return 0; + } + FilePermission fp = (FilePermission) p; + int matchedMask = mask & fp.mask; + // Can't match any bits? + if (matchedMask == 0) { + return 0; + } + + // Is this permission <> + if (includeAll) { + return matchedMask; + } + + // We can't imply all files + if (fp.includeAll) { + return 0; + } + + // Scan the length of p checking all match possibilities + // \- implies everything except \ + int thisLength = canonPath.length(); + if (allSubdir && thisLength == 2 + && !fp.canonPath.equals(File.separator)) { + return matchedMask; + } + // need /- to imply /- + if (fp.allSubdir && !allSubdir) { + return 0; + } + // need /- or /* to imply /* + if (fp.allDir && !allSubdir && !allDir) { + return 0; + } + + boolean includeDir = false; + int pLength = fp.canonPath.length(); + // do not compare the * or - + if (allDir || allSubdir) { + thisLength--; + } + if (fp.allDir || fp.allSubdir) { + pLength--; + } + for (int i = 0; i < pLength; i++) { + char pChar = fp.canonPath.charAt(i); + // Is p longer than this permissions canonLength? + if (i >= thisLength) { + if (i == thisLength) { + // Is this permission include all? (must have matched up + // until this point). + if (allSubdir) { + return matchedMask; + } + // Is this permission include a dir? Continue the check + // afterwards. + if (allDir) { + includeDir = true; + } + } + // If not includeDir then is has to be a mismatch. + if (!includeDir) { + return 0; + } + /** + * If we have * for this and find a separator it is invalid. IE: + * this is '/a/*' and p is '/a/b/c' we should fail on the + * separator after the b. Except for root, canonical paths do + * not end in a separator. + */ + if (pChar == File.separatorChar) { + return 0; + } + } else { + // Are the characters matched? + if (canonPath.charAt(i) != pChar) { + return 0; + } + } + } + // Must have matched upto this point or it's a valid file in an include + // all directory + if (pLength == thisLength) { + if (allSubdir) { + // /- implies /- or /* + return fp.allSubdir || fp.allDir ? matchedMask : 0; + } else { + return allDir == fp.allDir ? matchedMask : 0; + } + } + return includeDir ? matchedMask : 0; + } + + /** + * Answers a new PermissionCollection in which to place FilePermission + * Objects. + * + * @return A new PermissionCollection suitable for storing FilePermission + * objects. + */ + @Override + public PermissionCollection newPermissionCollection() { + return new FilePermissionCollection(); + } + + /** + * Answers an int representing the hash code value for this FilePermission. + * + * @return int the hash code value for this FilePermission. + */ + @Override + public int hashCode() { + return (canonPath == null ? + getName().hashCode() : canonPath.hashCode()) + mask; + } + + private void writeObject(ObjectOutputStream stream) throws IOException { + stream.defaultWriteObject(); + } + + private void readObject(ObjectInputStream stream) throws IOException, + ClassNotFoundException { + stream.defaultReadObject(); + init(getName(), actions); + } }