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