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