2 * Copyright (C) 2010 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.apache.harmony.xml.dom;
19 import org.w3c.dom.DOMConfiguration;
20 import org.w3c.dom.DOMErrorHandler;
21 import org.w3c.dom.DOMException;
22 import org.w3c.dom.DOMStringList;
25 import java.util.TreeMap;
28 * A minimal implementation of DOMConfiguration. This implementation uses inner
29 * parameter instances to centralize each parameter's behaviour.
31 public final class DOMConfigurationImpl implements DOMConfiguration {
33 private static final Map<String, Parameter> PARAMETERS
34 = new TreeMap<String, Parameter>(String.CASE_INSENSITIVE_ORDER);
38 * True to canonicalize the document (unsupported). This includes
39 * removing DocumentType nodes from the tree and removing unused
40 * namespace declarations. Setting this to true also sets these
43 * normalize-characters = false
44 * cdata-sections = false
46 * namespace-declarations = true
48 * element-content-whitespace = true
49 * Setting these parameters to another value shall revert the canonical
52 PARAMETERS.put("canonical-form", new FixedParameter(false));
55 * True to keep existing CDATA nodes; false to replace them/merge them
56 * into adjacent text nodes.
58 PARAMETERS.put("cdata-sections", new BooleanParameter() {
59 public Object get(DOMConfigurationImpl config) {
60 return config.cdataSections;
62 public void set(DOMConfigurationImpl config, Object value) {
63 config.cdataSections = (Boolean) value;
68 * True to check character normalization (unsupported).
70 PARAMETERS.put("check-character-normalization", new FixedParameter(false));
73 * True to keep comments in the document; false to discard them.
75 PARAMETERS.put("comments", new BooleanParameter() {
76 public Object get(DOMConfigurationImpl config) {
77 return config.comments;
79 public void set(DOMConfigurationImpl config, Object value) {
80 config.comments = (Boolean) value;
85 * True to expose schema normalized values. Setting this to true sets
86 * the validate parameter to true. Has no effect when validate is false.
88 PARAMETERS.put("datatype-normalization", new BooleanParameter() {
89 public Object get(DOMConfigurationImpl config) {
90 return config.datatypeNormalization;
92 public void set(DOMConfigurationImpl config, Object value) {
93 if ((Boolean) value) {
94 config.datatypeNormalization = true;
95 config.validate = true;
97 config.datatypeNormalization = false;
103 * True to keep whitespace elements in the document; false to discard
104 * them (unsupported).
106 PARAMETERS.put("element-content-whitespace", new FixedParameter(true));
109 * True to keep entity references in the document; false to expand them.
111 PARAMETERS.put("entities", new BooleanParameter() {
112 public Object get(DOMConfigurationImpl config) {
113 return config.entities;
115 public void set(DOMConfigurationImpl config, Object value) {
116 config.entities = (Boolean) value;
121 * Handler to be invoked when errors are encountered.
123 PARAMETERS.put("error-handler", new Parameter() {
124 public Object get(DOMConfigurationImpl config) {
125 return config.errorHandler;
127 public void set(DOMConfigurationImpl config, Object value) {
128 config.errorHandler = (DOMErrorHandler) value;
130 public boolean canSet(DOMConfigurationImpl config, Object value) {
131 return value == null || value instanceof DOMErrorHandler;
136 * Bulk alias to set the following parameter values:
137 * validate-if-schema = false
139 * datatype-normalization = false
140 * cdata-sections = false
141 * namespace-declarations = true
143 * element-content-whitespace = true
146 * Querying this returns true if all of the above parameters have the
147 * listed values; false otherwise.
149 PARAMETERS.put("infoset", new BooleanParameter() {
150 public Object get(DOMConfigurationImpl config) {
151 // validate-if-schema is always false
152 // element-content-whitespace is always true
153 // namespace-declarations is always true
154 return !config.entities
155 && !config.datatypeNormalization
156 && !config.cdataSections
159 && config.namespaces;
161 public void set(DOMConfigurationImpl config, Object value) {
162 if ((Boolean) value) {
163 // validate-if-schema is always false
164 // element-content-whitespace is always true
165 // namespace-declarations is always true
166 config.entities = false;
167 config.datatypeNormalization = false;
168 config.cdataSections = false;
169 config.wellFormed = true;
170 config.comments = true;
171 config.namespaces = true;
177 * True to perform namespace processing; false for none.
179 PARAMETERS.put("namespaces", new BooleanParameter() {
180 public Object get(DOMConfigurationImpl config) {
181 return config.namespaces;
183 public void set(DOMConfigurationImpl config, Object value) {
184 config.namespaces = (Boolean) value;
189 * True to include namespace declarations; false to discard them
190 * (unsupported). Even when namespace declarations are discarded,
191 * prefixes are retained.
193 * Has no effect if namespaces is false.
195 PARAMETERS.put("namespace-declarations", new FixedParameter(true));
198 * True to fully normalize characters (unsupported).
200 PARAMETERS.put("normalize-characters", new FixedParameter(false));
203 * A list of whitespace-separated URIs representing the schemas to validate
204 * against. Has no effect if schema-type is null.
206 PARAMETERS.put("schema-location", new Parameter() {
207 public Object get(DOMConfigurationImpl config) {
208 return config.schemaLocation;
210 public void set(DOMConfigurationImpl config, Object value) {
211 config.schemaLocation = (String) value;
213 public boolean canSet(DOMConfigurationImpl config, Object value) {
214 return value == null || value instanceof String;
219 * URI representing the type of schema language, such as
220 * "http://www.w3.org/2001/XMLSchema" or "http://www.w3.org/TR/REC-xml".
222 PARAMETERS.put("schema-type", new Parameter() {
223 public Object get(DOMConfigurationImpl config) {
224 return config.schemaType;
226 public void set(DOMConfigurationImpl config, Object value) {
227 config.schemaType = (String) value;
229 public boolean canSet(DOMConfigurationImpl config, Object value) {
230 return value == null || value instanceof String;
235 * True to split CDATA sections containing "]]>"; false to signal an
238 PARAMETERS.put("split-cdata-sections", new BooleanParameter() {
239 public Object get(DOMConfigurationImpl config) {
240 return config.splitCdataSections;
242 public void set(DOMConfigurationImpl config, Object value) {
243 config.splitCdataSections = (Boolean) value;
248 * True to require validation against a schema or DTD. Validation will
249 * recompute element content whitespace, ID and schema type data.
251 * Setting this unsets validate-if-schema.
253 PARAMETERS.put("validate", new BooleanParameter() {
254 public Object get(DOMConfigurationImpl config) {
255 return config.validate;
257 public void set(DOMConfigurationImpl config, Object value) {
258 // validate-if-schema is always false
259 config.validate = (Boolean) value;
264 * True to validate if a schema was declared (unsupported). Setting this
267 PARAMETERS.put("validate-if-schema", new FixedParameter(false));
270 * True to report invalid characters in node names, attributes, elements,
271 * comments, text, CDATA sections and processing instructions.
273 PARAMETERS.put("well-formed", new BooleanParameter() {
274 public Object get(DOMConfigurationImpl config) {
275 return config.wellFormed;
277 public void set(DOMConfigurationImpl config, Object value) {
278 config.wellFormed = (Boolean) value;
282 // TODO add "resource-resolver" property for use with LS feature...
285 private boolean cdataSections = true;
286 private boolean comments = true;
287 private boolean datatypeNormalization = false;
288 private boolean entities = true;
289 private DOMErrorHandler errorHandler;
290 private boolean namespaces = true;
291 private String schemaLocation;
292 private String schemaType;
293 private boolean splitCdataSections = true;
294 private boolean validate = false;
295 private boolean wellFormed = true;
297 interface Parameter {
298 Object get(DOMConfigurationImpl config);
299 void set(DOMConfigurationImpl config, Object value);
300 boolean canSet(DOMConfigurationImpl config, Object value);
303 static class FixedParameter implements Parameter {
304 final Object onlyValue;
305 FixedParameter(Object onlyValue) {
306 this.onlyValue = onlyValue;
308 public Object get(DOMConfigurationImpl config) {
311 public void set(DOMConfigurationImpl config, Object value) {
312 if (!onlyValue.equals(value)) {
313 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
314 "Unsupported value: " + value);
317 public boolean canSet(DOMConfigurationImpl config, Object value) {
318 return onlyValue.equals(value);
322 static abstract class BooleanParameter implements Parameter {
323 public boolean canSet(DOMConfigurationImpl config, Object value) {
324 return value instanceof Boolean;
328 public boolean canSetParameter(String name, Object value) {
329 Parameter parameter = PARAMETERS.get(name);
330 return parameter != null && parameter.canSet(this, value);
333 public void setParameter(String name, Object value) throws DOMException {
334 Parameter parameter = PARAMETERS.get(name);
335 if (parameter == null) {
336 throw new DOMException(DOMException.NOT_FOUND_ERR, "No such parameter: " + name);
339 parameter.set(this, value);
340 } catch (NullPointerException e) {
341 throw new DOMException(DOMException.TYPE_MISMATCH_ERR,
342 "Null not allowed for " + name);
343 } catch (ClassCastException e) {
344 throw new DOMException(DOMException.TYPE_MISMATCH_ERR,
345 "Invalid type for " + name + ": " + value.getClass());
349 public Object getParameter(String name) throws DOMException {
350 Parameter parameter = PARAMETERS.get(name);
351 if (parameter == null) {
352 throw new DOMException(DOMException.NOT_FOUND_ERR, "No such parameter: " + name);
354 return parameter.get(this);
357 public DOMStringList getParameterNames() {
358 final String[] result = PARAMETERS.keySet().toArray(new String[PARAMETERS.size()]);
359 return new DOMStringList() {
360 public String item(int index) {
361 return index < result.length ? result[index] : null;
363 public int getLength() {
364 return result.length;
366 public boolean contains(String str) {
367 return PARAMETERS.containsKey(str); // case-insensitive.