FileDocCategorySizeDatePackage
Provider.javaAPI DocAndroid 1.5 API44485Wed May 06 22:41:06 BST 2009java.security

Provider

public abstract class Provider extends Properties
{@code Provider} is the abstract superclass for all security providers in the Java security infrastructure.
since
Android 1.0

Fields Summary
private static final long
serialVersionUID
private String
name
private double
version
private transient String
versionString
private String
info
private transient int
providerNumber
private transient org.apache.harmony.luni.util.TwoKeyHashMap
serviceTable
private transient org.apache.harmony.luni.util.TwoKeyHashMap
aliasTable
private transient org.apache.harmony.luni.util.TwoKeyHashMap
propertyServiceTable
private transient org.apache.harmony.luni.util.TwoKeyHashMap
propertyAliasTable
private transient Properties
changedProperties
private transient Service
returnedService
private transient String
lastAlgorithm
private transient String
lastServiceName
private transient Set
lastServicesSet
private transient String
lastType
private transient Service
lastServicesByType
Constructors Summary
protected Provider(String name, double version, String info)
Constructs a new instance of {@code Provider} with its name, version and description.

param
name the name of the provider.
param
version the version of the provider.
param
info a description of the provider.
since
Android 1.0


                                                                                
           
        this.name = name;
        this.version = version;
        this.info = info;
        versionString = String.valueOf(version);
        putProviderInfo();
    
Methods Summary
private booleancheckAttribute(java.lang.String servAlg, java.lang.String attribute, java.lang.String val)

        
        String attributeValue = getPropertyIgnoreCase(servAlg + ' " + attribute);
        if (attributeValue != null) {
            if (attribute.equalsIgnoreCase("KeySize")) { //$NON-NLS-1$
                // BEGIN android-changed
                if (Integer.parseInt(attributeValue) >= Integer.parseInt(val)) {
                    return true;
                }
                // END android-changed
            } else { // other attributes
                if (attributeValue.equalsIgnoreCase(val)) {
                    return true;
                }
            }
        }
        return false;
    
public synchronized voidclear()
Clears all properties used to look up services implemented by this {@code Provider}.

If a {@code SecurityManager} is installed, code calling this method needs the {@code SecurityPermission} {@code clearProviderProperties.NAME} (where NAME is the provider name) to be granted, otherwise a {@code SecurityException} will be thrown.

throws
SecurityException if a {@code SecurityManager} is installed and the caller does not have permission to invoke this method.
since
Android 1.0

        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkSecurityAccess("clearProviderProperties." + name); //$NON-NLS-1$
        }
        super.clear();
        if (serviceTable != null) {
            serviceTable.clear();
        }
        if (propertyServiceTable != null) {
            propertyServiceTable.clear();
        }
        if (aliasTable != null) {
            aliasTable.clear();
        }
        if (propertyAliasTable != null) {
            propertyAliasTable.clear();
        }
        // BEGIN android-changed
        changedProperties = null;
        // END android-changed
        putProviderInfo();
        if (providerNumber != -1) {
            // if registered then refresh Services
            Services.setNeedRefresh();
        }
        servicesChanged();
    
public synchronized java.util.SetentrySet()

        return Collections.unmodifiableSet(super.entrySet());
    
public java.lang.StringgetInfo()
Returns a description of the services being provided.

return
a description of the services being provided.
since
Android 1.0

        return info;
    
public java.lang.StringgetName()
Returns the name of this provider.

return
the name of this provider.
since
Android 1.0

        return name;
    
private java.lang.StringgetPropertyIgnoreCase(java.lang.String key)

        String res = getProperty(key);
        if (res != null) {
            return res;
        }
        for (Enumeration<?> e = propertyNames(); e.hasMoreElements();) {
            String pname = (String) e.nextElement();
            if (key.equalsIgnoreCase(pname)) {
                return getProperty(pname);
            }
        }
        return null;
    
intgetProviderNumber()
Get the provider preference order number.

return

        return providerNumber;
    
