summaryrefslogtreecommitdiffstats
path: root/dom/src/test/java/org/w3c/domts/LSDocumentBuilderFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'dom/src/test/java/org/w3c/domts/LSDocumentBuilderFactory.java')
-rw-r--r--dom/src/test/java/org/w3c/domts/LSDocumentBuilderFactory.java414
1 files changed, 414 insertions, 0 deletions
diff --git a/dom/src/test/java/org/w3c/domts/LSDocumentBuilderFactory.java b/dom/src/test/java/org/w3c/domts/LSDocumentBuilderFactory.java
new file mode 100644
index 0000000..7ed0f54
--- /dev/null
+++ b/dom/src/test/java/org/w3c/domts/LSDocumentBuilderFactory.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2001-2004 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.domts;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+
+/**
+ * This class implements the generic parser and configuation
+ * abstract class for the DOM L3 implementations
+ *
+ * @author Curt Arnold
+ */
+public class LSDocumentBuilderFactory
+ extends DOMTestDocumentBuilderFactory {
+
+ private final Object parser;
+ private final Method parseURIMethod;
+ private final DOMImplementation impl;
+
+ /**
+ *
+ * Abstract class for a strategy to map a DocumentBuilderSetting
+ * to an action on LSParser.
+ */
+ private static abstract class LSStrategy {
+
+ /**
+ * Constructor.
+ */
+ protected LSStrategy() {
+ }
+
+ /**
+ * Applies setting to LSParser
+ *
+ * @param setting setting
+ * @param parser parser
+ * @throws DOMTestIncompatibleException if parser does not support setting
+ */
+ public abstract void applySetting(DocumentBuilderSetting setting,
+ Object parser) throws
+ DOMTestIncompatibleException;
+
+ /**
+ * Gets state of setting for parser
+ *
+ * @param parser parser
+ * @return state of setting
+ */
+ public abstract boolean hasSetting(Object parser);
+
+ }
+
+ /**
+ * Represents a fixed setting, for example, all Java implementations
+ * supported signed values.
+ *
+ */
+ private static class LSFixedStrategy
+ extends LSStrategy {
+ private final boolean fixedValue;
+
+ /**
+ * Constructor
+ *
+ * @param settingName setting name
+ * @param fixedValue fixed value
+ */
+ public LSFixedStrategy(boolean fixedValue) {
+ this.fixedValue = fixedValue;
+ }
+
+ /**
+ * Apply setting. Throws exception if requested setting
+ * does not match fixed value.
+ */
+ public void applySetting(DocumentBuilderSetting setting, Object parser) throws
+ DOMTestIncompatibleException {
+ if (setting.getValue() != fixedValue) {
+ throw new DOMTestIncompatibleException(null, setting);
+ }
+ }
+
+ /**
+ * Gets fixed value for setting
+ */
+ public boolean hasSetting(Object parser) {
+ return fixedValue;
+ }
+ }
+
+ /**
+ * A strategy for a setting that can be applied by setting a DOMConfiguration
+ * parameter.
+ *
+ */
+ private static class LSParameterStrategy
+ extends LSStrategy {
+ private final String lsParameter;
+ private final boolean inverse;
+
+ /**
+ * Constructor
+ *
+ * @param lsParameter corresponding DOMConfiguration parameter
+ * @param inverse if true, DOMConfiguration value is the inverse
+ * of the setting value
+ */
+ public LSParameterStrategy(String lsParameter, boolean inverse) {
+ this.lsParameter = lsParameter;
+ this.inverse = inverse;
+ }
+
+ protected static void setParameter(DocumentBuilderSetting setting,
+ Object parser,
+ String parameter,
+ Object value) throws
+ DOMTestIncompatibleException {
+ try {
+ Method domConfigMethod = parser.getClass().getMethod("getDomConfig",
+ new Class[0]);
+ Object domConfig = domConfigMethod.invoke(parser, new Object[0]);
+ Method setParameterMethod = domConfig.getClass().getMethod(
+ "setParameter", new Class[] {String.class, Object.class});
+ setParameterMethod.invoke(domConfig, new Object[] {parameter, value});
+
+ }
+ catch (InvocationTargetException ex) {
+ throw new DOMTestIncompatibleException(ex.getTargetException(), setting);
+ }
+ catch (Exception ex) {
+ throw new DOMTestIncompatibleException(ex, setting);
+ }
+ }
+
+ protected static Object getParameter(Object parser,
+ String parameter) throws Exception {
+ Method domConfigMethod = parser.getClass().getMethod("getDomConfig",
+ new Class[0]);
+ Object domConfig = domConfigMethod.invoke(parser, new Object[0]);
+ Method getParameterMethod = domConfig.getClass().getMethod("getParameter",
+ new Class[] {String.class});
+ return getParameterMethod.invoke(domConfig, new Object[] {parameter});
+ }
+
+ /**
+ * Apply setting
+ */
+ public void applySetting(DocumentBuilderSetting setting, Object parser) throws
+ DOMTestIncompatibleException {
+ if (inverse) {
+ setParameter(setting, parser, lsParameter,
+ new Boolean(!setting.getValue()));
+ }
+ else {
+ setParameter(setting, parser, lsParameter, new Boolean(setting.getValue()));
+ }
+ }
+
+ /**
+ * Get value of setting
+ */
+ public boolean hasSetting(Object parser) {
+ try {
+ if (inverse) {
+ return! ( (Boolean) getParameter(parser, lsParameter)).booleanValue();
+ }
+ else {
+ return ( (Boolean) getParameter(parser, lsParameter)).booleanValue();
+ }
+ }
+ catch (Exception ex) {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * A strategy for the validation settings which require
+ * two DOMConfigurure parameters being set, 'validate' and 'schema-type'
+ *
+ */
+ private static class LSValidateStrategy
+ extends LSParameterStrategy {
+ private final String schemaType;
+
+ /**
+ * Constructor
+ * @param schemaType schema type
+ */
+ public LSValidateStrategy(String schemaType) {
+ super("validate", false);
+ this.schemaType = schemaType;
+ }
+
+ /**
+ * Apply setting
+ */
+ public void applySetting(DocumentBuilderSetting setting, Object parser) throws
+ DOMTestIncompatibleException {
+ super.applySetting(setting, parser);
+ setParameter(null, parser, "schema-type", schemaType);
+ }
+
+ /**
+ * Get setting value
+ */
+ public boolean hasSetting(Object parser) {
+ if (super.hasSetting(parser)) {
+ try {
+ String parserSchemaType = (String) getParameter(parser, "schema-type");
+ if (schemaType == null || schemaType.equals(parserSchemaType)) {
+ return true;
+ }
+ }
+ catch (Exception ex) {
+ }
+ }
+ return false;
+ }
+
+ }
+
+ /**
+ * Strategies for mapping DocumentBuilderSettings to
+ * actions on LSParser
+ */
+ private static final Map strategies;
+
+ static {
+ strategies = new HashMap();
+ strategies.put("coalescing", new LSParameterStrategy("cdata-sections", true));
+ strategies.put("expandEntityReferences", new LSParameterStrategy("entities", true));
+ strategies.put("ignoringElementContentWhitespace",
+ new LSParameterStrategy("element-content-whitespace", true));
+ strategies.put("namespaceAware", new LSParameterStrategy("namespaces", false));
+ strategies.put("validating",
+ new LSValidateStrategy("http://www.w3.org/TR/REC-xml"));
+ strategies.put("schemaValidating",
+ new LSValidateStrategy("http://www.w3.org/2001/XMLSchema"));
+ strategies.put("ignoringComments", new LSParameterStrategy("comments", true));
+ strategies.put("signed", new LSFixedStrategy(true));
+ strategies.put("hasNullString", new LSFixedStrategy(true));
+ }
+
+ /**
+ * Creates a LS implementation of DOMTestDocumentBuilderFactory.
+ * @param settings array of settings, may be null.
+ * @throws DOMTestIncompatibleException
+ * Thrown if implementation does not support the specified settings
+ */
+ public LSDocumentBuilderFactory(DocumentBuilderSetting[] settings) throws
+ DOMTestIncompatibleException {
+ super(settings);
+
+ try {
+ Class domImplRegistryClass = Class.forName(
+ "org.w3c.dom.bootstrap.DOMImplementationRegistry");
+ Method newInstanceMethod = domImplRegistryClass.getMethod("newInstance", null);
+ Object domRegistry = newInstanceMethod.invoke(null, null);
+ Method getDOMImplementationMethod = domImplRegistryClass.getMethod(
+ "getDOMImplementation", new Class[] {String.class});
+ impl = (DOMImplementation) getDOMImplementationMethod.invoke(domRegistry,
+ new Object[] {"LS"});
+ Method createLSParserMethod = impl.getClass().getMethod("createLSParser",
+ new Class[] {short.class, String.class});
+ parser = createLSParserMethod.invoke(impl,
+ new Object[] {new Short( (short) 1), null});
+ parseURIMethod = parser.getClass().getMethod("parseURI",
+ new Class[] {String.class});
+ }
+ catch (InvocationTargetException ex) {
+ throw new DOMTestIncompatibleException(ex.getTargetException(), null);
+ }
+ catch (Exception ex) {
+ throw new DOMTestIncompatibleException(ex, null);
+ }
+
+ if (settings != null) {
+ for (int i = 0; i < settings.length; i++) {
+ Object strategy = strategies.get(settings[i].getProperty());
+ if (strategy == null) {
+ throw new DOMTestIncompatibleException(null, settings[i]);
+ }
+ else {
+ ( (LSStrategy) strategy).applySetting(settings[i], parser);
+ }
+ }
+ }
+ }
+
+ /**
+ * Create new instance of document builder factory
+ * reflecting specified settings
+ * @param newSettings new settings
+ * @return New instance
+ * @throws DOMTestIncompatibleException
+ * if settings are not supported by implementation
+ */
+ public DOMTestDocumentBuilderFactory newInstance(
+ DocumentBuilderSetting[] newSettings) throws DOMTestIncompatibleException {
+ if (newSettings == null) {
+ return this;
+ }
+ DocumentBuilderSetting[] mergedSettings = mergeSettings(newSettings);
+ return new LSDocumentBuilderFactory(mergedSettings);
+ }
+
+ /**
+ * Loads specified URL
+ * @param url url to load
+ * @return DOM document
+ * @throws DOMTestLoadException if unable to load document
+ */
+ public Document load(java.net.URL url) throws DOMTestLoadException {
+ try {
+ return (Document) parseURIMethod.invoke(parser,
+ new Object[] {url.toString()});
+ }
+ catch (InvocationTargetException ex) {
+ throw new DOMTestLoadException(ex.getTargetException());
+ }
+ catch (Exception ex) {
+ throw new DOMTestLoadException(ex);
+ }
+ }
+
+ /**
+ * Gets DOMImplementation
+ * @return DOM implementation, may be null
+ */
+ public DOMImplementation getDOMImplementation() {
+ return impl;
+ }
+
+ /**
+ * Determines if the implementation supports the specified feature
+ * @param feature Feature
+ * @param version Version
+ * @return true if implementation supports the feature
+ */
+ public boolean hasFeature(String feature, String version) {
+ return getDOMImplementation().hasFeature(feature, version);
+ }
+
+ private boolean hasProperty(String parameter) {
+ try {
+ return ( (Boolean) LSParameterStrategy.getParameter(parser, parameter)).
+ booleanValue();
+ }
+ catch (Exception ex) {
+ return true;
+ }
+
+ }
+
+ /**
+ * Indicates whether the implementation combines text and cdata nodes.
+ * @return true if coalescing
+ */
+ public boolean isCoalescing() {
+ return!hasProperty("cdata-sections");
+ }
+
+ /**
+ * Indicates whether the implementation expands entity references.
+ * @return true if expanding entity references
+ */
+ public boolean isExpandEntityReferences() {
+ return!hasProperty("entities");
+ }
+
+ /**
+ * Indicates whether the implementation ignores
+ * element content whitespace.
+ * @return true if ignoring element content whitespace
+ */
+ public boolean isIgnoringElementContentWhitespace() {
+ return!hasProperty("element-content-whitespace");
+ }
+
+ /**
+ * Indicates whether the implementation is namespace aware.
+ * @return true if namespace aware
+ */
+ public boolean isNamespaceAware() {
+ return hasProperty("namespaces");
+ }
+
+ /**
+ * Indicates whether the implementation is validating.
+ * @return true if validating
+ */
+ public boolean isValidating() {
+ return hasProperty("validate");
+ }
+
+}