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