synchronized java.security.Provider$ServicegetService(java.lang.String type)
Get the service of the specified type

        updatePropertyServiceTable();
        if (lastServicesByType != null && type.equals(lastType)) {
            return lastServicesByType;
        }
        Provider.Service service;
        for (Iterator<Service> it = getServices().iterator(); it.hasNext();) {
            service = it.next();
            if (type.equals(service.type)) {
                lastType = type;
                lastServicesByType = service;
                return service;
            }
        }
        return null;
    
public synchronized java.security.Provider$ServicegetService(java.lang.String type, java.lang.String algorithm)
Returns the service with the specified {@code type} implementing the specified {@code algorithm}, or {@code null} if no such implementation exists.

If two services match the requested type and algorithm, the one added with the {@link #putService(Service)} is returned (as opposed to the one added via {@link #put(Object, Object)}.

param
type the type of the service (for example {@code KeyPairGenerator})
param
algorithm the algorithm name (case insensitive)
return
the requested service, or {@code null} if no such implementation exists
since
Android 1.0

        if (type == null || algorithm == null) {
            throw new NullPointerException();
        }

        if (type.equals(lastServiceName)
                && algorithm.equalsIgnoreCase(lastAlgorithm)) {
            return returnedService;
        }

        String alg = algorithm.toUpperCase();
        Object o = null;
        if (serviceTable != null) {
            o = serviceTable.get(type, alg);
        }
        if (o == null && aliasTable != null) {
            o = aliasTable.get(type, alg);
        }
        if (o == null) {
            updatePropertyServiceTable();
        }
        if (o == null && propertyServiceTable != null) {
            o = propertyServiceTable.get(type, alg);
        }
        if (o == null && propertyAliasTable != null) {
            o = propertyAliasTable.get(type, alg);
        }

        if (o != null) {
            lastServiceName = type;
            lastAlgorithm = algorithm;
            returnedService = (Provider.Service) o;
            return returnedService;
        }
        return null;
    
public synchronized java.util.SetgetServices()
Returns an unmodifiable {@code Set} of all services registered by this provider.

return
an unmodifiable {@code Set} of all services registered by this provider
since
Android 1.0

        updatePropertyServiceTable();
        if (lastServicesSet != null) {
            return lastServicesSet;
        }
        if (serviceTable != null) {
            lastServicesSet = new HashSet<Service>(serviceTable.values());
        } else {
            lastServicesSet = new HashSet<Service>();
        }
        if (propertyServiceTable != null) {
            lastServicesSet.addAll(propertyServiceTable.values());
        }
        lastServicesSet = Collections.unmodifiableSet(lastServicesSet);
        return lastServicesSet;
    
public doublegetVersion()
Returns the version number for the services being provided.

return
the version number for the services being provided.
since
Android 1.0

        return version;
    
booleanimplementsAlg(java.lang.String serv, java.lang.String alg, java.lang.String attribute, java.lang.String val)
returns true if the provider implements the specified algorithm. Caller must specify the cryptographic service and specify constraints via the attribute name the attribute value

param
serv Crypto service.
param
alg Algorithm or type.
param
attribute The attribute name or {@code null}.
param
val The attribute value.
return

        String servAlg = serv + "." + alg; //$NON-NLS-1$
        String prop = getPropertyIgnoreCase(servAlg);
        if (prop == null) {
            alg = getPropertyIgnoreCase("Alg.Alias." + servAlg); //$NON-NLS-1$
            if (alg != null) {
                servAlg = serv + "." + alg; //$NON-NLS-1$
                prop = getPropertyIgnoreCase(serv + "." + alg); //$NON-NLS-1$
            }
        }
        if (prop != null) {
            if (attribute == null) {
                return true;
            } else {
                return checkAttribute(serv + "." + alg, attribute, val); //$NON-NLS-1$
            }
        }
        return false;
    
public java.util.SetkeySet()

        return Collections.unmodifiableSet(super.keySet());
    
public synchronized voidload(java.io.InputStream inStream)

        Properties tmp = new Properties();
        tmp.load(inStream);
        myPutAll(tmp);
    
private voidmyPutAll(java.util.Map t)

        if (changedProperties == null) {
            changedProperties = new Properties();
        }
        Iterator<? extends Map.Entry<?, ?>> it = t.entrySet().iterator();
        Object key;
        Object value;
        while (it.hasNext()) {
            Map.Entry<?, ?> entry = it.next();
            key = entry.getKey();
            if (key instanceof String && ((String) key).startsWith("Provider.")) { //$NON-NLS-1$
                // Provider service type is reserved
                continue;
            }
            value = entry.getValue();
            super.put(key, value);
            if (changedProperties.remove(key) == null) {
                removeFromPropertyServiceTable(key);
            }
            changedProperties.put(key, value);
        }
        if (providerNumber != -1) {
            // if registered then refresh Services
            Services.setNeedRefresh();
        }
    
public synchronized java.lang.Objectput(java.lang.Object key, java.lang.Object value)
Maps the specified {@code key} property name to the specified {@code value}.

If a {@code SecurityManager} is installed, code calling this method needs the {@code SecurityPermission} {@code putProviderProperty.NAME} (where NAME is the provider name) to be granted, otherwise a {@code SecurityException} will be thrown.

param
key the name of the property.
param
value the value of the property.
return
the value that was previously mapped to the specified {@code key} ,or {@code null} if it did not have one.
throws
SecurityException if a {@code SecurityManager} is installed and the caller does not have permission to invoke this method.
since
Android 1.0

        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkSecurityAccess("putProviderProperty." + name); //$NON-NLS-1$
        }
        if (key instanceof String && ((String) key).startsWith("Provider.")) { //$NON-NLS-1$
            // Provider service type is reserved
            return null;
        }
        if (providerNumber != -1) {
            // if registered then refresh Services
            Services.setNeedRefresh();
        }
        if (changedProperties != null && changedProperties.remove(key) == null) {
            removeFromPropertyServiceTable(key);
        }
        if (changedProperties == null) {
            changedProperties = new Properties();
        }
        changedProperties.put(key, value);
        return super.put(key, value);
    
