FileDocCategorySizeDatePackage
UnresolvedPermission.javaAPI DocAndroid 1.5 API15346Wed May 06 22:41:06 BST 2009java.security

UnresolvedPermission

public final class UnresolvedPermission extends Permission implements Serializable
An {@code UnresolvedPermission} represents a {@code Permission} whose type should be resolved lazy and not during initialization time of the {@code Policy}. {@code UnresolvedPermission}s contain all information to be replaced by a concrete typed {@code Permission} right before the access checks are performed.
since
Android 1.0

Fields Summary
private static final long
serialVersionUID
private static final ObjectStreamField[]
serialPersistentFields
private transient String
targetName
private transient String
targetActions
private transient Certificate[]
targetCerts
private transient int
hash
Constructors Summary
public UnresolvedPermission(String type, String name, String actions, Certificate[] certs)
Constructs a new instance of {@code UnresolvedPermission}. The supplied parameters are used when this instance is resolved to the concrete {@code Permission}.

param
type the fully qualified class name of the permission this class is resolved to.
param
name the name of the permission this class is resolved to, maybe {@code null}.
param
actions the actions of the permission this class is resolved to, maybe {@code null}.
param
certs the certificates of the permission this class is resolved to, maybe {@code null}.
throws
NullPointerException if type is {@code null}.
since
Android 1.0


                                                                                                                                                                                                          
          
                                  
        super(type);
        checkType(type);
        targetName = name;
        targetActions = actions;
        if (certs != null && certs.length != 0) {
            //TODO filter non-signer certificates ???
            List tmp = new ArrayList();
            for (int i = 0; i < certs.length; i++) {
                if (certs[i] != null) {
                    tmp.add(certs[i]);
                }
            }
            if (tmp.size() != 0) {
                targetCerts = (Certificate[])tmp.toArray(
                                new Certificate[tmp.size()]);
            }
        }
        hash = 0;
    
Methods Summary
private final voidcheckType(java.lang.String type)

        if (type == null) {
            throw new NullPointerException(Messages.getString("security.2F")); //$NON-NLS-1$
        }

        // type is the class name of the Permission class.
        // Empty string is inappropriate for class name.
        // But this check is commented out for compatibility with RI.
        // see JIRA issue HARMONY-733
        // if (type.length() == 0) {
        //     throw new IllegalArgumentException("type cannot be empty");
        // }
    
public booleanequals(java.lang.Object obj)
Compares the specified object with this {@code UnresolvedPermission} for equality and returns {@code true} if the specified object is equal, {@code false} otherwise. To be equal, the specified object needs to be an instance of {@code UnresolvedPermission}, the two {@code UnresolvedPermission}s must refer to the same type and must have the same name, the same actions and certificates.

param
obj object to be compared for equality with this {@code UnresolvedPermission}.
return
{@code true} if the specified object is equal to this {@code UnresolvedPermission}, otherwise {@code false}.
since
Android 1.0

        if (obj == this) {
            return true;
        }
        if (obj instanceof UnresolvedPermission) {
            UnresolvedPermission that = (UnresolvedPermission)obj;
            if (getName().equals(that.getName())
                && (targetName == null ? that.targetName == null 
                    : targetName.equals(that.targetName))
                && (targetActions == null ? that.targetActions == null
                    : targetActions.equals(that.targetActions))
                && (PolicyUtils.matchSubset(targetCerts, that.targetCerts) 
                    && PolicyUtils.matchSubset(that.targetCerts, targetCerts))) {
                return true;
            }
        }
        return false;
    
public java.lang.StringgetActions()
Returns an empty string since there are no actions allowed for {@code UnresolvedPermission}. The actions, specified in the constructor, are used when the concrete permission is resolved and created.

return
an empty string, indicating that there are no actions.
since
Android 1.0

        return ""; //$NON-NLS-1$
    
public java.lang.StringgetUnresolvedActions()
Returns the actions of the permission this {@code UnresolvedPermission} is resolved to.

return
the actions of the permission this {@code UnresolvedPermission} is resolved to.
since
Android 1.0

        return targetActions;
    
public java.security.cert.Certificate[]getUnresolvedCerts()
Returns the certificates of the permission this {@code UnresolvedPermission} is resolved to.

return
the certificates of the permission this {@code UnresolvedPermission} is resolved to.
since
Android 1.0

        if (targetCerts != null) {
            Certificate[] certs = new Certificate[targetCerts.length];
            System.arraycopy(targetCerts, 0, certs, 0, certs.length);
            return certs;
        }
        return null;
    
public java.lang.StringgetUnresolvedName()
Returns the name of the permission this {@code UnresolvedPermission} is resolved to.

return
the name of the permission this {@code UnresolvedPermission} is resolved to.
since
Android 1.0

        return targetName;
    
public java.lang.StringgetUnresolvedType()
Returns the fully qualified class name of the permission this {@code UnresolvedPermission} is resolved to.

return
the fully qualified class name of the permission this {@code UnresolvedPermission} is resolved to.
since
Android 1.0

        return super.getName();
    
