Home | History | Annotate | Download | only in domts
      1 /*
      2  * Copyright (c) 2001-2004 World Wide Web Consortium,
      3  * (Massachusetts Institute of Technology, Institut National de
      4  * Recherche en Informatique et en Automatique, Keio University). All
      5  * Rights Reserved. This program is distributed under the W3C's Software
      6  * Intellectual Property License. This program is distributed in the
      7  * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
      8  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
      9  * PURPOSE.
     10  * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
     11  */
     12 
     13 package org.w3c.domts;
     14 
     15 import java.lang.reflect.Method;
     16 import java.util.ArrayList;
     17 import java.util.List;
     18 
     19 import org.w3c.dom.DOMImplementation;
     20 import org.w3c.dom.Document;
     21 
     22 /**
     23  * This class represents a particular parser and configuration
     24  * (such as entity-expanding, non-validating, whitespace ignoring)
     25  * for a test session.  Individual tests or suites within a
     26  * session can override the session properties on a call to
     27  * createBuilderFactory.
     28  *
     29  * @author Curt Arnold
     30  */
     31 public abstract class DOMTestDocumentBuilderFactory {
     32   /**
     33    *   Parser configuration
     34    */
     35   private final DocumentBuilderSetting[] settings;
     36 
     37   /**
     38    *   Constructor
     39    *   @param properties Array of parser settings, may be null.
     40    */
     41   public DOMTestDocumentBuilderFactory(DocumentBuilderSetting[] settings) throws
     42       DOMTestIncompatibleException {
     43     if (settings == null) {
     44       this.settings = new DocumentBuilderSetting[0];
     45     }
     46     else {
     47       this.settings = (DocumentBuilderSetting[]) settings.clone();
     48     }
     49   }
     50 
     51   /**
     52    *   Returns an instance of DOMTestDocumentBuilderFactory
     53    *   with the settings from the argument list
     54    *   and any non-revoked settings from the current object.
     55    *   @param settings array of settings, may be null.
     56    */
     57   public abstract DOMTestDocumentBuilderFactory newInstance(
     58       DocumentBuilderSetting[] settings) throws DOMTestIncompatibleException;
     59 
     60   public abstract DOMImplementation getDOMImplementation();
     61 
     62   public abstract boolean hasFeature(String feature, String version);
     63 
     64   public abstract Document load(java.net.URL url) throws DOMTestLoadException;
     65 
     66   /**
     67    *  Creates XPath evaluator
     68    *  @param doc DOM document, may not be null
     69    */
     70   public Object createXPathEvaluator(Document doc) {
     71     try {
     72       Method getFeatureMethod = doc.getClass().getMethod("getFeature",
     73           new Class[] {String.class, String.class});
     74       if (getFeatureMethod != null) {
     75         return getFeatureMethod.invoke(doc, new Object[] {"XPath", null});
     76       }
     77     }
     78     catch (Exception ex) {
     79     }
     80     return doc;
     81   }
     82 
     83   /**
     84    *   Merges the settings from the specific test case or suite
     85    *   with the existing (typically session) settings.
     86    *   @param settings new settings, may be null which will
     87    *   return clone of existing settings.
     88    */
     89   protected DocumentBuilderSetting[] mergeSettings(DocumentBuilderSetting[]
     90       newSettings) {
     91     if (newSettings == null) {
     92       return (DocumentBuilderSetting[]) settings.clone();
     93     }
     94     List mergedSettings = new ArrayList(settings.length + newSettings.length);
     95     //
     96     //    all new settings are respected
     97     //
     98     for (int i = 0; i < newSettings.length; i++) {
     99       mergedSettings.add(newSettings[i]);
    100     }
    101     //
    102     //    for all previous settings, take only those that
    103     //       do not conflict with existing settings
    104     for (int i = 0; i < settings.length; i++) {
    105       DocumentBuilderSetting setting = settings[i];
    106       boolean hasConflict = false;
    107       for (int j = 0; j < newSettings.length; j++) {
    108         DocumentBuilderSetting newSetting = newSettings[j];
    109         if (newSetting.hasConflict(setting) || setting.hasConflict(newSetting)) {
    110           hasConflict = true;
    111           break;
    112         }
    113       }
    114       if (!hasConflict) {
    115         mergedSettings.add(setting);
    116       }
    117     }
    118 
    119     DocumentBuilderSetting[] mergedArray =
    120         new DocumentBuilderSetting[mergedSettings.size()];
    121     for (int i = 0; i < mergedSettings.size(); i++) {
    122       mergedArray[i] = (DocumentBuilderSetting) mergedSettings.get(i);
    123     }
    124     return mergedArray;
    125   }
    126 
    127   public String addExtension(String testFileName) {
    128     String contentType = getContentType();
    129     if ("text/html".equals(contentType)) {
    130       return testFileName + ".html";
    131     }
    132     if ("image/svg+xml".equals(contentType)) {
    133       return testFileName + ".svg";
    134     }
    135     if ("application/xhtml+xml".equals(contentType)) {
    136       return testFileName + ".xhtml";
    137     }
    138     return testFileName + ".xml";
    139   }
    140 
    141   public abstract boolean isCoalescing();
    142 
    143   public abstract boolean isExpandEntityReferences();
    144 
    145   public abstract boolean isIgnoringElementContentWhitespace();
    146 
    147   public abstract boolean isNamespaceAware();
    148 
    149   public abstract boolean isValidating();
    150 
    151   public String getContentType() {
    152     return System.getProperty("org.w3c.domts.contentType", "text/xml");
    153   }
    154 
    155   /**
    156    * Creates an array of all determinable settings for the DocumentBuilder
    157    * including those at implementation defaults.
    158    * @param builder must not be null
    159    */
    160   public final DocumentBuilderSetting[] getActualSettings() {
    161 
    162     DocumentBuilderSetting[] allSettings = new DocumentBuilderSetting[] {
    163         DocumentBuilderSetting.coalescing,
    164         DocumentBuilderSetting.expandEntityReferences,
    165         DocumentBuilderSetting.hasNullString,
    166         DocumentBuilderSetting.ignoringElementContentWhitespace,
    167         DocumentBuilderSetting.namespaceAware,
    168         DocumentBuilderSetting.signed,
    169         DocumentBuilderSetting.validating,
    170         DocumentBuilderSetting.notCoalescing,
    171         DocumentBuilderSetting.notExpandEntityReferences,
    172         DocumentBuilderSetting.notHasNullString,
    173         DocumentBuilderSetting.notIgnoringElementContentWhitespace,
    174         DocumentBuilderSetting.notNamespaceAware,
    175         DocumentBuilderSetting.notSigned,
    176         DocumentBuilderSetting.notValidating
    177     };
    178 
    179     List list = new ArrayList(allSettings.length / 2);
    180     for (int i = 0; i < allSettings.length; i++) {
    181       if (allSettings[i].hasSetting(this)) {
    182         list.add(allSettings[i]);
    183       }
    184     }
    185     DocumentBuilderSetting[] settings = new DocumentBuilderSetting[list.size()];
    186     for (int i = 0; i < settings.length; i++) {
    187       settings[i] = (DocumentBuilderSetting) list.get(i);
    188     }
    189     return settings;
    190   }
    191 
    192 }
    193