public synchronized voidputAll(java.util.Map t)
Copies all from the provided map to this {@code Provider}.

If a {@code SecurityManager} is installed, code calling this method needs the {@code SecurityPermission} {@code putProviderProperty.NAME} (where NAME is the provider name) to be granted, otherwise a {@code SecurityException} will be thrown.

param
t the mappings to copy to this provider.
throws
SecurityException if a {@code SecurityManager} is installed and the caller does not have permission to invoke this method.
since
Android 1.0


        // Implementation note:
        // checkSecurityAccess method call is NOT specified
        // Do it as in put(Object key, Object value).

        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkSecurityAccess("putProviderProperty." + name); //$NON-NLS-1$
        }
        myPutAll(t);
    
private voidputProviderInfo()

        super.put("Provider.id name", null != name ? name : "null"); //$NON-NLS-1$
        super.put("Provider.id version", versionString); //$NON-NLS-1$
        super.put("Provider.id info", null != info ? info : "null"); //$NON-NLS-1$
        super.put("Provider.id className", this.getClass().getName()); //$NON-NLS-1$
    
protected synchronized voidputService(java.security.Provider$Service s)
Adds a {@code Service} to this {@code Provider}. If a service with the same name was registered via this method, it is replace.

If a {@code SecurityManager} is installed, code calling this method needs the {@code SecurityPermission} {@code putProviderProperty.NAME} (where NAME is the provider name) to be granted, otherwise a {@code SecurityException} will be thrown.

param
s the {@code Service} to register
throws
SecurityException if a {@code SecurityManager} is installed and the caller does not have permission to invoke this method
since
Android 1.0

        if (s == null) {
            throw new NullPointerException();
        }
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkSecurityAccess("putProviderProperty." + name); //$NON-NLS-1$
        }
        if ("Provider".equals(s.getType())) { // Provider service type cannot be //$NON-NLS-1$
                                              // added
            return;
        }
        servicesChanged();
        if (serviceTable == null) {
            serviceTable = new TwoKeyHashMap<String, String, Service>(128);
        }
        serviceTable.put(s.type, s.algorithm.toUpperCase(), s);
        if (s.aliases != null) {
            if (aliasTable == null) {
                aliasTable = new TwoKeyHashMap<String, String, Service>(256);
            }
            for (Iterator<String> it = s.getAliases(); it.hasNext();) {
                aliasTable.put(s.type, (it.next()).toUpperCase(), s);
            }
        }
        serviceInfoToProperties(s);
    