public inthashCode()
Returns the hash code value for this {@code UnresolvedPermission}. Returns the same hash code for {@code UnresolvedPermission}s that are equal to each other as required by the general contract of {@link Object#hashCode}.

return
the hash code value for this {@code UnresolvedPermission}.
see
Object#equals(Object)
see
UnresolvedPermission#equals(Object)
since
Android 1.0

        if (hash == 0) {
            hash = getName().hashCode();
            if (targetName != null) {
                hash ^= targetName.hashCode();
            }
            if (targetActions != null) {
                hash ^= targetActions.hashCode();
            }
        }
        return hash;
    
public booleanimplies(java.security.Permission permission)
Indicates whether the specified permission is implied by this {@code UnresolvedPermission}. {@code UnresolvedPermission} objects imply nothing since nothing is known about them yet.

Before actual implication checking, this method tries to resolve UnresolvedPermissions (if any) against the passed instance. Successfully resolved permissions (if any) are taken into account during further processing.

param
permission the permission to check.
return
always {@code false}
since
Android 1.0

        return false;
    
public java.security.PermissionCollectionnewPermissionCollection()
Returns a new {@code PermissionCollection} for holding {@code UnresolvedPermission} objects.

return
a new PermissionCollection for holding {@code UnresolvedPermission} objects.
since
Android 1.0

        return new UnresolvedPermissionCollection();
    
private voidreadObject(java.io.ObjectInputStream in)

com.intel.drl.spec_ref
Reads the object from stream and checks target type for validity.

        checkType(getUnresolvedType());
        ObjectInputStream.GetField fields = in.readFields();
        if (!getUnresolvedType().equals(fields.get("type", null))) { //$NON-NLS-1$
            throw new InvalidObjectException(Messages.getString("security.31")); //$NON-NLS-1$
        }
        targetName = (String)fields.get("name", null); //$NON-NLS-1$
        targetActions = (String)fields.get("actions", null); //$NON-NLS-1$
        int certNumber = in.readInt();
        if (certNumber != 0) {
            targetCerts = new Certificate[certNumber];
            for (int i = 0; i < certNumber; i++) {
                try {
                    String type = in.readUTF();
                    int length = in.readInt();
                    byte[] enc = new byte[length];
                    in.readFully(enc, 0, length);
                    targetCerts[i] = CertificateFactory.getInstance(type)
                        .generateCertificate(new ByteArrayInputStream(enc));
                } catch (CertificateException cee) {
                    throw ((IOException)new IOException(
                        Messages.getString("security.32")).initCause(cee)); //$NON-NLS-1$
                }
            }
        }
    
java.security.Permissionresolve(java.lang.Class targetType)
Tries to resolve this permission into the specified class.

It is assumed that the class has a proper name (as returned by {@code getName()} of this unresolved permission), so no check is performed to verify this. However, the class must have all required certificates (as per {@code getUnresolvedCerts()}) among the passed collection of signers. If it does, a zero, one, and/or two-argument constructor is tried to instantiate a new permission, which is then returned.

If an appropriate constructor is not available or the class is improperly signed, {@code null} is returned.

param
targetType - a target class instance, must not be {@code null}
param
signers - actual signers of the targetType
return
resolved permission or null

        // check signers at first
        if (PolicyUtils.matchSubset(targetCerts, targetType.getSigners())) {
            try {
                return PolicyUtils.instantiatePermission(targetType,
                                                         targetName,
                                                         targetActions);
            } catch (Exception ignore) {
                //TODO log warning?
            }
        }
        return null;
    
public java.lang.StringtoString()
Returns a string containing a concise, human-readable description of this {@code UnresolvedPermission} including its target name and its target actions.

return
a printable representation for this {@code UnresolvedPermission}.
since
Android 1.0

        return "(unresolved " + getName() + " " + targetName + " " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            + targetActions + ")"; //$NON-NLS-1$
    
private voidwriteObject(java.io.ObjectOutputStream out)

com.intel.drl.spec_ref
Outputs {@code type},{@code name},{@code actions} fields via default mechanism; next manually writes certificates in the following format:
  1. int : number of certs or zero
  2. each cert in the following format
    1. String : certificate type
    2. int : length in bytes of certificate
    3. byte[] : certificate encoding
see
Java Spec

        ObjectOutputStream.PutField fields = out.putFields();
        fields.put("type", getUnresolvedType()); //$NON-NLS-1$
        fields.put("name", getUnresolvedName()); //$NON-NLS-1$
        fields.put("actions", getUnresolvedActions()); //$NON-NLS-1$
        out.writeFields();
        if (targetCerts == null) {
            out.writeInt(0);
        } else {
            out.writeInt(targetCerts.length);
            for (int i = 0; i < targetCerts.length; i++) {
                try {
                    byte[] enc = targetCerts[i].getEncoded();
                    out.writeUTF(targetCerts[i].getType());
                    out.writeInt(enc.length);
                    out.write(enc);
                } catch (CertificateEncodingException cee) {
                    throw ((IOException)new NotSerializableException(
                        Messages.getString("security.30",  //$NON-NLS-1$
                        targetCerts[i])).initCause(cee));
                }
            }
        }