1
2
3
4
5
6
7
8 package org.dom4j.datatype;
9
10 import org.dom4j.Attribute;
11 import org.dom4j.Document;
12 import org.dom4j.DocumentFactory;
13 import org.dom4j.Element;
14 import org.dom4j.Namespace;
15 import org.dom4j.QName;
16 import org.dom4j.io.SAXReader;
17
18 import org.xml.sax.EntityResolver;
19 import org.xml.sax.InputSource;
20
21 /***
22 * <p>
23 * <code>DatatypeDocumentFactory</code> is a factory of XML objects which
24 * support the <a href="http://www.w3.org/TR/xmlschema-2/">XML Schema Data Types
25 * </a> specification.
26 * </p>
27 *
28 * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
29 * @version $Revision: 1.9 $
30 */
31 public class DatatypeDocumentFactory extends DocumentFactory {
32
33 private static final boolean DO_INTERN_QNAME = false;
34
35 /*** The Singleton instance */
36 protected static transient DatatypeDocumentFactory singleton
37 = new DatatypeDocumentFactory();
38
39 private static final Namespace XSI_NAMESPACE = Namespace.get("xsi",
40 "http://www.w3.org/2001/XMLSchema-instance");
41
42 private static final QName XSI_SCHEMA_LOCATION = QName.get(
43 "schemaLocation", XSI_NAMESPACE);
44
45 private static final QName XSI_NO_SCHEMA_LOCATION = QName.get(
46 "noNamespaceSchemaLocation", XSI_NAMESPACE);
47
48 /*** The builder of XML Schemas */
49 private SchemaParser schemaBuilder;
50
51 /*** reader of XML Schemas */
52 private SAXReader xmlSchemaReader = new SAXReader();
53
54 /*** If schemas are automatically loaded when parsing instance documents */
55 private boolean autoLoadSchema = true;
56
57 public DatatypeDocumentFactory() {
58 schemaBuilder = new SchemaParser(this);
59 }
60
61 /***
62 * <p>
63 * Access to the singleton instance of this factory.
64 * </p>
65 *
66 * @return the default singleon instance
67 */
68 public static DocumentFactory getInstance() {
69 return singleton;
70 }
71
72 /***
73 * Loads the given XML Schema document into this factory so schema-aware
74 * Document, Elements and Attributes will be created by this factory.
75 *
76 * @param schemaDocument
77 * is an XML Schema Document instance.
78 */
79 public void loadSchema(Document schemaDocument) {
80 schemaBuilder.build(schemaDocument);
81 }
82
83 public void loadSchema(Document schemaDocument, Namespace targetNamespace) {
84 schemaBuilder.build(schemaDocument, targetNamespace);
85 }
86
87 /***
88 * Registers the given <code>DatatypeElementFactory</code> for the given
89 * <element> schema element
90 *
91 * @param elementQName
92 * DOCUMENT ME!
93 *
94 * @return DOCUMENT ME!
95 */
96 public DatatypeElementFactory getElementFactory(QName elementQName) {
97 DatatypeElementFactory result = null;
98
99 if (DO_INTERN_QNAME) {
100 elementQName = intern(elementQName);
101 }
102
103 DocumentFactory factory = elementQName.getDocumentFactory();
104 if (factory instanceof DatatypeElementFactory) {
105 result = (DatatypeElementFactory) factory;
106 }
107
108 return result;
109 }
110
111
112
113 public Attribute createAttribute(Element owner, QName qname, String value) {
114 if (autoLoadSchema && qname.equals(XSI_NO_SCHEMA_LOCATION)) {
115 Document document = (owner != null) ? owner.getDocument() : null;
116 loadSchema(document, value);
117 } else if (autoLoadSchema && qname.equals(XSI_SCHEMA_LOCATION)) {
118 Document document = (owner != null) ? owner.getDocument() : null;
119 String uri = value.substring(0, value.indexOf(' '));
120 Namespace namespace = owner.getNamespaceForURI(uri);
121 loadSchema(document, value.substring(value.indexOf(' ') + 1),
122 namespace);
123 }
124
125 return super.createAttribute(owner, qname, value);
126 }
127
128
129
130 protected void loadSchema(Document document, String schemaInstanceURI) {
131 try {
132 EntityResolver resolver = document.getEntityResolver();
133
134 if (resolver == null) {
135 String msg = "No EntityResolver available for resolving URI: ";
136 throw new InvalidSchemaException(msg + schemaInstanceURI);
137 }
138
139 InputSource inputSource = resolver.resolveEntity(null,
140 schemaInstanceURI);
141
142 if (resolver == null) {
143 throw new InvalidSchemaException("Could not resolve the URI: "
144 + schemaInstanceURI);
145 }
146
147 Document schemaDocument = xmlSchemaReader.read(inputSource);
148 loadSchema(schemaDocument);
149 } catch (Exception e) {
150 System.out.println("Failed to load schema: " + schemaInstanceURI);
151 System.out.println("Caught: " + e);
152 e.printStackTrace();
153 throw new InvalidSchemaException("Failed to load schema: "
154 + schemaInstanceURI);
155 }
156 }
157
158 protected void loadSchema(Document document, String schemaInstanceURI,
159 Namespace namespace) {
160 try {
161 EntityResolver resolver = document.getEntityResolver();
162
163 if (resolver == null) {
164 String msg = "No EntityResolver available for resolving URI: ";
165 throw new InvalidSchemaException(msg + schemaInstanceURI);
166 }
167
168 InputSource inputSource = resolver.resolveEntity(null,
169 schemaInstanceURI);
170
171 if (resolver == null) {
172 throw new InvalidSchemaException("Could not resolve the URI: "
173 + schemaInstanceURI);
174 }
175
176 Document schemaDocument = xmlSchemaReader.read(inputSource);
177 loadSchema(schemaDocument, namespace);
178 } catch (Exception e) {
179 System.out.println("Failed to load schema: " + schemaInstanceURI);
180 System.out.println("Caught: " + e);
181 e.printStackTrace();
182 throw new InvalidSchemaException("Failed to load schema: "
183 + schemaInstanceURI);
184 }
185 }
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223