public synchronized java.lang.Objectremove(java.lang.Object key)
Removes the specified {@code key} and its associated value from this {@code Provider}.

If a {@code SecurityManager} is installed, code calling this method needs the {@code SecurityPermission} {@code removeProviderProperty.NAME} (where NAME is the provider name) to be granted, otherwise a {@code SecurityException} will be thrown.

param
key the name of the property
return
the value that was mapped to the specified {@code key} ,or {@code null} if no mapping was present
throws
SecurityException if a {@code SecurityManager} is installed and the caller does not have the permission to invoke this method.
since
Android 1.0

        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkSecurityAccess("removeProviderProperty." + name); //$NON-NLS-1$
        }
        if (key instanceof String && ((String) key).startsWith("Provider.")) { //$NON-NLS-1$
            // Provider service type is reserved
            return null;
        }
        if (providerNumber != -1) {
            // if registered then refresh Services
            Services.setNeedRefresh();
        }
        if (changedProperties != null && changedProperties.remove(key) == null) {
            removeFromPropertyServiceTable(key);
            // BEGIN android-added
            if (changedProperties.size() == 0) {
                changedProperties = null;
            }
            // END android-added
        }
        return super.remove(key);
    
private voidremoveFromPropertyServiceTable(java.lang.Object key)

        if (key == null || !(key instanceof String)) {
            return;
        }
        String k = (String) key;
        if (k.startsWith("Provider.")) { // Provider service type is reserved //$NON-NLS-1$
            return;
        }
        Provider.Service s;
        String serviceName;
        String algorithm = null;
        String attribute = null;
        int i;
        if (k.startsWith("Alg.Alias.")) { // Alg.Alias.<crypto_service>.<aliasName>=<stanbdardName> //$NON-NLS-1$
            String aliasName;
            String service_alias = k.substring(10);
            i = service_alias.indexOf("."); //$NON-NLS-1$
            serviceName = service_alias.substring(0, i);
            aliasName = service_alias.substring(i + 1);
            if (propertyAliasTable != null) {
                propertyAliasTable.remove(serviceName, aliasName.toUpperCase());
            }
            if (propertyServiceTable != null) {
                for (Iterator<Service> it = propertyServiceTable.values().iterator(); it
                        .hasNext();) {
                    s = it.next();
                    if (s.aliases.contains(aliasName)) {
                        s.aliases.remove(aliasName);
                        return;
                    }
                }
            }
            return;
        }
        int j = k.indexOf("."); //$NON-NLS-1$
        if (j == -1) { // unknown format
            return;
        }

        i = k.indexOf(" "); //$NON-NLS-1$
        if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className>
            serviceName = k.substring(0, j);
            algorithm = k.substring(j + 1);
            if (propertyServiceTable != null) {
                Provider.Service ser = propertyServiceTable.remove(serviceName, algorithm.toUpperCase());
                if (ser != null && propertyAliasTable != null
                        && ser.aliases != null) {
                    for (Iterator<String> it = ser.aliases.iterator(); it.hasNext();) {
                        propertyAliasTable.remove(serviceName, (it
                                .next()).toUpperCase());
                    }
                }
            }
        } else { // <crypto_service>.<algorithm_or_type>
                 // <attribute_name>=<attrValue>
            attribute = k.substring(i + 1);
            serviceName = k.substring(0, j);
            algorithm = k.substring(j + 1, i);
            if (propertyServiceTable != null) {
                Object o = propertyServiceTable.get(serviceName, algorithm
                        .toUpperCase());
                if (o != null) {
                    s = (Provider.Service) o;
                    s.attributes.remove(attribute);
                }
            }
        }
    
