All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.w3c.dom.bootstrap.DOMImplementationRegistry Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2004 World Wide Web Consortium,
 *
 * (Massachusetts Institute of Technology, European Research Consortium for
 * Informatics and Mathematics, Keio University). All Rights Reserved. This
 * work is distributed under the W3C(r) Software License [1] 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.
 *
 * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
 */


package org.w3c.dom.bootstrap;

import java.util.StringTokenizer;
import java.util.Vector;
import org.w3c.dom.DOMImplementationSource;
import org.w3c.dom.DOMImplementationList;
import org.w3c.dom.DOMImplementation;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.PrivilegedAction;

/**
 * A factory that enables applications to obtain instances of
 * DOMImplementation.
 *
 * 

* Example: *

* *
 *  // get an instance of the DOMImplementation registry
 *  DOMImplementationRegistry registry =
 *       DOMImplementationRegistry.newInstance();
 *  // get a DOM implementation the Level 3 XML module
 *  DOMImplementation domImpl =
 *       registry.getDOMImplementation("XML 3.0");
 * 
* *

* This provides an application with an implementation-independent starting * point. DOM implementations may modify this class to meet new security * standards or to provide *additional* fallbacks for the list of * DOMImplementationSources. *

* * @see DOMImplementation * @see DOMImplementationSource * @since DOM Level 3 */ public final class DOMImplementationRegistry { /** * The system property to specify the * DOMImplementationSource class names. */ public static final String PROPERTY = "org.w3c.dom.DOMImplementationSourceList"; /** * Default columns per line. */ private static final int DEFAULT_LINE_LENGTH = 80; /** * Default DOMImplementationSource. */ private static final String DEFAULT_DOM_IMPLEMENTATION_SOURCE = "org.apache.xerces.dom.DOMXSImplementationSourceImpl"; /** * The list of DOMImplementationSources. */ private Vector sources; /** * Private constructor. * @param srcs Vector List of DOMImplementationSources */ private DOMImplementationRegistry(final Vector srcs) { sources = srcs; } /** * Obtain a new instance of a DOMImplementationRegistry. * * The DOMImplementationRegistry is initialized by the * application or the implementation, depending on the context, by * first checking the value of the Java system property * org.w3c.dom.DOMImplementationSourceList and * the the service provider whose contents are at * "META-INF/services/org.w3c.dom.DOMImplementationSourceList" * The value of this property is a white-space separated list of * names of availables classes implementing the * DOMImplementationSource interface. Each class listed * in the class name list is instantiated and any exceptions * encountered are thrown to the application. * * @return an initialized instance of DOMImplementationRegistry * @throws ClassNotFoundException * If any specified class can not be found * @throws InstantiationException * If any specified class is an interface or abstract class * @throws IllegalAccessException * If the default constructor of a specified class is not accessible * @throws ClassCastException * If any specified class does not implement * DOMImplementationSource */ public static DOMImplementationRegistry newInstance() throws ClassNotFoundException, InstantiationException, IllegalAccessException, ClassCastException { Vector sources = new Vector(); ClassLoader classLoader = getClassLoader(); // fetch system property: String p = getSystemProperty(PROPERTY); // // if property is not specified then use contents of // META-INF/org.w3c.dom.DOMImplementationSourceList from classpath if (p == null) { p = getServiceValue(classLoader); } if (p == null) { // // DOM Implementations can modify here to add *additional* fallback // mechanisms to access a list of default DOMImplementationSources. p = DEFAULT_DOM_IMPLEMENTATION_SOURCE; } if (p != null) { StringTokenizer st = new StringTokenizer(p); while (st.hasMoreTokens()) { String sourceName = st.nextToken(); // Use context class loader, falling back to Class.forName // if and only if this fails... Class sourceClass = null; if (classLoader != null) { sourceClass = classLoader.loadClass(sourceName); } else { sourceClass = Class.forName(sourceName); } DOMImplementationSource source = (DOMImplementationSource) sourceClass.newInstance(); sources.addElement(source); } } return new DOMImplementationRegistry(sources); } /** * Return the first implementation that has the desired * features, or null if none is found. * * @param features * A string that specifies which features are required. This is * a space separated list in which each feature is specified by * its name optionally followed by a space and a version number. * This is something like: "XML 1.0 Traversal +Events 2.0" * @return An implementation that has the desired features, * or null if none found. */ public DOMImplementation getDOMImplementation(final String features) { int size = sources.size(); String name = null; for (int i = 0; i < size; i++) { DOMImplementationSource source = (DOMImplementationSource) sources.elementAt(i); DOMImplementation impl = source.getDOMImplementation(features); if (impl != null) { return impl; } } return null; } /** * Return a list of implementations that support the * desired features. * * @param features * A string that specifies which features are required. This is * a space separated list in which each feature is specified by * its name optionally followed by a space and a version number. * This is something like: "XML 1.0 Traversal +Events 2.0" * @return A list of DOMImplementations that support the desired features. */ public DOMImplementationList getDOMImplementationList(final String features) { final Vector implementations = new Vector(); int size = sources.size(); for (int i = 0; i < size; i++) { DOMImplementationSource source = (DOMImplementationSource) sources.elementAt(i); DOMImplementationList impls = source.getDOMImplementationList(features); for (int j = 0; j < impls.getLength(); j++) { DOMImplementation impl = impls.item(j); implementations.addElement(impl); } } return new DOMImplementationList() { public DOMImplementation item(final int index) { if (index >= 0 && index < implementations.size()) { try { return (DOMImplementation) implementations.elementAt(index); } catch (ArrayIndexOutOfBoundsException e) { return null; } } return null; } public int getLength() { return implementations.size(); } }; } /** * Register an implementation. * * @param s The source to be registered, may not be null */ public void addSource(final DOMImplementationSource s) { if (s == null) { throw new NullPointerException(); } if (!sources.contains(s)) { sources.addElement(s); } } /** * * Gets a class loader. * * @return A class loader, possibly null */ private static ClassLoader getClassLoader() { try { ClassLoader contextClassLoader = getContextClassLoader(); if (contextClassLoader != null) { return contextClassLoader; } } catch (Exception e) { // Assume that the DOM application is in a JRE 1.1, use the // current ClassLoader return DOMImplementationRegistry.class.getClassLoader(); } return DOMImplementationRegistry.class.getClassLoader(); } /** * This method attempts to return the first line of the resource * META-INF/services/org.w3c.dom.DOMImplementationSourceList * from the provided ClassLoader. * * @param classLoader classLoader, may not be null. * @return first line of resource, or null */ private static String getServiceValue(final ClassLoader classLoader) { String serviceId = "META-INF/services/" + PROPERTY; // try to find services in CLASSPATH try { InputStream is = getResourceAsStream(classLoader, serviceId); if (is != null) { BufferedReader rd; try { rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH); } catch (java.io.UnsupportedEncodingException e) { rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH); } String serviceValue = null; try { serviceValue = rd.readLine(); } finally { rd.close(); } if (serviceValue != null && serviceValue.length() > 0) { return serviceValue; } } } catch (Exception ex) { return null; } return null; } /** * A simple JRE (Java Runtime Environment) 1.1 test * * @return true if JRE 1.1 */ private static boolean isJRE11() { try { Class c = Class.forName("java.security.AccessController"); // java.security.AccessController existed since 1.2 so, if no // exception was thrown, the DOM application is running in a JRE // 1.2 or higher return false; } catch (Exception ex) { // ignore } return true; } /** * This method returns the ContextClassLoader or null if * running in a JRE 1.1 * * @return The Context Classloader */ private static ClassLoader getContextClassLoader() { return isJRE11() ? null : (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { ClassLoader classLoader = null; try { classLoader = Thread.currentThread().getContextClassLoader(); } catch (SecurityException ex) { } return classLoader; } }); } /** * This method returns the system property indicated by the specified name * after checking access control privileges. For a JRE 1.1, this check is * not done. * * @param name the name of the system property * @return the system property */ private static String getSystemProperty(final String name) { return isJRE11() ? (String) System.getProperty(name) : (String) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return System.getProperty(name); } }); } /** * This method returns an Inputstream for the reading resource * META-INF/services/org.w3c.dom.DOMImplementationSourceList after checking * access control privileges. For a JRE 1.1, this check is not done. * * @param classLoader classLoader * @param name the resource * @return an Inputstream for the resource specified */ private static InputStream getResourceAsStream(final ClassLoader classLoader, final String name) { if (isJRE11()) { InputStream ris; if (classLoader == null) { ris = ClassLoader.getSystemResourceAsStream(name); } else { ris = classLoader.getResourceAsStream(name); } return ris; } else { return (InputStream) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { InputStream ris; if (classLoader == null) { ris = ClassLoader.getSystemResourceAsStream(name); } else { ris = classLoader.getResourceAsStream(name); } return ris; } }); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy