1/*
2 * Copyright (c) 2001-2004 World Wide Web Consortium, (Massachusetts Institute of
3 * Technology, Institut National de Recherche en Informatique et en
4 * Automatique, Keio University). All Rights Reserved. This program is
5 * distributed under the W3C's Software Intellectual Property License. This
6 * program is distributed in the hope that it will be useful, but WITHOUT ANY
7 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8 * FOR A PARTICULAR PURPOSE. See W3C License
9 * http://www.w3.org/Consortium/Legal/ for more details.
10 */
11
12package org.w3c.domts;
13
14import java.lang.reflect.Method;
15
16import javax.xml.parsers.DocumentBuilderFactory;
17
18/**
19 * This class is a strategy that provides the mapping from an abstract setting
20 * (such as DocumentBuilderSetting.validating) to a specific DOM implementation
21 *
22 * @author Curt Arnold @date 2 Feb 2002
23 */
24public abstract class DocumentBuilderSettingStrategy {
25  protected DocumentBuilderSettingStrategy() {
26  }
27
28  private static final String JAXP_SCHEMA_LANGUAGE =
29      "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
30  private static final String W3C_XML_SCHEMA =
31      "http://www.w3.org/2001/XMLSchema";
32
33  public boolean hasConflict(DocumentBuilderSettingStrategy other) {
34    return (other == this);
35  }
36
37  public abstract void applySetting(
38      DocumentBuilderFactory factory,
39      boolean value) throws DOMTestIncompatibleException;
40
41  public abstract boolean hasSetting(DOMTestDocumentBuilderFactory factory);
42
43  public static final DocumentBuilderSettingStrategy coalescing =
44      new DocumentBuilderSettingStrategy() {
45    public void applySetting(DocumentBuilderFactory factory, boolean value)
46        throws DOMTestIncompatibleException {
47      factory.setCoalescing(value);
48    }
49
50    public boolean hasSetting(DOMTestDocumentBuilderFactory factory) {
51      return factory.isCoalescing();
52    }
53
54  };
55
56  public static final DocumentBuilderSettingStrategy
57      expandEntityReferences =
58      new DocumentBuilderSettingStrategy() {
59    public void applySetting(DocumentBuilderFactory factory, boolean value)
60        throws DOMTestIncompatibleException {
61      factory.setExpandEntityReferences(value);
62    }
63
64    public boolean hasSetting(DOMTestDocumentBuilderFactory factory) {
65      return factory.isExpandEntityReferences();
66    }
67  };
68
69  public static final DocumentBuilderSettingStrategy
70      ignoringElementContentWhitespace =
71      new DocumentBuilderSettingStrategy() {
72    public void applySetting(DocumentBuilderFactory factory, boolean value)
73        throws DOMTestIncompatibleException {
74      factory.setIgnoringElementContentWhitespace(value);
75    }
76
77    public boolean hasSetting(DOMTestDocumentBuilderFactory factory) {
78      return factory.isIgnoringElementContentWhitespace();
79    }
80  };
81
82  public static final DocumentBuilderSettingStrategy ignoringComments =
83      new DocumentBuilderSettingStrategy() {
84    public void applySetting(DocumentBuilderFactory factory, boolean value)
85        throws DOMTestIncompatibleException {
86      if (value) {
87        throw new DOMTestIncompatibleException(
88            new Exception("ignoreComments=true not supported"),
89            DocumentBuilderSetting.ignoringComments);
90      }
91    }
92
93    public boolean hasSetting(DOMTestDocumentBuilderFactory factory) {
94      return false;
95    }
96  };
97
98  public static final DocumentBuilderSettingStrategy namespaceAware =
99      new DocumentBuilderSettingStrategy() {
100    public void applySetting(DocumentBuilderFactory factory, boolean value) throws
101        DOMTestIncompatibleException {
102      factory.setNamespaceAware(value);
103    }
104
105    public boolean hasSetting(DOMTestDocumentBuilderFactory factory) {
106      return factory.isNamespaceAware();
107    }
108  };
109
110  public static final DocumentBuilderSettingStrategy validating =
111      new DocumentBuilderSettingStrategy() {
112    public void applySetting(DocumentBuilderFactory factory, boolean value) throws
113        DOMTestIncompatibleException {
114      factory.setValidating(value);
115    }
116
117    public boolean hasSetting(DOMTestDocumentBuilderFactory factory) {
118      return factory.isValidating();
119    }
120  };
121
122  public static final DocumentBuilderSettingStrategy signed =
123      new DocumentBuilderSettingStrategy() {
124    public void applySetting(DocumentBuilderFactory factory, boolean value) throws
125        DOMTestIncompatibleException {
126      if (!value) {
127        throw new DOMTestIncompatibleException(
128            null,
129            DocumentBuilderSetting.notSigned);
130      }
131    }
132
133    public boolean hasSetting(DOMTestDocumentBuilderFactory factory) {
134      return true;
135    }
136  };
137
138  public static final DocumentBuilderSettingStrategy hasNullString =
139      new DocumentBuilderSettingStrategy() {
140    public void applySetting(DocumentBuilderFactory factory, boolean value) throws
141        DOMTestIncompatibleException {
142      if (!value) {
143        throw new DOMTestIncompatibleException(
144            null,
145            DocumentBuilderSetting.notHasNullString);
146      }
147    }
148
149    public boolean hasSetting(DOMTestDocumentBuilderFactory factory) {
150      return true;
151    }
152  };
153
154  public static final DocumentBuilderSettingStrategy schemaValidating =
155      new DocumentBuilderSettingStrategy() {
156    public void applySetting(DocumentBuilderFactory factory, boolean value) throws
157        DOMTestIncompatibleException {
158      if (value) {
159        factory.setNamespaceAware(true);
160        factory.setValidating(true);
161        factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
162      }
163      else {
164        factory.setAttribute(JAXP_SCHEMA_LANGUAGE,
165                             "http://www.w3.org/TR/REC-xml");
166      }
167    }
168
169    public boolean hasSetting(DOMTestDocumentBuilderFactory factory) {
170      try {
171        if (factory.isValidating()) {
172          Method getAttrMethod = factory.getClass().getMethod("getAttribute",
173              new Class[] {String.class});
174          String val = (String) getAttrMethod.invoke(factory,
175              new Object[] {JAXP_SCHEMA_LANGUAGE});
176          return W3C_XML_SCHEMA.equals(val);
177        }
178      }
179      catch (Exception ex) {
180      }
181      return false;
182    }
183
184    //
185    //   schema validating conflicts with namespaceAware
186    //        and validating
187    //
188    public boolean hasConflict(DocumentBuilderSettingStrategy other) {
189      if (other == this ||
190          other == DocumentBuilderSettingStrategy.namespaceAware ||
191          other == DocumentBuilderSettingStrategy.validating) {
192        return true;
193      }
194      return false;
195    }
196
197  };
198
199}
200