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

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

/*
 * Copyright (C) 2005 by Quentin Anciaux
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Library General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This library 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 Library General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *	@author Quentin Anciaux
 */

package org.w3c.dom.bootstrap;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.DOMImplementationList;
import org.w3c.dom.DOMImplementationSource;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import java.security.AccessController;
import java.security.PrivilegedAction;

import java.util.StringTokenizer;
import java.util.Vector;


/**
 * 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; /** 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. } 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(); 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 * * @throws NullPointerException DOCUMENT ME! */ 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 = rd.readLine(); 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.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