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 package org.exolab.castor.builder.binding;
46
47
48 import java.util.HashMap;
49 import java.util.HashSet;
50 import java.util.Hashtable;
51 import java.util.Map;
52 import java.util.Set;
53
54 import org.exolab.castor.builder.binding.xml.AutomaticNamingType;
55 import org.exolab.castor.builder.binding.xml.Binding;
56 import org.exolab.castor.builder.binding.xml.ComponentBindingType;
57 import org.exolab.castor.builder.binding.xml.Exclude;
58 import org.exolab.castor.builder.binding.xml.Excludes;
59 import org.exolab.castor.builder.binding.xml.Forces;
60 import org.exolab.castor.xml.schema.Annotated;
61 import org.exolab.castor.xml.schema.AttributeDecl;
62 import org.exolab.castor.xml.schema.ElementDecl;
63 import org.exolab.castor.xml.schema.Structure;
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 public final class ExtendedBinding extends Binding {
96
97
98
99
100 protected static final String PATH_SEPARATOR = "/";
101
102
103
104 protected static final String ATTRIBUTE_PREFIX = "@";
105
106
107
108 public static final String COMPLEXTYPE_ID = "complexType:";
109
110
111
112 public static final String SIMPLETYPE_ID = "simpleType:";
113
114
115
116 public static final String ENUMTYPE_ID = "enumType:";
117
118
119
120 public static final String GROUP_ID = "group:";
121
122 private static final short ATTRIBUTE = 10;
123 private static final short ELEMENT = 11;
124 private static final short COMPLEXTYPE = 12;
125 private static final short GROUP = 13;
126 private static final short ENUM_TYPE = 14;
127 private static final short SIMPLETYPE = 15;
128
129
130
131
132 private Hashtable<String, ComponentBindingType> _componentBindings;
133
134
135
136
137
138 private boolean _bindingProcessed = false;
139
140
141
142
143
144 private Set<String> _automaticNameResolutionForced = new HashSet<String>();
145
146
147
148
149 private Map<String, Exclude> _automaticNameResolutionExcludes = new HashMap<String, Exclude>();
150
151
152
153
154
155 public ExtendedBinding() {
156 super();
157 _componentBindings = new Hashtable<String, ComponentBindingType>();
158 }
159
160
161
162
163
164
165
166
167
168
169
170
171 public ComponentBindingType getComponentBindingType(final Annotated annotated) {
172 if (annotated == null) {
173 return null;
174 }
175
176
177 if (annotated.getStructureType() == Structure.GROUP) {
178 return null;
179 }
180
181 if (!_bindingProcessed) {
182 processBindingComponents();
183 }
184
185 String xPath = XPathHelper.getSchemaLocation(annotated);
186 ComponentBindingType result = lookupComponentBindingType(xPath);
187 if (result == null) {
188
189 switch (annotated.getStructureType()) {
190
191 case Structure.ELEMENT :
192
193
194 if (result == null) {
195 ElementDecl element = (ElementDecl) annotated;
196 if (element.isReference()) {
197 xPath = XPathHelper.getSchemaLocation(element.getReference());
198 result = lookupComponentBindingType(xPath);
199 }
200
201 element = null;
202 }
203 break;
204
205 case Structure.ATTRIBUTE :
206 if (result == null) {
207
208
209 AttributeDecl attribute = (AttributeDecl) annotated;
210 if (attribute.isReference()) {
211 xPath = XPathHelper.getSchemaLocation(attribute.getReference());
212 result = lookupComponentBindingType(xPath);
213 }
214 attribute = null;
215 }
216 break;
217
218 default :
219 break;
220 }
221 }
222
223 return result;
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237
238 private ComponentBindingType lookupComponentBindingType(final String xPath) {
239 if (xPath == null) {
240 return null;
241 }
242 ComponentBindingType componentBinding =
243 _componentBindings.get(xPath);
244
245
246
247 if (componentBinding == null) {
248 int occurence = xPath.indexOf('{');
249 String xPathNoNamespaces = xPath;
250 if (occurence > 0) {
251 while (occurence > 0) {
252 String xPathOld = xPathNoNamespaces;
253 xPathNoNamespaces = xPathOld.substring(0, occurence);
254 int closingOccurence = xPathOld.indexOf('}');
255 xPathNoNamespaces += xPathOld.substring(closingOccurence + 1);
256 occurence = xPathNoNamespaces.indexOf('{');
257 }
258 componentBinding = lookupComponentBindingType(xPathNoNamespaces);
259 }
260 }
261 return componentBinding;
262 }
263
264
265
266
267
268
269
270
271
272 private void processBindingComponents() {
273 ComponentBindingType temp;
274 ComponentBindingType[] tempBindings = getAttributeBinding();
275
276
277 for (int i = 0; i < tempBindings.length; i++) {
278 temp = tempBindings[i];
279
280 handleComponent(temp, null, ATTRIBUTE);
281 }
282
283
284 tempBindings = getComplexTypeBinding();
285 for (int i = 0; i < tempBindings.length; i++) {
286 temp = tempBindings[i];
287 handleComponent(temp, null, COMPLEXTYPE);
288 }
289
290
291 tempBindings = getElementBinding();
292 for (int i = 0; i < tempBindings.length; i++) {
293 temp = tempBindings[i];
294 handleComponent(temp, null, ELEMENT);
295 }
296
297
298 tempBindings = getGroupBinding();
299 for (int i = 0; i < tempBindings.length; i++) {
300 temp = tempBindings[i];
301 handleComponent(temp, null, GROUP);
302 }
303
304
305 tempBindings = getEnumBinding();
306 for (int i = 0; i < tempBindings.length; i++) {
307 temp = tempBindings[i];
308 handleComponent(temp, null, ENUM_TYPE);
309 }
310
311
312 tempBindings = getSimpleTypeBinding();
313 for (int i = 0; i < tempBindings.length; i++) {
314 temp = tempBindings[i];
315 handleComponent(temp, null, SIMPLETYPE);
316 }
317
318 temp = null;
319 tempBindings = null;
320
321 _bindingProcessed = true;
322 }
323
324
325
326
327
328 void handleAutomaticNaming(final AutomaticNamingType type) {
329 Forces forcesOuter = type.getForces();
330 if (forcesOuter != null) {
331 String[] forces = forcesOuter.getForce();
332 for (int i = 0; i < forces.length; i++) {
333 String elementName = forces[i];
334 _automaticNameResolutionForced.add(elementName);
335
336 }
337 }
338
339 Excludes excludesOuter = type.getExcludes();
340 if (excludesOuter != null) {
341 Exclude[] excludes = excludesOuter.getExclude();
342 for (int i = 0; i < excludes.length; i++) {
343 Exclude exclude = excludes[i];
344 _automaticNameResolutionExcludes.put(exclude.getName(), exclude);
345 }
346 }
347 }
348
349
350
351
352
353
354
355
356
357
358
359 private void handleComponent(
360 final ComponentBindingType binding, final String xPath, final int type) {
361 if (binding == null) {
362 return;
363 }
364
365 String currentPath = xPath;
366 if (currentPath == null) {
367 currentPath = new String();
368 }
369
370 String name = binding.getName();
371 boolean xpathUsed = (name.indexOf("/") != -1);
372
373 switch (type) {
374 case ATTRIBUTE :
375
376 if (!xpathUsed) {
377 currentPath = currentPath + PATH_SEPARATOR + ATTRIBUTE_PREFIX;
378 }
379 currentPath += name;
380 _componentBindings.put(currentPath, binding);
381 break;
382
383 case SIMPLETYPE :
384
385 if (!xpathUsed) {
386 currentPath += SIMPLETYPE_ID;
387 }
388 currentPath += name;
389 _componentBindings.put(currentPath, binding);
390 break;
391
392 case ELEMENT :
393
394 if (!xpathUsed) {
395 currentPath += PATH_SEPARATOR;
396 }
397 currentPath += name;
398 _componentBindings.put(currentPath, binding);
399 break;
400
401 case COMPLEXTYPE :
402
403 if (!xpathUsed) {
404 currentPath += COMPLEXTYPE_ID;
405 } else {
406 if (!name.substring(1, 12).equals("complexType")) {
407 currentPath += PATH_SEPARATOR + COMPLEXTYPE_ID;
408 currentPath += name.substring(1);
409 } else {
410 currentPath += name;
411 }
412 }
413 _componentBindings.put(currentPath, binding);
414 break;
415
416 case ENUM_TYPE :
417
418 if (!xpathUsed) {
419 currentPath += ENUMTYPE_ID;
420 }
421 currentPath += name;
422 _componentBindings.put(currentPath, binding);
423 break;
424
425 case GROUP :
426
427 if (!xpathUsed) {
428 currentPath += GROUP_ID;
429 }
430 currentPath += name;
431 _componentBindings.put(currentPath, binding);
432 break;
433
434 default :
435
436 throw new IllegalStateException("Invalid ComponentBindingType: the"
437 + " type (attribute, element, complextype or group) is unknown");
438 }
439
440
441 ComponentBindingType temp;
442 ComponentBindingType[] tempBindings = binding.getAttributeBinding();
443
444
445 for (int i = 0; i < tempBindings.length; i++) {
446 temp = tempBindings[i];
447
448 handleComponent(temp, currentPath, ATTRIBUTE);
449 }
450
451
452 tempBindings = binding.getComplexTypeBinding();
453 for (int i = 0; i < tempBindings.length; i++) {
454 temp = tempBindings[i];
455 handleComponent(temp, currentPath, COMPLEXTYPE);
456 }
457
458
459 tempBindings = binding.getSimpleTypeBinding();
460 for (int i = 0; i < tempBindings.length; i++) {
461 temp = tempBindings[i];
462 handleComponent(temp, currentPath, SIMPLETYPE);
463 }
464
465
466 tempBindings = binding.getElementBinding();
467 for (int i = 0; i < tempBindings.length; i++) {
468 temp = tempBindings[i];
469 handleComponent(temp, currentPath, ELEMENT);
470 }
471
472
473 tempBindings = binding.getGroupBinding();
474 for (int i = 0; i < tempBindings.length; i++) {
475 temp = tempBindings[i];
476 handleComponent(temp, currentPath, GROUP);
477 }
478
479
480 tempBindings = binding.getEnumBinding();
481 for (int i = 0; i < tempBindings.length; i++) {
482 temp = tempBindings[i];
483 handleComponent(temp, currentPath, ENUM_TYPE);
484 }
485
486
487 temp = null;
488 tempBindings = null;
489 }
490
491
492
493
494
495
496
497 public boolean existsExclusion(final String localName) {
498 return _automaticNameResolutionExcludes.containsKey(localName);
499 }
500
501
502
503
504
505
506 public Exclude getExclusion(final String localName) {
507 return _automaticNameResolutionExcludes.get(localName);
508 }
509
510
511
512
513
514
515
516 public boolean existsForce(final String localName) {
517 return _automaticNameResolutionForced.contains(localName);
518 }
519
520
521
522
523
524 public Set<String> getForces() {
525 return _automaticNameResolutionForced;
526 }
527
528 }