Path: blob/master/src/java.base/share/classes/sun/security/jca/GetInstance.java
41159 views
/*1* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.jca;2627import java.util.*;2829import java.security.*;30import java.security.Provider.Service;3132/**33* Collection of utility methods to facilitate implementing getInstance()34* methods in the JCA/JCE/JSSE/... framework.35*36* @author Andreas Sterbenz37* @since 1.538*/39public class GetInstance {4041private GetInstance() {42// empty43}4445/**46* Static inner class representing a newly created instance.47*/48public static final class Instance {49// public final fields, access directly without accessors50public final Provider provider;51public final Object impl;52private Instance(Provider provider, Object impl) {53this.provider = provider;54this.impl = impl;55}56// Return Provider and implementation as an array as used in the57// old Security.getImpl() methods.58public Object[] toArray() {59return new Object[] {impl, provider};60}61}6263public static Service getService(String type, String algorithm)64throws NoSuchAlgorithmException {65ProviderList list = Providers.getProviderList();66Service s = list.getService(type, algorithm);67if (s == null) {68throw new NoSuchAlgorithmException69(algorithm + " " + type + " not available");70}71return s;72}7374public static Service getService(String type, String algorithm,75String provider) throws NoSuchAlgorithmException,76NoSuchProviderException {77if (provider == null || provider.isEmpty()) {78throw new IllegalArgumentException("missing provider");79}80Provider p = Providers.getProviderList().getProvider(provider);81if (p == null) {82throw new NoSuchProviderException("no such provider: " + provider);83}84Service s = p.getService(type, algorithm);85if (s == null) {86throw new NoSuchAlgorithmException("no such algorithm: "87+ algorithm + " for provider " + provider);88}89return s;90}9192public static Service getService(String type, String algorithm,93Provider provider) throws NoSuchAlgorithmException {94if (provider == null) {95throw new IllegalArgumentException("missing provider");96}97Service s = provider.getService(type, algorithm);98if (s == null) {99throw new NoSuchAlgorithmException("no such algorithm: "100+ algorithm + " for provider " + provider.getName());101}102return s;103}104105/**106* Return a List of all the available Services that implement107* (type, algorithm). Note that the list is initialized lazily108* and Provider loading and lookup is only trigered when109* necessary.110*/111public static List<Service> getServices(String type, String algorithm) {112ProviderList list = Providers.getProviderList();113return list.getServices(type, algorithm);114}115116/**117* This method exists for compatibility with JCE only. It will be removed118* once JCE has been changed to use the replacement method.119* @deprecated use {@code getServices(List<ServiceId>)} instead120*/121@Deprecated122public static List<Service> getServices(String type,123List<String> algorithms) {124ProviderList list = Providers.getProviderList();125return list.getServices(type, algorithms);126}127128/**129* Return a List of all the available Services that implement any of130* the specified algorithms. See getServices(String, String) for detals.131*/132public static List<Service> getServices(List<ServiceId> ids) {133ProviderList list = Providers.getProviderList();134return list.getServices(ids);135}136137/*138* For all the getInstance() methods below:139* @param type the type of engine (e.g. MessageDigest)140* @param clazz the Spi class that the implementation must subclass141* (e.g. MessageDigestSpi.class) or null if no superclass check142* is required143* @param algorithm the name of the algorithm (or alias), e.g. MD5144* @param provider the provider (String or Provider object)145* @param param the parameter to pass to the Spi constructor146* (for CertStores)147*148* There are overloaded methods for all the permutations.149*/150151public static Instance getInstance(String type, Class<?> clazz,152String algorithm) throws NoSuchAlgorithmException {153// in the almost all cases, the first service will work154// avoid taking long path if so155ProviderList list = Providers.getProviderList();156Service firstService = list.getService(type, algorithm);157if (firstService == null) {158throw new NoSuchAlgorithmException159(algorithm + " " + type + " not available");160}161NoSuchAlgorithmException failure;162try {163return getInstance(firstService, clazz);164} catch (NoSuchAlgorithmException e) {165failure = e;166}167// if we cannot get the service from the preferred provider,168// fail over to the next169for (Service s : list.getServices(type, algorithm)) {170if (s == firstService) {171// do not retry initial failed service172continue;173}174try {175return getInstance(s, clazz);176} catch (NoSuchAlgorithmException e) {177failure = e;178}179}180throw failure;181}182183public static Instance getInstance(String type, Class<?> clazz,184String algorithm, Object param) throws NoSuchAlgorithmException {185List<Service> services = getServices(type, algorithm);186NoSuchAlgorithmException failure = null;187for (Service s : services) {188try {189return getInstance(s, clazz, param);190} catch (NoSuchAlgorithmException e) {191failure = e;192}193}194if (failure != null) {195throw failure;196} else {197throw new NoSuchAlgorithmException198(algorithm + " " + type + " not available");199}200}201202public static Instance getInstance(String type, Class<?> clazz,203String algorithm, String provider) throws NoSuchAlgorithmException,204NoSuchProviderException {205return getInstance(getService(type, algorithm, provider), clazz);206}207208public static Instance getInstance(String type, Class<?> clazz,209String algorithm, Object param, String provider)210throws NoSuchAlgorithmException, NoSuchProviderException {211return getInstance(getService(type, algorithm, provider), clazz, param);212}213214public static Instance getInstance(String type, Class<?> clazz,215String algorithm, Provider provider)216throws NoSuchAlgorithmException {217return getInstance(getService(type, algorithm, provider), clazz);218}219220public static Instance getInstance(String type, Class<?> clazz,221String algorithm, Object param, Provider provider)222throws NoSuchAlgorithmException {223return getInstance(getService(type, algorithm, provider), clazz, param);224}225226/*227* The two getInstance() methods below take a service. They are228* intended for classes that cannot use the standard methods, e.g.229* because they implement delayed provider selection like the230* Signature class.231*/232233public static Instance getInstance(Service s, Class<?> clazz)234throws NoSuchAlgorithmException {235Object instance = s.newInstance(null);236checkSuperClass(s, instance.getClass(), clazz);237return new Instance(s.getProvider(), instance);238}239240public static Instance getInstance(Service s, Class<?> clazz,241Object param) throws NoSuchAlgorithmException {242Object instance = s.newInstance(param);243checkSuperClass(s, instance.getClass(), clazz);244return new Instance(s.getProvider(), instance);245}246247/**248* Check is subClass is a subclass of superClass. If not,249* throw a NoSuchAlgorithmException.250*/251public static void checkSuperClass(Service s, Class<?> subClass,252Class<?> superClass) throws NoSuchAlgorithmException {253if (superClass == null) {254return;255}256if (superClass.isAssignableFrom(subClass) == false) {257throw new NoSuchAlgorithmException258("class configured for " + s.getType() + ": "259+ s.getClassName() + " not a " + s.getType());260}261}262263}264265266