protected synchronized voidremoveService(java.security.Provider$Service s)
Removes a previously registered {@code Service} from this {@code Provider}.

If a {@code SecurityManager} is installed, code calling this method needs the {@code SecurityPermission} {@code removeProviderProperty.NAME} (where NAME is the provider name) to be granted, otherwise a {@code SecurityException} will be thrown.

param
s the {@code Service} to remove
throws
SecurityException if a {@code SecurityManager} is installed and the caller does not have permission to invoke this method
throws
NullPointerException if {@code s} is {@code null}
since
Android 1.0

        if (s == null) {
            throw new NullPointerException();
        }
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkSecurityAccess("removeProviderProperty." + name); //$NON-NLS-1$
        }
        servicesChanged();
        if (serviceTable != null) {
            serviceTable.remove(s.type, s.algorithm.toUpperCase());
        }
        if (aliasTable != null && s.aliases != null) {
            for (Iterator<String> it = s.getAliases(); it.hasNext();) {
                aliasTable.remove(s.type, (it.next()).toUpperCase());
            }
        }
        serviceInfoFromProperties(s);
    
private voidserviceInfoFromProperties(java.security.Provider$Service s)

        super.remove(s.type + "." + s.algorithm); //$NON-NLS-1$
        if (s.aliases != null) {
            for (Iterator<String> i = s.aliases.iterator(); i.hasNext();) {
                super.remove("Alg.Alias." + s.type + "." + i.next()); //$NON-NLS-1$ //$NON-NLS-2$
            }
        }
        if (s.attributes != null) {
            for (Iterator<Map.Entry<String, String>> i = s.attributes.entrySet().iterator(); i.hasNext();) {
                Map.Entry<String, String> entry = i.next();
                super.remove(s.type + "." + s.algorithm + " " + entry.getKey()); //$NON-NLS-1$ //$NON-NLS-2$
            }
        }
        if (providerNumber != -1) {
            // if registered then refresh Services
            Services.setNeedRefresh();
        }
    
private voidserviceInfoToProperties(java.security.Provider$Service s)

        super.put(s.type + "." + s.algorithm, s.className); //$NON-NLS-1$
        if (s.aliases != null) {
            for (Iterator<String> i = s.aliases.iterator(); i.hasNext();) {
                super.put("Alg.Alias." + s.type + "." + i.next(), s.algorithm); //$NON-NLS-1$ //$NON-NLS-2$
            }
        }
        if (s.attributes != null) {
            for (Iterator<Map.Entry<String, String>> i = s.attributes.entrySet().iterator(); i.hasNext();) {
                Map.Entry<String, String> entry = i.next();
                super.put(s.type + "." + s.algorithm + " " + entry.getKey(), //$NON-NLS-1$ //$NON-NLS-2$
                        entry.getValue());
            }
        }
        if (providerNumber != -1) {
            // if registered then refresh Services
            Services.setNeedRefresh();
        }
    
private voidservicesChanged()

        lastServicesByType = null;
        lastServiceName = null;
        lastServicesSet = null;
    
voidsetProviderNumber(int n)
Set the provider preference order number.

param
n

        providerNumber = n;
    
public java.lang.StringtoString()
Returns a string containing a concise, human-readable description of this {@code Provider} including its name and its version.

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

        // BEGIN android-changed
        return name + " version " + version; //$NON-NLS-1$
        // END android-changed
    
