simpleelementfactory.java
来自「java jdk 1.4的源码」· Java 代码 · 共 381 行
JAVA
381 行
/* * $Id: SimpleElementFactory.java,v 1.2 2001/04/20 00:52:21 edwingo Exp $ * * The Apache Software License, Version 1.1 * * * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. 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. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Crimson" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR * ITS 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, Sun Microsystems, Inc., * http://www.sun.com. For more information on the Apache Software * Foundation, please see <http://www.apache.org/>. */package org.apache.crimson.tree;import java.util.Dictionary;import java.util.Hashtable;import java.util.Locale;import org.w3c.dom.*;/** * This is a convenience class for creating application-specific elements * associated with specified (or default) XML namespaces. It maintains * tables mapping element tag names to classes, and uses them as needed * to instantiate classes. The string <em>*Element</em>, which is not a * legal XML element name, may be used to map otherwise unrecognized tags * to a particular class. If this factory is not configured, then all * mappings are to the <a href=ElementNode.html>ElementNode</a> class. * Erroneous mappings are fatal errors. * * <P> A suggested XML syntax for recording these bindings, which may * in the future be explicitly supported, is: <PRE> * <b><bindings xmlns="..."></b> * <!-- first, bindings for the "default" namespace --> * <b><binding tag="..." class="..."/></b> * <binding <b>tag="*Element"</b> class="..."/> * ... * * <!-- then bindings for other namespaces --> * <b><namespace uri="..."></b> * <binding tag="..." class="..."/> * ... * <b></namespace></b> * * <!-- can specify JAR files for namespaces --> * <namespace uri="..." <b>jar="..."</b>> * <binding tag="..." class="..."/> * ... * </namespace> * ... * <b></bindings></b> * </PRE> * * <P> Note that while most URIs used to identify namespaces will be URLs, * such as <em>http://www.example.com/xml/purchasing</em>, some may also * be URNs like <em>urn:uuid:221ffe10-ae3c-11d1-b66c-00805f8a2676</em>. * You can't assume that the URIs are associated with web-accessible data; * they must be treated as being no more than distinguishable strings. * * <P> Applications classes configuring an element factory will need to * provide their own class loader (<code>this.class.getClassLoader</code>) * to get the desired behavior in common cases. Classes loaded via some * URL will similarly need to use a network class loader. * * @author David Brownell * @version $Revision: 1.2 $ */public class SimpleElementFactory implements ElementFactory{ // in the absense of a mapping tied to namespace URI, use these private Dictionary defaultMapping; private ClassLoader defaultLoader; private String defaultNs; // these hold mappings tied to namespace URIs private Dictionary nsMappings; private Dictionary nsLoaders; private Locale locale = Locale.getDefault (); /** * Constructs an unconfigured element factory. */ public SimpleElementFactory () { } /** * Records a default element name to namespace mapping, for use * by namespace-unaware DOM construction and when a specific * namespace mapping is not available. * * @param dict Keys are element names, and values are either class * names (interpreted with respect to <em>loader</em>) or class * objects. This value may not be null, and the dictionary is * retained and modified by the factory. * @param loader If non-null, this is used instead of the bootstrap * class loader when mapping from class names to class objects. */ public void addMapping (Dictionary dict, ClassLoader loader) { if (dict == null) throw new IllegalArgumentException (); defaultMapping = dict; defaultLoader = loader; } /** * Records a namespace-specific mapping between element names and * classes. * * @param namespace A URI identifying the namespace for which the * mapping is defined * @param dict Keys are element names, and values are either class * names (interpreted with respect to <em>loader</em>) or class * objects. This value may not be null, and the dictionary is * retained and modified by the factory. * @param loader If non-null, this is used instead of the bootstrap * class loader when mapping from class names to class objects. */ public void addMapping ( String namespace, Dictionary dict, ClassLoader loader ) { if (namespace == null || dict == null) throw new IllegalArgumentException (); if (nsMappings == null) { nsMappings = new Hashtable (); nsLoaders = new Hashtable (); } nsMappings.put (namespace, dict); if (loader != null) nsLoaders.put (namespace, loader); } /** * Defines a URI to be treated as the "default" namespace. This * is used only when choosing element classes, and may not be * visible when instances are asked for their namespaces. */ public void setDefaultNamespace (String ns) { defaultNs = ns; } private Class map2Class ( String key, Dictionary node2class, ClassLoader loader ) { Object mapResult = node2class.get (key); if (mapResult instanceof Class) return (Class) mapResult; if (mapResult == null) return null; if (mapResult instanceof String) { String className = (String) mapResult; Class retval; try { if (loader == null) { // Find the appropriate ClassLoader to use depending on // if we are part of the JDK or not and taking JDK // version into account. loader = findClassLoader(); } if (loader == null) retval = Class.forName (className); else retval = loader.loadClass (className); // // We really have no option here. DOM requires two // bidirectional relationships (parent/child, and // between siblings) and one unidirectional one (nodes // belong to one document) but doesn't provide APIs that // would suffice to maintain them. So those APIs // must rely on knowledge of the implementation to // which things are connecting. // if (!ElementNode.class.isAssignableFrom (retval)) throw new IllegalArgumentException (getMessage ("SEF-000", new Object [] { key, className })); node2class.put (key, retval); return retval; } catch (ClassNotFoundException e) { throw new IllegalArgumentException (getMessage ("SEF-001", new Object [] { key, className, e.getMessage ()})); } } // another option: clone elements, resetting parent // and document associations? throw new IllegalArgumentException (getMessage ("SEF-002", new Object [] { key })); } private ElementNode doMap ( String tagName, Dictionary node2class, ClassLoader loader ) { Class theClass; ElementNode retval; theClass = map2Class (tagName, node2class, loader); if (theClass == null) theClass = map2Class ("*Element", node2class, loader); if (theClass == null) retval = new ElementNode (tagName); else { try { retval = (ElementNode) theClass.newInstance (); } catch (Exception e) { //InstantiationException //IllegalAccessException throw new IllegalArgumentException (getMessage ("SEF-003", new Object [] {tagName, theClass.getName (), e.getMessage () })); } } return retval; } /** * Creates an element by using the mapping associated with the * specified namespace, or the default namespace as appropriate. * If no mapping associated with that namespace is defined, then * the default mapping is used. * * @param namespace URI for namespace; null indicates use of * the default namespace, if any. * @param localName element tag, without any embedded colon */ public ElementEx createElementEx (String namespace, String localName) { Dictionary mapping = null; if (namespace == null) namespace = defaultNs; if (nsMappings != null) mapping = (Dictionary) nsMappings.get (namespace); if (mapping == null) return doMap (localName, defaultMapping, defaultLoader); else return doMap (localName, mapping, (ClassLoader)nsLoaders.get (namespace)); } /** * Creates an element by using the default mapping. * * @param tag element tag */ public ElementEx createElementEx (String tag) { return doMap (tag, defaultMapping, defaultLoader); } /* * Gets the messages from the resource bundles for the given messageId. */ String getMessage (String messageId) { return getMessage (messageId, null); } /* * Gets the messages from the resource bundles for the given messageId * after formatting it with the parameters passed to it. */ //XXX use the default locale only at this point. String getMessage (String messageId, Object[] parameters) { return XmlDocument.catalog.getMessage (locale, messageId, parameters); } /* * The following section of code tries to get our ContextClassLoader, * if we are running in Java 2. This code is derived from * javax.xml.parsers.FactoryFinder. */ /** * Figure out which ClassLoader to use. For JDK 1.2 and later use the * context ClassLoader if possible. Note: we defer linking the class * that calls an API only in JDK 1.2 until runtime so that we can catch * LinkageError so that this code will run in older non-Sun JVMs such * as the Microsoft JVM in IE. */ private static ClassLoader findClassLoader() { ClassLoader classLoader; try { // Construct the name of the concrete class to instantiate Class clazz = Class.forName(SimpleElementFactory.class.getName() + "$ClassLoaderFinderConcrete"); ClassLoaderFinder clf = (ClassLoaderFinder) clazz.newInstance(); classLoader = clf.getContextClassLoader(); } catch (LinkageError le) { // Assume that we are running JDK 1.1, use the current ClassLoader classLoader = SimpleElementFactory.class.getClassLoader(); } catch (ClassNotFoundException x) { // This case should not normally happen. MS IE can throw this // instead of a LinkageError the second time Class.forName() is // called so assume that we are running JDK 1.1 and use the // current ClassLoader classLoader = SimpleElementFactory.class.getClassLoader(); } catch (Exception x) { // Something abnormal happened so just use current ClassLoader classLoader = SimpleElementFactory.class.getClassLoader(); } return classLoader; } /* * The following nested classes allow getContextClassLoader() to be * called only on JDK 1.2 and yet run in older JDK 1.1 JVMs */ private static abstract class ClassLoaderFinder { abstract ClassLoader getContextClassLoader(); } static class ClassLoaderFinderConcrete extends ClassLoaderFinder { ClassLoader getContextClassLoader() { return Thread.currentThread().getContextClassLoader(); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?