/*
 *  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);
    }
}
