1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.exolab.castor.xml.schema.reader;
47
48
49 import org.exolab.castor.net.URIException;
50 import org.exolab.castor.net.URILocation;
51 import org.exolab.castor.net.URIResolver;
52 import org.exolab.castor.xml.AttributeSet;
53 import org.exolab.castor.xml.XMLException;
54 import org.exolab.castor.xml.schema.Schema;
55 import org.exolab.castor.xml.schema.SchemaContext;
56 import org.exolab.castor.xml.schema.SchemaException;
57 import org.exolab.castor.xml.schema.SchemaNames;
58 import org.xml.sax.InputSource;
59 import org.xml.sax.Locator;
60 import org.xml.sax.Parser;
61
62
63
64
65
66
67
68
69
70
71
72 public class IncludeUnmarshaller extends ComponentReader
73 {
74
75
76 public IncludeUnmarshaller(
77 final SchemaContext schemaContext,
78 final Schema schema,
79 final AttributeSet atts,
80 final URIResolver uriResolver,
81 final Locator locator,
82 final SchemaUnmarshallerState state)
83 throws XMLException {
84 super(schemaContext);
85
86 setURIResolver(uriResolver);
87 URILocation uri = null;
88
89 String include = atts.getValue("schemaLocation");
90 if (include == null)
91 throw new SchemaException("'schemaLocation' attribute missing on 'include'");
92
93 if (include.indexOf("\\") != -1) {
94 String err = include+" is not a valid URI as defined by IETF RFC 2396.";
95 err += "The URI must not contain '\\'.";
96 throw new SchemaException(err);
97 }
98
99 try {
100 String documentBase = locator.getSystemId();
101 if (documentBase != null) {
102 if (!documentBase.endsWith("/"))
103 documentBase = documentBase.substring(0, documentBase.lastIndexOf("/") +1 );
104 }
105 uri = getURIResolver().resolve(include, documentBase);
106 } catch (URIException ure) {
107 throw new XMLException(ure);
108 }
109
110 if (uri != null)
111 include = uri.getAbsoluteURI();
112
113
114 if (schema.includeProcessed(include)) {
115 return;
116 }
117 else if (include.equals(schema.getSchemaLocation())) {
118 return;
119 }
120
121 Schema includedSchema = null;
122 boolean alreadyLoaded = false;
123
124
125 if (state.cacheIncludedSchemas) {
126 if (uri instanceof SchemaLocation) {
127 includedSchema = ((SchemaLocation)uri).getSchema();
128 schema.cacheIncludedSchema(includedSchema);
129 alreadyLoaded = true;
130 }
131
132 if (state.processed(include)) {
133 includedSchema = state.getSchema(include);
134 schema.cacheIncludedSchema(includedSchema);
135 alreadyLoaded = true;
136 }
137 }
138
139 if (includedSchema == null)
140 includedSchema = new Schema();
141 else
142 state.markAsProcessed(include, includedSchema);
143
144
145 schema.addInclude(include);
146
147 if (alreadyLoaded)
148 return;
149 Parser parser = null;
150 try {
151 parser = getSchemaContext().getParser();
152 }
153 catch(RuntimeException rte) {}
154 if (parser == null) {
155 throw new SchemaException("Error failed to create parser for include");
156 }
157 SchemaUnmarshaller schemaUnmarshaller = new SchemaUnmarshaller(getSchemaContext(), true, state, getURIResolver());
158
159 if (state.cacheIncludedSchemas)
160 schemaUnmarshaller.setSchema(includedSchema);
161 else
162 schemaUnmarshaller.setSchema(schema);
163
164 Sax2ComponentReader handler = new Sax2ComponentReader(schemaUnmarshaller);
165 parser.setDocumentHandler(handler);
166 parser.setErrorHandler(handler);
167
168 try {
169 InputSource source = new InputSource(uri.getReader());
170 source.setSystemId(uri.getAbsoluteURI());
171 parser.parse(source);
172 }
173 catch(java.io.IOException ioe) {
174 throw new SchemaException("Error reading include file '"+include+"'");
175 }
176 catch(org.xml.sax.SAXException sx) {
177 throw new SchemaException(sx);
178 }
179 if (state.cacheIncludedSchemas) {
180 String ns = includedSchema.getTargetNamespace();
181 if (ns == null || ns == "")
182 includedSchema.setTargetNamespace(schema.getTargetNamespace());
183 else if (!ns.equals(schema.getTargetNamespace()))
184 throw new SchemaException("The target namespace of the included components must be the same as the target namespace of the including schema");
185 schema.cacheIncludedSchema(includedSchema);
186 }
187 }
188
189
190
191
192
193 public String elementName() {
194 return SchemaNames.INCLUDE;
195 }
196
197
198
199
200
201 public Object getObject() {
202 return null;
203 }
204
205 }