jaxws/src/jdk.xml.bind/share/classes/com/sun/xml/internal/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java
changeset 32904 42076a665ea1
parent 25871 b80b84e87032
child 33547 e4c76ac38b12
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/src/jdk.xml.bind/share/classes/com/sun/xml/internal/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java	Fri Oct 02 14:36:40 2015 +0200
@@ -0,0 +1,261 @@
+/**
+ * Copyright (c) 2001, 2015 Thai Open Source Software Center Ltd
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *     Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *
+ *     Neither the name of the Thai Open Source Software Center Ltd nor
+ *     the names of its contributors may be used to endorse or promote
+ *     products derived from this software without specific prior written
+ *     permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.sun.xml.internal.org.relaxng.datatype.helpers;
+
+import com.sun.xml.internal.org.relaxng.datatype.DatatypeLibraryFactory;
+import com.sun.xml.internal.org.relaxng.datatype.DatatypeLibrary;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+
+/**
+ * Discovers the datatype library implementation from the classpath.
+ *
+ * <p>
+ * The call of the createDatatypeLibrary method finds an implementation
+ * from a given datatype library URI at run-time.
+ */
+public class DatatypeLibraryLoader implements DatatypeLibraryFactory {
+  private final Service service = new Service(DatatypeLibraryFactory.class);
+
+  public DatatypeLibrary createDatatypeLibrary(String uri) {
+    for (Enumeration e = service.getProviders();
+         e.hasMoreElements();) {
+      DatatypeLibraryFactory factory
+        = (DatatypeLibraryFactory)e.nextElement();
+      DatatypeLibrary library = factory.createDatatypeLibrary(uri);
+      if (library != null)
+        return library;
+    }
+    return null;
+  }
+
+        private static class Service {
+          private final Class serviceClass;
+          private final Enumeration configFiles;
+          private Enumeration classNames = null;
+          private final Vector providers = new Vector();
+          private Loader loader;
+
+          private class ProviderEnumeration implements Enumeration {
+            private int nextIndex = 0;
+
+            public boolean hasMoreElements() {
+              return nextIndex < providers.size() || moreProviders();
+            }
+
+            public Object nextElement() {
+              try {
+                return providers.elementAt(nextIndex++);
+              }
+              catch (ArrayIndexOutOfBoundsException e) {
+                throw new NoSuchElementException();
+              }
+            }
+          }
+
+          private static class Singleton implements Enumeration {
+            private Object obj;
+            private Singleton(Object obj) {
+              this.obj = obj;
+            }
+
+            public boolean hasMoreElements() {
+              return obj != null;
+            }
+
+            public Object nextElement() {
+              if (obj == null)
+                throw new NoSuchElementException();
+              Object tem = obj;
+              obj = null;
+              return tem;
+            }
+          }
+
+          // JDK 1.1
+          private static class Loader {
+            Enumeration getResources(String resName) {
+              ClassLoader cl = Loader.class.getClassLoader();
+              URL url;
+              if (cl == null)
+                url = ClassLoader.getSystemResource(resName);
+              else
+                url = cl.getResource(resName);
+              return new Singleton(url);
+            }
+
+            Class loadClass(String name) throws ClassNotFoundException {
+              return Class.forName(name);
+            }
+          }
+
+          // JDK 1.2+
+          private static class Loader2 extends Loader {
+            private ClassLoader cl;
+
+            Loader2() {
+              cl = Loader2.class.getClassLoader();
+              // If the thread context class loader has the class loader
+              // of this class as an ancestor, use the thread context class
+              // loader.  Otherwise, the thread context class loader
+              // probably hasn't been set up properly, so don't use it.
+              ClassLoader clt = Thread.currentThread().getContextClassLoader();
+              for (ClassLoader tem = clt; tem != null; tem = tem.getParent())
+                if (tem == cl) {
+                  cl = clt;
+                  break;
+                }
+            }
+
+            Enumeration getResources(String resName) {
+              try {
+                return cl.getResources(resName);
+              }
+              catch (IOException e) {
+                return new Singleton(null);
+              }
+            }
+
+            Class loadClass(String name) throws ClassNotFoundException {
+              return Class.forName(name, true, cl);
+            }
+          }
+
+          public Service(Class cls) {
+            try {
+              loader = new Loader2();
+            }
+            catch (NoSuchMethodError e) {
+              loader = new Loader();
+            }
+            serviceClass = cls;
+            String resName = "META-INF/services/" + serviceClass.getName();
+            configFiles = loader.getResources(resName);
+          }
+
+          public Enumeration getProviders() {
+            return new ProviderEnumeration();
+          }
+
+          synchronized private boolean moreProviders() {
+            for (;;) {
+              while (classNames == null) {
+                if (!configFiles.hasMoreElements())
+                  return false;
+                classNames = parseConfigFile((URL)configFiles.nextElement());
+              }
+              while (classNames.hasMoreElements()) {
+                String className = (String)classNames.nextElement();
+                try {
+                  Class cls = loader.loadClass(className);
+                  Object obj = cls.newInstance();
+                  if (serviceClass.isInstance(obj)) {
+                    providers.addElement(obj);
+                    return true;
+                  }
+                }
+                catch (ClassNotFoundException e) { }
+                catch (InstantiationException e) { }
+                catch (IllegalAccessException e) { }
+                catch (LinkageError e) { }
+              }
+              classNames = null;
+            }
+          }
+
+          private static final int START = 0;
+          private static final int IN_NAME = 1;
+          private static final int IN_COMMENT = 2;
+
+          private static Enumeration parseConfigFile(URL url) {
+            try {
+              InputStream in = url.openStream();
+              Reader r;
+              try {
+                r = new InputStreamReader(in, "UTF-8");
+              }
+              catch (UnsupportedEncodingException e) {
+                r = new InputStreamReader(in, "UTF8");
+              }
+              r = new BufferedReader(r);
+              Vector tokens = new Vector();
+              StringBuffer tokenBuf = new StringBuffer();
+              int state = START;
+              for (;;) {
+                int n = r.read();
+                if (n < 0)
+                  break;
+                char c = (char)n;
+                switch (c) {
+                case '\r':
+                case '\n':
+                  state = START;
+                  break;
+                case ' ':
+                case '\t':
+                  break;
+                case '#':
+                  state = IN_COMMENT;
+                  break;
+                default:
+                  if (state != IN_COMMENT) {
+                    state = IN_NAME;
+                    tokenBuf.append(c);
+                  }
+                  break;
+                }
+                if (tokenBuf.length() != 0 && state != IN_NAME) {
+                  tokens.addElement(tokenBuf.toString());
+                  tokenBuf.setLength(0);
+                }
+              }
+              if (tokenBuf.length() != 0)
+                tokens.addElement(tokenBuf.toString());
+              return tokens.elements();
+            }
+            catch (IOException e) {
+              return null;
+            }
+          }
+        }
+
+}