Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / security / DatabasePermission.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/security/DatabasePermission.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/security/DatabasePermission.java
new file mode 100644 (file)
index 0000000..724eebf
--- /dev/null
@@ -0,0 +1,452 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.security.DatabasePermission\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.security;\r
+\r
+import java.security.Permission;\r
+\r
+import java.util.Set;\r
+import java.util.HashSet;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.ObjectInputStream;\r
+import java.io.ObjectOutputStream;\r
+\r
+\r
+/**\r
+ * This class represents access to database-scoped privileges.\r
+ *\r
+ * An example of database-scoped privileges is the permission to create\r
+ * a database under a specified directory path.\r
+ * <p>\r
+ * A DatabasePermission is defined by two string attributes, similar to\r
+ * a java.io.FilePermission:\r
+ * <ul>\r
+ * <li> <i>URL</i> - a location description of or for a Derby database\r
+ * <li> <i>Actions</i> - a list of granted administrative actions\r
+ * </ul>\r
+ * The database location URL may contain certain wildcard characters.\r
+ * The currently only supported database action is <i>create</i>.\r
+ *\r
+ * @see DatabasePermission#DatabasePermission(String,String)\r
+ * @see SystemPermission\r
+ * @see java.io.FilePermission\r
+ */\r
+public class DatabasePermission extends Permission {\r
+\r
+    /**\r
+     * The URL protocol scheme specifying a directory location.\r
+     */\r
+    static public final String URL_PROTOCOL_DIRECTORY = "directory:";\r
+\r
+    /**\r
+     * The URL file path separator character.\r
+     */\r
+    static public final char URL_PATH_SEPARATOR_CHAR = '/';\r
+\r
+    /**\r
+     * The relative path character.\r
+     */\r
+    static public final char URL_PATH_RELATIVE_CHAR = '.';\r
+\r
+    /**\r
+     * The wildcard character specifying arbitrarily named databases\r
+     * under a directory path.\r
+     */\r
+    static public final char URL_PATH_WILDCARD_CHAR = '*';\r
+\r
+    /**\r
+     * The wildcard character specifying arbitrarily named databases\r
+     * anywhere under a path and its subdirectories.\r
+     */\r
+    static public final char URL_PATH_RECURSIVE_CHAR = '-';\r
+\r
+    // derived path type constants\r
+    static public final String URL_PATH_SEPARATOR_STRING\r
+        = String.valueOf(URL_PATH_SEPARATOR_CHAR);\r
+    static public final String URL_PATH_RELATIVE_STRING\r
+        = String.valueOf(URL_PATH_RELATIVE_CHAR);\r
+    static public final String URL_PATH_RELATIVE_PREFIX\r
+        = (URL_PATH_RELATIVE_STRING + URL_PATH_SEPARATOR_CHAR);\r
+    static public final String URL_PATH_WILDCARD_STRING\r
+        = String.valueOf(URL_PATH_WILDCARD_CHAR);\r
+    static public final String URL_PATH_WILDCARD_SUFFIX\r
+        = (URL_PATH_SEPARATOR_STRING + URL_PATH_WILDCARD_CHAR);\r
+    static public final String URL_PATH_RECURSIVE_STRING\r
+        = String.valueOf(URL_PATH_RECURSIVE_CHAR);\r
+    static public final String URL_PATH_RECURSIVE_SUFFIX\r
+        = (URL_PATH_SEPARATOR_STRING + URL_PATH_RECURSIVE_CHAR);\r
+\r
+    /**\r
+     * The create database permission.\r
+     */\r
+    static public final String CREATE = "create";\r
+\r
+    /**\r
+     * The legal database permission action names.\r
+     */\r
+    static protected final Set LEGAL_ACTIONS = new HashSet();\r
+    static {\r
+        // when adding new actions, check method: implies(Permission)\r
+        LEGAL_ACTIONS.add(CREATE);\r
+    };\r
+\r
+    /**\r
+     * The original location URL passed to constructor.\r
+     */\r
+    private final String url;\r
+\r
+    /**\r
+     * This permission's canonical directory path.\r
+     *\r
+     * The path consists of a canonicalized form of the user-specified URL,\r
+     * stripped off the protocol specification and any recursive/wildcard\r
+     * characters.  The canonical path is used when testing permissions\r
+     * with implies(), where real directory locations, not just notational\r
+     * differences, ought to be compared.  Analog to java.io.FilePermission,\r
+     * the canonical path is also used by equals() and hashCode() to support\r
+     * hashing and mapping of permissions by their real directory locations.\r
+     *\r
+     * Because canonical file paths are platform dependent, this field\r
+     * must not be serialized (hence transient) but be recomputed from\r
+     * the original URL upon deserialization.\r
+     */\r
+    private transient String path;\r
+\r
+    /**\r
+     * The parent directory of this permission's canonical directory path,\r
+     * or null if this permission's path does not name a parent directory.\r
+     *\r
+     * Because canonical file paths are platform dependent, this field\r
+     * must not be serialized (hence transient) but be recomputed from\r
+     * the original URL upon deserialization.\r
+     */\r
+    private transient String parentPath;\r
+\r
+    /**\r
+     * Indicates whether the path denotes a recursive, wildcard, or single\r
+     * location.\r
+     *\r
+     * If the path denotes a recursive or wildcard location, this field's\r
+     * value is URL_PATH_RECURSIVE_CHAR or URL_PATH_WILDCARD_CHAR,\r
+     * respectively; otherwise, it's URL_PATH_SEPARATOR_CHAR denoting a\r
+     * single location.\r
+     */\r
+    private char pathType;\r
+\r
+    /**\r
+     * Creates a new DatabasePermission with the specified URL and actions.\r
+     * <P>\r
+     * <i>actions</i> contains a comma-separated list of the desired actions\r
+     * granted on a database. Currently, the only supported action is\r
+     * <code>create</code>.\r
+     * <P>\r
+     * <i>URL</i> denotes a database location URL, which, at this time, must\r
+     * start with <code>directory:</code> followed by a directory pathname.\r
+     * Note that in a URL, the separator character is always "/" rather than\r
+     * the file separator of the operating-system.  The directory path may\r
+     * be absolute or relative, in which case it is prefixed with the current\r
+     * user directory. In addition, similar to java.io.FilePermission, the\r
+     * directory pathname may end with a wildcard character to allow for\r
+     * arbitrarily named databases under a path:\r
+     * <ul>\r
+     * <li> "directory:location" - refers to a database called\r
+     *      <i>location</i>,\r
+     * <li> "directory:location/*" - refers to any database in the\r
+     *      directory <i>location</i>,\r
+     * <li> "directory:location/-" - refers to any database anywhere under\r
+     *      <i>location</i> or its subdirectories.\r
+     * <li> "directory:*" - refers to any database in the user's current\r
+     *      working directory.\r
+     * <li> "directory:-" - refers to any database anywhere under the\r
+     *      user's current working directory or its subdirectories.\r
+     * </ul>\r
+     * Note that in contrast to FilePermission, there is no reasonable use\r
+     * for a special pathname "<<ALL FILES>>" matching all locations.\r
+     *\r
+     * @param url the database URL\r
+     * @param actions the action string\r
+     * @throws NullPointerException if an argument is null\r
+     * @throws IllegalArgumentException if an argument is not legal\r
+     * @throws IOException if the location URL cannot be canonicalized\r
+     * @see Permission#Permission(String)\r
+     * @see java.io.FilePermission#FilePermission(String,String)\r
+     */\r
+    public DatabasePermission(String url, String actions)\r
+        throws IOException {\r
+        super(url);\r
+        initActions(actions);\r
+        initLocation(url);\r
+\r
+        // store original URL for reconstructing path at deserialization\r
+        this.url = url;\r
+    }\r
+\r
+    /**\r
+     * Parses the list of database actions.\r
+     *\r
+     * @param actions the comma-separated action list\r
+     * @throws NullPointerException if actions is null\r
+     * @throws IllegalArgumentException if not a list of legal actions\r
+     */\r
+    protected void initActions(String actions) {\r
+        // note that exception messages on the action list aren't localized,\r
+        // as is the general rule with runtime exceptions indicating\r
+        // internal coding errors\r
+\r
+        // analog to java.security.BasicPermission, we check that actions\r
+        // is not null nor empty\r
+       if (actions == null) {\r
+           throw new NullPointerException("actions can't be null");\r
+        }\r
+       if (actions.length() == 0) {\r
+           throw new IllegalArgumentException("actions can't be empty");\r
+       }\r
+\r
+        // splitting the comma-separated list into the individual actions\r
+        // may throw a java.util.regex.PatternSyntaxException, which is a\r
+        // java.lang.IllegalArgumentException, hence directly applicable\r
+        final String[] s = actions.split(",");\r
+\r
+        // check for any illegal actions\r
+        for (int i = 0; i < s.length; i++) {\r
+            final String action = s[i].trim();\r
+            if (!LEGAL_ACTIONS.contains(action)) {\r
+                // report illegal action\r
+                final String msg = "Illegal action '" + action + "'";\r
+                //System.out.println("DatabasePermission: " + msg);\r
+                throw new IllegalArgumentException(msg);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Parses the database location URL.\r
+     *\r
+     * @param url the database URL\r
+     * @throws NullPointerException if the URL is null\r
+     * @throws IllegalArgumentException if the URL is not well-formed\r
+     * @throws IOException if the location URL cannot be canonicalized\r
+     */\r
+    protected void initLocation(String url)\r
+        throws IOException {\r
+        // note that exception messages on the URL aren't localized,\r
+        // as is the general rule with runtime exceptions indicating\r
+        // internal coding errors\r
+\r
+        // analog to java.security.BasicPermission, we check that URL\r
+        // is not null nor empty\r
+       if (url == null) {\r
+           throw new NullPointerException("URL can't be null");\r
+        }\r
+       if (url.length() == 0) {\r
+           throw new IllegalArgumentException("URL can't be empty");\r
+       }\r
+\r
+        // check URL's protocol scheme and initialize path\r
+        if (!url.startsWith(URL_PROTOCOL_DIRECTORY)) {\r
+            final String msg = "Unsupported protocol in URL '" + url + "'";\r
+            //System.out.println("DatabasePermission: " + msg);\r
+            throw new IllegalArgumentException(msg);\r
+        }\r
+        String p = url.substring(URL_PROTOCOL_DIRECTORY.length());\r
+\r
+        // check path for relative/recursive/wildcard specifications,\r
+        // split path into real pathname and the path type\r
+        if (p.equals(URL_PATH_RECURSIVE_STRING)) {\r
+            // relative & recursive:  "-" --> '-', "./"\r
+            pathType = URL_PATH_RECURSIVE_CHAR;\r
+            p = URL_PATH_RELATIVE_PREFIX;\r
+        } else if (p.equals(URL_PATH_WILDCARD_STRING)) {\r
+            // relative & wildcard:   "*" --> '*', "./"\r
+            pathType = URL_PATH_WILDCARD_CHAR;\r
+            p = URL_PATH_RELATIVE_PREFIX;\r
+        } else if (p.endsWith(URL_PATH_RECURSIVE_SUFFIX)) {\r
+            // absolute & recursive:  "<path>/-" --> '-', "<path>/"\r
+            pathType = URL_PATH_RECURSIVE_CHAR;\r
+            p = p.substring(0, p.length() - 1);\r
+        } else if (p.endsWith(URL_PATH_WILDCARD_SUFFIX)) {\r
+            // absolute & wildcard:   "<path>/*" --> '*', "<path>/"\r
+            pathType = URL_PATH_WILDCARD_CHAR;\r
+            p = p.substring(0, p.length() - 1);\r
+        } else {\r
+            // absolute | relative:   "<path>" --> '/', "<path>"\r
+            pathType = URL_PATH_SEPARATOR_CHAR;\r
+            // p = p;\r
+        }\r
+\r
+        // resolve against user's working directory if relative pathname\r
+        if (p.startsWith(URL_PATH_RELATIVE_PREFIX)) {\r
+            final String cwd = System.getProperty("user.dir");\r
+            // concatenated path "<cwd>/./<path>" will be canonicalized\r
+            p = cwd + URL_PATH_SEPARATOR_STRING + p;\r
+        }\r
+\r
+        // store canonicalized path as required for implies(Permission);\r
+        // may throw IOException \r
+        final File f = (new File(p)).getCanonicalFile();\r
+        this.path = f.getPath();\r
+\r
+        // store canonicalized path of parent file as required for\r
+        // implies(Permission); may throw IOException; note that\r
+        // the path already denotes parent directory if of wildcard type:\r
+        // for example, the parent of "/a/-" or "/a/*" is "/a"\r
+        this.parentPath = ((pathType != URL_PATH_SEPARATOR_CHAR)\r
+                           ? path : f.getParent());\r
+\r
+        //assert (pathType == URL_PATH_SEPARATOR_CHAR\r
+        //        || pathType == URL_PATH_WILDCARD_CHAR\r
+        //        || pathType == URL_PATH_RECURSIVE_CHAR);\r
+        //assert (path != null);\r
+    }\r
+\r
+    /**\r
+     * Checks if this DatabasePermission implies a specified permission.\r
+     * <P>\r
+     * This method returns true if:<p>\r
+     * <ul>\r
+     * <li> <i>p</i> is an instanceof DatabasePermission and<p>\r
+     * <li> <i>p</i>'s directory pathname is implied by this object's\r
+     *      pathname. For example, "/tmp/*" implies "/tmp/foo", since\r
+     *      "/tmp/*" encompasses the "/tmp" directory and all files in that\r
+     *      directory, including the one named "foo".\r
+     * </ul>\r
+     * @param p the permission to check against\r
+     * @return true if the specified permission is implied by this object,\r
+     * false if not\r
+     * @see Permission#implies(Permission)\r
+     */\r
+    public boolean implies(Permission p) {\r
+        //System.out.println("this = " + this);\r
+        //System.out.println("that = " + p);\r
+\r
+        // can only imply other DatabasePermissions\r
+        if (!(p instanceof DatabasePermission)) {\r
+            return false;\r
+        }\r
+        final DatabasePermission that = (DatabasePermission)p;\r
+\r
+        // a recursive permission implies any other if a path prefix\r
+        if (this.pathType == URL_PATH_RECURSIVE_CHAR) {\r
+            return (that.parentPath != null\r
+                    && that.parentPath.startsWith(this.path));\r
+        }\r
+        //assert (this.pathType != URL_PATH_RECURSIVE_CHAR);\r
+\r
+        // a non-recursive permission cannot imply a recursive one\r
+        if (that.pathType == URL_PATH_RECURSIVE_CHAR) {\r
+            return false;\r
+        }\r
+        //assert (that.pathType != URL_PATH_RECURSIVE_CHAR);\r
+\r
+        //System.out.println("");\r
+        \r
+        // a wildcard permission implies another if a parent directory\r
+        if (this.pathType == URL_PATH_WILDCARD_CHAR) {\r
+            return this.path.equals(that.parentPath);\r
+        }\r
+        //assert (this.pathType != URL_PATH_WILDCARD_CHAR);\r
+\r
+        // a non-wildcard permission cannot imply a wildcard one\r
+        if (that.pathType == URL_PATH_WILDCARD_CHAR) {\r
+            return false;\r
+        }\r
+        //assert (that.pathType != URL_PATH_WILDCARD_CHAR);\r
+\r
+        // non-recursive, non-wildcard permissions imply when paths are equal\r
+        //assert (this.pathType == URL_PATH_SEPARATOR_CHAR);\r
+        //assert (that.pathType == URL_PATH_SEPARATOR_CHAR);\r
+        return this.path.equals(that.path);\r
+    }\r
+\r
+    /**\r
+     * Checks two DatabasePermission objects for equality.\r
+     * <P>\r
+     * Checks that <i>obj</i> is a DatabasePermission and has the same\r
+     * canonizalized URL and actions as this object.\r
+     * <P>\r
+     * @param obj the object we are testing for equality with this object\r
+     * @return true if obj is a DatabasePermission, and has the same URL and\r
+     * actions as this DatabasePermission object, false if not\r
+     *\r
+     * @see Permission#equals(Object)\r
+     */\r
+    public boolean equals(Object obj) {\r
+        if (obj == this) {\r
+            return true;\r
+        }\r
+\r
+        if (!(obj instanceof DatabasePermission)) {\r
+            return false;\r
+        }\r
+        final DatabasePermission that = (DatabasePermission)obj;\r
+\r
+        // compare canonicalized URLs\r
+        return (path.equals(that.path) && pathType == that.pathType);\r
+    }\r
+\r
+    /**\r
+     * Returns the hash code value for this object.\r
+     *\r
+     * @return a hash code value for this object\r
+     * @see Permission#hashCode()\r
+     */\r
+    public int hashCode() {\r
+        // hash canonicalized URL\r
+        return (path.hashCode() ^ pathType);\r
+    }\r
+\r
+    /**\r
+     * Returns the "canonical string representation" of the actions.\r
+     *\r
+     * @return the canonical string representation of the actions\r
+     * @see Permission#getActions()\r
+     */\r
+    public String getActions() {\r
+        // currently, the only supported action\r
+        return CREATE;\r
+    }\r
+\r
+\r
+    /**\r
+     * Called upon Serialization for saving the state of this\r
+     * DatabasePermission to a stream.\r
+     */\r
+    private void writeObject(ObjectOutputStream s)\r
+        throws IOException {\r
+        // write the non-static and non-transient fields to the stream\r
+        s.defaultWriteObject();\r
+    }\r
+\r
+    /**\r
+     * Called upon Deserialization for restoring the state of this\r
+     * DatabasePermission from a stream.\r
+     */\r
+    private void readObject(ObjectInputStream s)\r
+         throws IOException, ClassNotFoundException\r
+    {\r
+        // read the non-static and non-transient fields from the stream\r
+        s.defaultReadObject();\r
+        // restore the platform-dependent path from the original URL\r
+        initLocation(url);\r
+    }\r
+}\r