| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package java.util; |
| |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.ObjectStreamField; |
| import java.security.BasicPermission; |
| import java.security.Permission; |
| import java.security.PermissionCollection; |
| |
| import org.apache.harmony.luni.util.Util; |
| |
| /** |
| * {@code PropertyPermission} objects represent a permission to access system |
| * properties. |
| * <p> |
| * A permission is one of the possible permission strings like "user.name" or |
| * "java.version". It's also possible to use a wildcard to define the permission |
| * to several properties at once. For example "user.*" will define the |
| * permission for "user.home", "user.name", "user.dir", ... "*" defines the |
| * permission for all available properties. |
| * <p> |
| * There are two possible permission action types: read and write. Possible |
| * actions are "read", "write", or "read,write"/"write,read". |
| * |
| * @since Android 1.0 |
| */ |
| public final class PropertyPermission extends BasicPermission { |
| private static final long serialVersionUID = 885438825399942851L; |
| |
| transient private boolean read, write; |
| |
| /** |
| * Constructs a new instance of this class. |
| * |
| * @param name |
| * the (possibly wildcarded) name of the property. |
| * @param actions |
| * the actions which are applicable to it. Possible actions are |
| * "read", "write", or "read,write"/"write,read". Anything else |
| * will result in an {@code IllegalArgumentException}. |
| * @since Android 1.0 |
| */ |
| public PropertyPermission(String name, String actions) { |
| super(name); |
| decodeActions(actions); |
| } |
| |
| private void decodeActions(String actions) { |
| StringTokenizer tokenizer = new StringTokenizer(Util.toASCIILowerCase(actions), |
| " \t\n\r,"); //$NON-NLS-1$ |
| while (tokenizer.hasMoreTokens()) { |
| String token = tokenizer.nextToken(); |
| if (token.equals("read")) { //$NON-NLS-1$ |
| read = true; |
| } else if (token.equals("write")) { //$NON-NLS-1$ |
| write = true; |
| } else { |
| throw new IllegalArgumentException(); |
| } |
| } |
| if (!read && !write) { |
| throw new IllegalArgumentException(); |
| } |
| } |
| |
| /** |
| * Compares the argument to the receiver, and returns true if they represent |
| * the <em>same</em> object using a class specific comparison. In this |
| * case, the receiver must be a {@code PropertyPermission} for the same |
| * property as the argument, and must have the same actions. |
| * If {@code o} is a permission that is not a {@code PropertyPermission}, |
| * this method may throw a {@code ClassCastException}. |
| * |
| * @param o |
| * the {@code Object} to compare with this {@code Object}. |
| * @return {@code true} if the {@code Object} is the same as this {@code Object}, |
| * {@code false} if it is different from this {@code Object}. |
| * @see #hashCode |
| * @since Android 1.0 |
| */ |
| @Override |
| public boolean equals(Object o) { |
| if (super.equals(o)) { |
| PropertyPermission pp = (PropertyPermission) o; |
| return read == pp.read && write == pp.write; |
| } |
| return false; |
| } |
| |
| /** |
| * Returns the actions associated with the receiver. The result will be |
| * either "read", "write", or "read,write". |
| * |
| * @return the actions associated with the receiver. |
| * @since Android 1.0 |
| */ |
| @Override |
| public String getActions() { |
| return read ? (write ? "read,write" : "read") : "write"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ |
| } |
| |
| /** |
| * Returns an integer hash code for the receiver. Any two objects which |
| * return {@code true} when passed to {@code equals} must return the same |
| * value for this method. |
| * |
| * @return the receiver's hash. |
| * @see #equals |
| * @since Android 1.0 |
| */ |
| @Override |
| public int hashCode() { |
| return super.hashCode(); |
| } |
| |
| /** |
| * Indicates whether the argument permission is implied by the receiver. |
| * |
| * @return boolean {@code true} if the argument permission is implied by the |
| * receiver, and {@code false} if it is not. |
| * @param permission |
| * the permission to check. |
| * @since Android 1.0 |
| */ |
| @Override |
| public boolean implies(Permission permission) { |
| if (super.implies(permission)) { |
| PropertyPermission pp = (PropertyPermission) permission; |
| return (read || !pp.read) && (write || !pp.write); |
| } |
| return false; |
| } |
| |
| /** |
| * Returns a new {@code PermissionCollection} for holding permissions of this class. |
| * Returns {@code null} if any {@code PermissionCollection} can be used. |
| * |
| * @return a new {@code PermissionCollection} or {@code null}. |
| * @see java.security.PermissionCollection |
| * @since Android 1.0 |
| */ |
| @Override |
| public PermissionCollection newPermissionCollection() { |
| return new PropertyPermissionCollection(); |
| } |
| |
| private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField( |
| "actions", String.class) }; //$NON-NLS-1$ |
| |
| private void writeObject(ObjectOutputStream stream) throws IOException { |
| ObjectOutputStream.PutField fields = stream.putFields(); |
| fields.put("actions", getActions()); //$NON-NLS-1$ |
| stream.writeFields(); |
| } |
| |
| private void readObject(ObjectInputStream stream) throws IOException, |
| ClassNotFoundException { |
| ObjectInputStream.GetField fields = stream.readFields(); |
| String actions = (String) fields.get("actions", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
| decodeActions(actions); |
| } |
| } |