/** * Returns the array of providers which meet the user supplied set of filters. The filter must be * supplied in one of two formats: <nl> * <li>CRYPTO_SERVICE_NAME.ALGORITHM_OR_TYPE * * <p>for example: "MessageDigest.SHA" The value associated with the key must be an empty * string. * <li>CRYPTO_SERVICE_NAME.ALGORITHM_OR_TYPE ATTR_NAME:ATTR_VALUE * * <p>for example: "Signature.MD2withRSA KeySize:512" where "KeySize:512" is the value of the * filter map entry. </nl> * * @param filter case-insensitive filter. * @return the providers which meet the user supplied string filter {@code filter}. A {@code null} * value signifies that none of the installed providers meets the filter specification. * @throws InvalidParameterException if an unusable filter is supplied. * @throws NullPointerException if {@code filter} is {@code null}. */ public static synchronized Provider[] getProviders(Map<String, String> filter) { if (filter == null) { throw new NullPointerException(); } if (filter.isEmpty()) { return null; } java.util.List<Provider> result = Services.getProvidersList(); Set<Entry<String, String>> keys = filter.entrySet(); Map.Entry<String, String> entry; for (Iterator<Entry<String, String>> it = keys.iterator(); it.hasNext(); ) { entry = it.next(); String key = entry.getKey(); String val = entry.getValue(); String attribute = null; int i = key.indexOf(' '); int j = key.indexOf('.'); if (j == -1) { throw new InvalidParameterException(); } if (i == -1) { // <crypto_service>.<algorithm_or_type> if (val.length() != 0) { throw new InvalidParameterException(); } } else { // <crypto_service>.<algorithm_or_type> <attribute_name> if (val.length() == 0) { throw new InvalidParameterException(); } attribute = key.substring(i + 1); if (attribute.trim().length() == 0) { throw new InvalidParameterException(); } key = key.substring(0, i); } String serv = key.substring(0, j); String alg = key.substring(j + 1); if (serv.length() == 0 || alg.length() == 0) { throw new InvalidParameterException(); } Provider p; for (int k = 0; k < result.size(); k++) { try { p = result.get(k); } catch (IndexOutOfBoundsException e) { break; } if (!p.implementsAlg(serv, alg, attribute, val)) { result.remove(p); k--; } } } if (result.size() > 0) { return result.toArray(new Provider[result.size()]); } return null; }
/** * Insert the given {@code Provider} at the specified {@code position}. The positions define the * preference order in which providers are searched for requested algorithms. * * @param provider the provider to insert. * @param position the position (starting from 1). * @return the actual position or {@code -1} if the given {@code provider} was already in the * list. The actual position may be different from the desired position. */ public static synchronized int insertProviderAt(Provider provider, int position) { // check that provider is not already // installed, else return -1; if (position <1) or (position > max // position) position = max position + 1; insert provider, shift up // one position for next providers; Note: The position is 1-based if (getProvider(provider.getName()) != null) { return -1; } int result = Services.insertProviderAt(provider, position); renumProviders(); return result; }
/** * Removes the {@code Provider} with the specified name form the collection of providers. If the * the {@code Provider} with the specified name is removed, all provider at a greater position are * shifted down one position. * * <p>Returns silently if {@code name} is {@code null} or no provider with the specified name is * installed. * * @param name the name of the provider to remove. */ public static synchronized void removeProvider(String name) { // It is not clear from spec.: // 1. if name is null, should we checkSecurityAccess or not? // throw SecurityException or not? // 2. as 1 but provider is not installed // 3. behavior if name is empty string? Provider p; if ((name == null) || (name.length() == 0)) { return; } p = getProvider(name); if (p == null) { return; } Services.removeProvider(p.getProviderNumber()); renumProviders(); p.setProviderNumber(-1); }
/** Update sequence numbers of all providers. */ private static void renumProviders() { Provider[] p = Services.getProviders(); for (int i = 0; i < p.length; i++) { p[i].setProviderNumber(i + 1); } }
/** * Returns the {@code Provider} with the specified name. Returns {@code null} if name is {@code * null} or no provider with the specified name is installed. * * @param name the name of the requested provider. * @return the provider with the specified name, maybe {@code null}. */ public static synchronized Provider getProvider(String name) { return Services.getProvider(name); }
/** * Returns an array containing all installed providers. The providers are ordered according their * preference order. * * @return an array containing all installed providers. */ public static synchronized Provider[] getProviders() { return Services.getProviders(); }