jaxws/src/java.xml.ws/share/classes/javax/xml/soap/ServiceLoaderUtil.java
changeset 34467 024f1ce7da02
child 45678 65fdff10664d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/ServiceLoaderUtil.java	Fri Nov 27 11:28:43 2015 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.xml.soap;
+
+import java.util.ServiceLoader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Shared ServiceLoader/FactoryFinder Utils shared among SAAJ, JAXB and JAXWS
+ * Class duplicated to all those projects.
+ *
+ * @author Miroslav.Kos@oracle.com
+ */
+class ServiceLoaderUtil {
+
+    static <P, T extends Exception> P firstByServiceLoader(Class<P> spiClass,
+                                                           Logger logger,
+                                                           ExceptionHandler<T> handler) throws T {
+        logger.log(Level.FINE, "Using java.util.ServiceLoader to find {0}", spiClass.getName());
+        // service discovery
+        try {
+            ServiceLoader<P> serviceLoader = ServiceLoader.load(spiClass);
+
+            for (P impl : serviceLoader) {
+                logger.fine("ServiceProvider loading Facility used; returning object [" +
+                        impl.getClass().getName() + "]");
+
+                return impl;
+            }
+        } catch (Throwable t) {
+            throw handler.createException(t, "Error while searching for service [" + spiClass.getName() + "]");
+        }
+        return null;
+    }
+
+    static void checkPackageAccess(String className) {
+        // make sure that the current thread has an access to the package of the given name.
+        SecurityManager s = System.getSecurityManager();
+        if (s != null) {
+            int i = className.lastIndexOf('.');
+            if (i != -1) {
+                s.checkPackageAccess(className.substring(0, i));
+            }
+        }
+    }
+
+    static Class nullSafeLoadClass(String className, ClassLoader classLoader) throws ClassNotFoundException {
+        if (classLoader == null) {
+            return Class.forName(className);
+        } else {
+            return classLoader.loadClass(className);
+        }
+    }
+
+    // Returns instance of required class. It checks package access (security)
+    // unless it is defaultClassname. It means if you are trying to instantiate
+    // default implementation (fallback), pass the class name to both first and second parameter.
+    static <T extends Exception> Object newInstance(String className,
+                                                    String defaultImplClassName, ClassLoader classLoader,
+                                                    final ExceptionHandler<T> handler) throws T {
+        try {
+            return safeLoadClass(className, defaultImplClassName, classLoader).newInstance();
+        } catch (ClassNotFoundException x) {
+            throw handler.createException(x, "Provider " + className + " not found");
+        } catch (Exception x) {
+            throw handler.createException(x, "Provider " + className + " could not be instantiated: " + x);
+        }
+    }
+
+    static Class safeLoadClass(String className,
+                               String defaultImplClassName,
+                               ClassLoader classLoader) throws ClassNotFoundException {
+
+        try {
+            checkPackageAccess(className);
+        } catch (SecurityException se) {
+            // anyone can access the platform default factory class without permission
+            if (defaultImplClassName != null && defaultImplClassName.equals(className)) {
+                return Class.forName(className);
+            }
+            // not platform default implementation ...
+            throw se;
+        }
+        return nullSafeLoadClass(className, classLoader);
+    }
+
+    static <T extends Exception> ClassLoader contextClassLoader(ExceptionHandler<T> exceptionHandler) throws T {
+        try {
+            return Thread.currentThread().getContextClassLoader();
+        } catch (Exception x) {
+            throw exceptionHandler.createException(x, x.toString());
+        }
+    }
+
+    static abstract class ExceptionHandler<T extends Exception> {
+
+        public abstract T createException(Throwable throwable, String message);
+
+    }
+
+}