Home | History | Annotate | Download | only in util
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package java.util;
     19 
     20 import java.io.IOException;
     21 import java.io.ObjectInputStream;
     22 import java.io.ObjectOutputStream;
     23 import java.io.ObjectStreamField;
     24 import java.security.BasicPermission;
     25 import java.security.Permission;
     26 import java.security.PermissionCollection;
     27 import org.apache.harmony.luni.util.Util;
     28 
     29 /**
     30  * {@code PropertyPermission} objects represent a permission to access system
     31  * properties.
     32  * <p>
     33  * A permission is one of the possible permission strings like "user.name" or
     34  * "java.version". It's also possible to use a wildcard to define the permission
     35  * to several properties at once. For example "user.*" will define the
     36  * permission for "user.home", "user.name", "user.dir", ... "*" defines the
     37  * permission for all available properties.
     38  * <p>
     39  * There are two possible permission action types: read and write. Possible
     40  * actions are "read", "write", or "read,write"/"write,read".
     41  */
     42 public final class PropertyPermission extends BasicPermission {
     43     private static final long serialVersionUID = 885438825399942851L;
     44 
     45     transient private boolean read, write;
     46 
     47     /**
     48      * Constructs a new instance of this class.
     49      *
     50      * @param name
     51      *            the (possibly wildcarded) name of the property.
     52      * @param actions
     53      *            the actions which are applicable to it. Possible actions are
     54      *            "read", "write", or "read,write"/"write,read". Anything else
     55      *            will result in an {@code IllegalArgumentException}.
     56      */
     57     public PropertyPermission(String name, String actions) {
     58         super(name);
     59         decodeActions(actions);
     60     }
     61 
     62     private void decodeActions(String actions) {
     63         StringTokenizer tokenizer = new StringTokenizer(Util.toASCIILowerCase(actions),
     64                 " \t\n\r,");
     65         while (tokenizer.hasMoreTokens()) {
     66             String token = tokenizer.nextToken();
     67             if (token.equals("read")) {
     68                 read = true;
     69             } else if (token.equals("write")) {
     70                 write = true;
     71             } else {
     72                 throw new IllegalArgumentException();
     73             }
     74         }
     75         if (!read && !write) {
     76             throw new IllegalArgumentException();
     77         }
     78     }
     79 
     80     /**
     81      * Compares the argument to the receiver, and returns true if they represent
     82      * the <em>same</em> object using a class specific comparison. In this
     83      * case, the receiver must be a {@code PropertyPermission} for the same
     84      * property as the argument, and must have the same actions.
     85      * If {@code o} is a permission that is not a {@code PropertyPermission},
     86      * this method may throw a {@code ClassCastException}.
     87      *
     88      * @param o
     89      *            the {@code Object} to compare with this {@code Object}.
     90      * @return {@code true} if the {@code Object} is the same as this {@code Object},
     91      *         {@code false} if it is different from this {@code Object}.
     92      * @see #hashCode
     93      */
     94     @Override
     95     public boolean equals(Object o) {
     96         if (super.equals(o)) {
     97             PropertyPermission pp = (PropertyPermission) o;
     98             return read == pp.read && write == pp.write;
     99         }
    100         return false;
    101     }
    102 
    103     /**
    104      * Returns the actions associated with the receiver. The result will be
    105      * either "read", "write", or "read,write".
    106      *
    107      * @return the actions associated with the receiver.
    108      */
    109     @Override
    110     public String getActions() {
    111         return read ? (write ? "read,write" : "read") : "write";
    112     }
    113 
    114     /**
    115      * Returns an integer hash code for the receiver. Any two objects which
    116      * return {@code true} when passed to {@code equals} must return the same
    117      * value for this method.
    118      *
    119      * @return the receiver's hash.
    120      * @see #equals
    121      */
    122     @Override
    123     public int hashCode() {
    124         return super.hashCode();
    125     }
    126 
    127     /**
    128      * Indicates whether the argument permission is implied by the receiver.
    129      *
    130      * @return boolean {@code true} if the argument permission is implied by the
    131      *         receiver, and {@code false} if it is not.
    132      * @param permission
    133      *            the permission to check.
    134      */
    135     @Override
    136     public boolean implies(Permission permission) {
    137         if (super.implies(permission)) {
    138             PropertyPermission pp = (PropertyPermission) permission;
    139             return (read || !pp.read) && (write || !pp.write);
    140         }
    141         return false;
    142     }
    143 
    144     /**
    145      * Returns a new {@code PermissionCollection} for holding permissions of this class.
    146      * Returns {@code null} if any {@code PermissionCollection} can be used.
    147      *
    148      * @return a new {@code PermissionCollection} or {@code null}.
    149      * @see java.security.PermissionCollection
    150      */
    151     @Override
    152     public PermissionCollection newPermissionCollection() {
    153         return new PropertyPermissionCollection();
    154     }
    155 
    156     private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
    157             "actions", String.class) };
    158 
    159     private void writeObject(ObjectOutputStream stream) throws IOException {
    160         ObjectOutputStream.PutField fields = stream.putFields();
    161         fields.put("actions", getActions());
    162         stream.writeFields();
    163     }
    164 
    165     private void readObject(ObjectInputStream stream) throws IOException,
    166             ClassNotFoundException {
    167         ObjectInputStream.GetField fields = stream.readFields();
    168         String actions = (String) fields.get("actions", "");
    169         decodeActions(actions);
    170     }
    171 }
    172