private voidupdatePropertyServiceTable()

        Object _key;
        Object _value;
        Provider.Service s;
        String serviceName;
        String algorithm;
        if (changedProperties == null || changedProperties.isEmpty()) {
            return;
        }
        for (Iterator<Map.Entry<Object, Object>> it = changedProperties.entrySet().iterator(); it
                .hasNext();) {
            Map.Entry<Object, Object> entry = it.next();
            _key = entry.getKey();
            _value = entry.getValue();
            if (_key == null || _value == null || !(_key instanceof String)
                    || !(_value instanceof String)) {
                continue;
            }
            String key = (String) _key;
            String value = (String) _value;
            if (key.startsWith("Provider")) { // Provider service type is reserved //$NON-NLS-1$
                continue;
            }
            int i;
            if (key.startsWith("Alg.Alias.")) { // Alg.Alias.<crypto_service>.<aliasName>=<stanbdardName> //$NON-NLS-1$
                String aliasName;
                String service_alias = key.substring(10);
                i = service_alias.indexOf("."); //$NON-NLS-1$
                serviceName = service_alias.substring(0, i);
                aliasName = service_alias.substring(i + 1);
                algorithm = value;
                String algUp = algorithm.toUpperCase();
                Object o = null;
                if (propertyServiceTable == null) {
                    propertyServiceTable = new TwoKeyHashMap<String, String, Service>(128);
                } else {
                    o = propertyServiceTable.get(serviceName, algUp);
                }
                if (o != null) {
                    s = (Provider.Service) o;
                    // BEGIN android-changed
                    s.addAlias(aliasName);
                    // END android-changed
                    if (propertyAliasTable == null) {
                        propertyAliasTable = new TwoKeyHashMap<String, String, Service>(256);
                    }
                    propertyAliasTable.put(serviceName,
                            aliasName.toUpperCase(), s);
                } else {
                    String className = (String) changedProperties
                            .get(serviceName + "." + algorithm); //$NON-NLS-1$
                    if (className != null) {
                        List<String> l = new ArrayList<String>();
                        l.add(aliasName);
                        s = new Provider.Service(this, serviceName, algorithm,
                                className, l, new HashMap<String, String>());
                        propertyServiceTable.put(serviceName, algUp, s);
                        if (propertyAliasTable == null) {
                            propertyAliasTable = new TwoKeyHashMap<String, String, Service>(256);
                        }
                        propertyAliasTable.put(serviceName, aliasName
                                .toUpperCase(), s);
                    }
                }
                continue;
            }
            int j = key.indexOf("."); //$NON-NLS-1$
            if (j == -1) { // unknown format
                continue;
            }
            i = key.indexOf(" "); //$NON-NLS-1$
            if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className>
                serviceName = key.substring(0, j);
                algorithm = key.substring(j + 1);
                String alg = algorithm.toUpperCase();
                Object o = null;
                if (propertyServiceTable != null) {
                    o = propertyServiceTable.get(serviceName, alg);
                }
                if (o != null) {
                    s = (Provider.Service) o;
                    s.className = value;
                } else {
                    // BEGIN android-changed
                    s = new Provider.Service(this, serviceName, algorithm,
                            value, Collections.<String>emptyList(),
                            Collections.<String,String>emptyMap());
                    // END android-changed
                    if (propertyServiceTable == null) {
                        propertyServiceTable = new TwoKeyHashMap<String, String, Service>(128);
                    }
                    propertyServiceTable.put(serviceName, alg, s);

                }
            } else { // <crypto_service>.<algorithm_or_type>
                     // <attribute_name>=<attrValue>
                serviceName = key.substring(0, j);
                algorithm = key.substring(j + 1, i);
                String attribute = key.substring(i + 1);
                String alg = algorithm.toUpperCase();
                Object o = null;
                if (propertyServiceTable != null) {
                    o = propertyServiceTable.get(serviceName, alg);
                }
                if (o != null) {
                    s = (Provider.Service) o;
                    // BEGIN android-changed
                    s.putAttribute(attribute, value);
                    // END android-changed
                } else {
                    String className = (String) changedProperties
                            .get(serviceName + "." + algorithm); //$NON-NLS-1$
                    if (className != null) {
                        Map<String, String> m = new HashMap<String, String>();
                        m.put(attribute, value);
                        s = new Provider.Service(this, serviceName, algorithm,
                                className, new ArrayList<String>(), m);
                        if (propertyServiceTable == null) {
                            propertyServiceTable = new TwoKeyHashMap<String, String, Service>(128);
                        }
                        propertyServiceTable.put(serviceName, alg, s);
                    }
                }
            }
        }
        servicesChanged();
        // BEGIN android-changed
        changedProperties = null;
        // END android-changed
    
public java.util.Collectionvalues()

        return Collections.unmodifiableCollection(super.values());