6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 package com.sun.org.apache.xerces.internal.impl.xs.traversers;
22
23 import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
24 import com.sun.org.apache.xerces.internal.impl.dv.XSFacets;
25 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
26 import com.sun.org.apache.xerces.internal.impl.validation.ValidationState;
27 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
28 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
29 import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
30 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl;
31 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl;
32 import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
33 import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl;
34 import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
35 import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl;
36 import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
37 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
38 import com.sun.org.apache.xerces.internal.util.DOMUtil;
39 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
40 import com.sun.org.apache.xerces.internal.util.SymbolTable;
41 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
42 import com.sun.org.apache.xerces.internal.xni.QName;
43 import com.sun.org.apache.xerces.internal.xs.XSAttributeUse;
44 import com.sun.org.apache.xerces.internal.xs.XSObjectList;
45 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
46 import java.util.ArrayList;
47 import java.util.List;
48 import java.util.Locale;
49 import org.w3c.dom.Element;
50
51 /**
52 * Class <code>XSDAbstractTraverser</code> serves as the base class for all
53 * other <code>XSD???Traverser</code>s. It holds the common data and provide
54 * a unified way to initialize these data.
55 *
56 * @xerces.internal
57 *
58 * @author Elena Litani, IBM
59 * @author Rahul Srivastava, Sun Microsystems Inc.
60 * @author Neeraj Bajaj, Sun Microsystems Inc.
61 *
62 * @LastModified: Oct 2017
63 */
64 abstract class XSDAbstractTraverser {
263 // Temp data structures to be re-used in traversing facets
264 private StringBuilder fPattern = new StringBuilder();
265 private final XSFacets xsFacets = new XSFacets();
266
267 static final class FacetInfo {
268
269 final XSFacets facetdata;
270 final Element nodeAfterFacets;
271 final short fPresentFacets;
272 final short fFixedFacets;
273
274 FacetInfo(XSFacets facets, Element nodeAfterFacets, short presentFacets, short fixedFacets) {
275 facetdata = facets;
276 this.nodeAfterFacets = nodeAfterFacets;
277 fPresentFacets = presentFacets;
278 fFixedFacets = fixedFacets;
279 }
280 }
281
282 FacetInfo traverseFacets(Element content,
283 XSSimpleType baseValidator,
284 XSDocumentInfo schemaDoc) {
285
286 short facetsPresent = 0 ;
287 short facetsFixed = 0; // facets that have fixed="true"
288 String facet;
289 boolean hasQName = containsQName(baseValidator);
290 List<String> enumData = null;
291 XSObjectListImpl enumAnnotations = null;
292 XSObjectListImpl patternAnnotations = null;
293 List<NamespaceContext> enumNSDecls = hasQName ? new ArrayList<>() : null;
294 int currentFacet = 0;
295 xsFacets.reset();
296 while (content != null) {
297 // General Attribute Checking
298 Object[] attrs = null;
299 facet = DOMUtil.getLocalName(content);
300 if (facet.equals(SchemaSymbols.ELT_ENUMERATION)) {
301 attrs = fAttrChecker.checkAttributes(content, false, schemaDoc, hasQName);
302 String enumVal = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
303 // The facet can't be used if the value is missing. Ignore
304 // this facet element.
305 if (enumVal == null) {
306 reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_ENUMERATION, SchemaSymbols.ATT_VALUE}, content);
307 fAttrChecker.returnAttrArray (attrs, schemaDoc);
308 content = DOMUtil.getNextSiblingElement(content);
309 continue;
310 }
311
312 NamespaceSupport nsDecls = (NamespaceSupport)attrs[XSAttributeChecker.ATTIDX_ENUMNSDECLS];
313
314 // for NOTATION types, need to check whether there is a notation
315 // declared with the same name as the enumeration value.
347 enumNSDecls.add(nsDecls);
348 Element child = DOMUtil.getFirstChildElement( content );
349
350 if (child != null &&
351 DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
352 // traverse annotation if any
353 enumAnnotations.addXSObject(enumAnnotations.getLength()-1,traverseAnnotationDecl(child, attrs, false, schemaDoc));
354 child = DOMUtil.getNextSiblingElement(child);
355 }
356 else {
357 String text = DOMUtil.getSyntheticAnnotation(content);
358 if (text != null) {
359 enumAnnotations.addXSObject(enumAnnotations.getLength()-1, traverseSyntheticAnnotation(content, text, attrs, false, schemaDoc));
360 }
361 }
362 if (child !=null) {
363 reportSchemaError("s4s-elt-must-match.1", new Object[]{"enumeration", "(annotation?)", DOMUtil.getLocalName(child)}, child);
364 }
365 }
366 else if (facet.equals(SchemaSymbols.ELT_PATTERN)) {
367 facetsPresent |= XSSimpleType.FACET_PATTERN;
368 attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
369 String patternVal = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
370 // The facet can't be used if the value is missing. Ignore
371 // this facet element.
372 if (patternVal == null) {
373 reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_PATTERN, SchemaSymbols.ATT_VALUE}, content);
374 fAttrChecker.returnAttrArray (attrs, schemaDoc);
375 content = DOMUtil.getNextSiblingElement(content);
376 continue;
377 }
378
379 if (fPattern.length() == 0) {
380 fPattern.append(patternVal);
381 } else {
382 // ---------------------------------------------
383 //datatypes: 5.2.4 pattern: src-multiple-pattern
384 // ---------------------------------------------
385 fPattern.append("|");
386 fPattern.append(patternVal);
387 }
388 Element child = DOMUtil.getFirstChildElement( content );
389 if (child != null &&
390 DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
391 // traverse annotation if any
392 if (patternAnnotations == null){
393 patternAnnotations = new XSObjectListImpl();
394 }
395 patternAnnotations.addXSObject(traverseAnnotationDecl(child, attrs, false, schemaDoc));
396 child = DOMUtil.getNextSiblingElement(child);
397 }
398 else {
460 // Report an error if the "value" attribute is missing.
461 // If it's not missing, then its value is invalid, and an
462 // error should have already been reported by the
463 // attribute checker.
464 if (content.getAttributeNodeNS(null, "value") == null) {
465 reportSchemaError("s4s-att-must-appear", new Object[]{content.getLocalName(), SchemaSymbols.ATT_VALUE}, content);
466 }
467 fAttrChecker.returnAttrArray (attrs, schemaDoc);
468 content = DOMUtil.getNextSiblingElement(content);
469 continue;
470 }
471
472 facetsPresent |= currentFacet;
473 // check for fixed facet
474 if (((Boolean)attrs[XSAttributeChecker.ATTIDX_FIXED]).booleanValue()) {
475 facetsFixed |= currentFacet;
476 }
477 switch (currentFacet) {
478 case XSSimpleType.FACET_MINLENGTH:
479 xsFacets.minLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
480 break;
481 case XSSimpleType.FACET_MAXLENGTH:
482 xsFacets.maxLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
483 break;
484 case XSSimpleType.FACET_MAXEXCLUSIVE:
485 xsFacets.maxExclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
486 break;
487 case XSSimpleType.FACET_MAXINCLUSIVE:
488 xsFacets.maxInclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
489 break;
490 case XSSimpleType.FACET_MINEXCLUSIVE:
491 xsFacets.minExclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
492 break;
493 case XSSimpleType.FACET_MININCLUSIVE:
494 xsFacets.minInclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
495 break;
496 case XSSimpleType.FACET_TOTALDIGITS:
497 xsFacets.totalDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
498 break;
499 case XSSimpleType.FACET_FRACTIONDIGITS:
500 xsFacets.fractionDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
501 break;
502 case XSSimpleType.FACET_WHITESPACE:
503 xsFacets.whiteSpace = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).shortValue();
504 break;
505 case XSSimpleType.FACET_LENGTH:
506 xsFacets.length = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
507 break;
508 }
509
510 Element child = DOMUtil.getFirstChildElement( content );
511 XSAnnotationImpl annotation = null;
512 if (child != null &&
513 DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
514 // traverse annotation if any
515 annotation = traverseAnnotationDecl(child, attrs, false, schemaDoc);
516 child = DOMUtil.getNextSiblingElement(child);
517 }
518 else {
519 String text = DOMUtil.getSyntheticAnnotation(content);
520 if (text != null) {
521 annotation = traverseSyntheticAnnotation(content, text, attrs, false, schemaDoc);
522 }
523 }
524 switch (currentFacet) {
525 case XSSimpleType.FACET_MINLENGTH:
526 xsFacets.minLengthAnnotation = annotation;
549 case XSSimpleType.FACET_WHITESPACE:
550 xsFacets.whiteSpaceAnnotation = annotation;
551 break;
552 case XSSimpleType.FACET_LENGTH:
553 xsFacets.lengthAnnotation = annotation;
554 break;
555 }
556 if (child != null) {
557 reportSchemaError("s4s-elt-must-match.1", new Object[]{facet, "(annotation?)", DOMUtil.getLocalName(child)}, child);
558 }
559 }
560 fAttrChecker.returnAttrArray (attrs, schemaDoc);
561 content = DOMUtil.getNextSiblingElement(content);
562 }
563 if (enumData !=null) {
564 facetsPresent |= XSSimpleType.FACET_ENUMERATION;
565 xsFacets.enumeration = enumData;
566 xsFacets.enumNSDecls = enumNSDecls;
567 xsFacets.enumAnnotations = enumAnnotations;
568 }
569 if ((facetsPresent & XSSimpleType.FACET_PATTERN) != 0) {
570 xsFacets.pattern = fPattern.toString();
571 xsFacets.patternAnnotations = patternAnnotations;
572 }
573
574 fPattern.setLength(0);
575
576 return new FacetInfo(xsFacets, content, facetsPresent, facetsFixed);
577 }
578
579
580 // return whether QName/NOTATION is part of the given type
581 private boolean containsQName(XSSimpleType type) {
582 if (type.getVariety() == XSSimpleType.VARIETY_ATOMIC) {
583 short primitive = type.getPrimitiveKind();
584 return (primitive == XSSimpleType.PRIMITIVE_QNAME ||
585 primitive == XSSimpleType.PRIMITIVE_NOTATION);
586 }
587 else if (type.getVariety() == XSSimpleType.VARIETY_LIST) {
588 return containsQName((XSSimpleType)type.getItemType());
589 }
590 else if (type.getVariety() == XSSimpleType.VARIETY_UNION) {
591 XSObjectList members = type.getMemberTypes();
592 for (int i = 0; i < members.getLength(); i++) {
593 if (containsQName((XSSimpleType)members.item(i)))
594 return true;
595 }
596 }
597 return false;
598 }
705 else {
706 attrGrp.fAttributeWC = tempAttrWC.
707 performIntersectionWith(attrGrp.fAttributeWC, tempAttrWC.fProcessContents);
708 if (attrGrp.fAttributeWC == null) {
709 String code = (enclosingCT == null) ? "src-attribute_group.2" : "src-ct.4";
710 String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
711 reportSchemaError(code, new Object[]{name}, child);
712 }
713 }
714 child = DOMUtil.getNextSiblingElement(child);
715 }
716 }
717
718 // Success
719 return child;
720
721 }
722
723 void reportSchemaError (String key, Object[] args, Element ele) {
724 fSchemaHandler.reportSchemaError(key, args, ele);
725 }
726
727 /**
728 * Element/Attribute traversers call this method to check whether
729 * the type is NOTATION without enumeration facet
730 */
731 void checkNotationType(String refName, XSTypeDefinition typeDecl, Element elem) {
732 if (typeDecl.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE &&
733 ((XSSimpleType)typeDecl).getVariety() == XSSimpleType.VARIETY_ATOMIC &&
734 ((XSSimpleType)typeDecl).getPrimitiveKind() == XSSimpleType.PRIMITIVE_NOTATION) {
735 if ((((XSSimpleType)typeDecl).getDefinedFacets() & XSSimpleType.FACET_ENUMERATION) == 0) {
736 reportSchemaError("enumeration-required-notation", new Object[]{typeDecl.getName(), refName, DOMUtil.getLocalName(elem)}, elem);
737 }
738 }
739 }
740
741 // Checks constraints for minOccurs, maxOccurs
742 protected XSParticleDecl checkOccurrences(XSParticleDecl particle,
743 String particleName, Element parent,
744 int allContextFlags,
|
6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 package com.sun.org.apache.xerces.internal.impl.xs.traversers;
22
23 import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
24 import com.sun.org.apache.xerces.internal.impl.dv.XSFacets;
25 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
26 import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
27 import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl;
28 import com.sun.org.apache.xerces.internal.impl.validation.ValidationState;
29 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
30 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
31 import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
32 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl;
33 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl;
34 import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
35 import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl;
36 import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
37 import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl;
38 import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
39 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
40 import com.sun.org.apache.xerces.internal.util.DOMUtil;
41 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
42 import com.sun.org.apache.xerces.internal.util.SymbolTable;
43 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
44 import com.sun.org.apache.xerces.internal.xni.QName;
45 import com.sun.org.apache.xerces.internal.xs.XSAttributeUse;
46 import com.sun.org.apache.xerces.internal.xs.XSObjectList;
47 import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition;
48 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
49 import java.util.ArrayList;
50 import java.util.List;
51 import java.util.Locale;
52 import org.w3c.dom.Element;
53
54 /**
55 * Class <code>XSDAbstractTraverser</code> serves as the base class for all
56 * other <code>XSD???Traverser</code>s. It holds the common data and provide
57 * a unified way to initialize these data.
58 *
59 * @xerces.internal
60 *
61 * @author Elena Litani, IBM
62 * @author Rahul Srivastava, Sun Microsystems Inc.
63 * @author Neeraj Bajaj, Sun Microsystems Inc.
64 *
65 * @LastModified: Oct 2017
66 */
67 abstract class XSDAbstractTraverser {
266 // Temp data structures to be re-used in traversing facets
267 private StringBuilder fPattern = new StringBuilder();
268 private final XSFacets xsFacets = new XSFacets();
269
270 static final class FacetInfo {
271
272 final XSFacets facetdata;
273 final Element nodeAfterFacets;
274 final short fPresentFacets;
275 final short fFixedFacets;
276
277 FacetInfo(XSFacets facets, Element nodeAfterFacets, short presentFacets, short fixedFacets) {
278 facetdata = facets;
279 this.nodeAfterFacets = nodeAfterFacets;
280 fPresentFacets = presentFacets;
281 fFixedFacets = fixedFacets;
282 }
283 }
284
285 FacetInfo traverseFacets(Element content,
286 XSTypeDefinition typeDef,
287 XSSimpleType baseValidator,
288 XSDocumentInfo schemaDoc) {
289
290 short facetsPresent = 0 ;
291 short facetsFixed = 0; // facets that have fixed="true"
292 String facet;
293 boolean hasQName = containsQName(baseValidator);
294 List<String> enumData = null;
295 XSObjectListImpl enumAnnotations = null;
296 XSObjectListImpl patternAnnotations = null;
297 List<NamespaceContext> enumNSDecls = hasQName ? new ArrayList<>() : null;
298 int currentFacet = 0;
299 xsFacets.reset();
300 boolean seenPattern = false;
301 Element contextNode = (Element)content.getParentNode();
302 boolean hasLengthFacet = false, hasMinLengthFacet = false, hasMaxLengthFacet = false;
303 while (content != null) {
304 // General Attribute Checking
305 Object[] attrs = null;
306 facet = DOMUtil.getLocalName(content);
307 if (facet.equals(SchemaSymbols.ELT_ENUMERATION)) {
308 attrs = fAttrChecker.checkAttributes(content, false, schemaDoc, hasQName);
309 String enumVal = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
310 // The facet can't be used if the value is missing. Ignore
311 // this facet element.
312 if (enumVal == null) {
313 reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_ENUMERATION, SchemaSymbols.ATT_VALUE}, content);
314 fAttrChecker.returnAttrArray (attrs, schemaDoc);
315 content = DOMUtil.getNextSiblingElement(content);
316 continue;
317 }
318
319 NamespaceSupport nsDecls = (NamespaceSupport)attrs[XSAttributeChecker.ATTIDX_ENUMNSDECLS];
320
321 // for NOTATION types, need to check whether there is a notation
322 // declared with the same name as the enumeration value.
354 enumNSDecls.add(nsDecls);
355 Element child = DOMUtil.getFirstChildElement( content );
356
357 if (child != null &&
358 DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
359 // traverse annotation if any
360 enumAnnotations.addXSObject(enumAnnotations.getLength()-1,traverseAnnotationDecl(child, attrs, false, schemaDoc));
361 child = DOMUtil.getNextSiblingElement(child);
362 }
363 else {
364 String text = DOMUtil.getSyntheticAnnotation(content);
365 if (text != null) {
366 enumAnnotations.addXSObject(enumAnnotations.getLength()-1, traverseSyntheticAnnotation(content, text, attrs, false, schemaDoc));
367 }
368 }
369 if (child !=null) {
370 reportSchemaError("s4s-elt-must-match.1", new Object[]{"enumeration", "(annotation?)", DOMUtil.getLocalName(child)}, child);
371 }
372 }
373 else if (facet.equals(SchemaSymbols.ELT_PATTERN)) {
374 attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
375 String patternVal = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
376 // The facet can't be used if the value is missing. Ignore
377 // this facet element.
378 if (patternVal == null) {
379 reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_PATTERN, SchemaSymbols.ATT_VALUE}, content);
380 fAttrChecker.returnAttrArray (attrs, schemaDoc);
381 content = DOMUtil.getNextSiblingElement(content);
382 continue;
383 }
384
385 seenPattern = true;
386 if (fPattern.length() == 0) {
387 fPattern.append(patternVal);
388 } else {
389 // ---------------------------------------------
390 //datatypes: 5.2.4 pattern: src-multiple-pattern
391 // ---------------------------------------------
392 fPattern.append("|");
393 fPattern.append(patternVal);
394 }
395 Element child = DOMUtil.getFirstChildElement( content );
396 if (child != null &&
397 DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
398 // traverse annotation if any
399 if (patternAnnotations == null){
400 patternAnnotations = new XSObjectListImpl();
401 }
402 patternAnnotations.addXSObject(traverseAnnotationDecl(child, attrs, false, schemaDoc));
403 child = DOMUtil.getNextSiblingElement(child);
404 }
405 else {
467 // Report an error if the "value" attribute is missing.
468 // If it's not missing, then its value is invalid, and an
469 // error should have already been reported by the
470 // attribute checker.
471 if (content.getAttributeNodeNS(null, "value") == null) {
472 reportSchemaError("s4s-att-must-appear", new Object[]{content.getLocalName(), SchemaSymbols.ATT_VALUE}, content);
473 }
474 fAttrChecker.returnAttrArray (attrs, schemaDoc);
475 content = DOMUtil.getNextSiblingElement(content);
476 continue;
477 }
478
479 facetsPresent |= currentFacet;
480 // check for fixed facet
481 if (((Boolean)attrs[XSAttributeChecker.ATTIDX_FIXED]).booleanValue()) {
482 facetsFixed |= currentFacet;
483 }
484 switch (currentFacet) {
485 case XSSimpleType.FACET_MINLENGTH:
486 xsFacets.minLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
487 hasMinLengthFacet = true;
488 break;
489 case XSSimpleType.FACET_MAXLENGTH:
490 xsFacets.maxLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
491 hasMaxLengthFacet = true;
492 break;
493 case XSSimpleType.FACET_MAXEXCLUSIVE:
494 xsFacets.maxExclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
495 break;
496 case XSSimpleType.FACET_MAXINCLUSIVE:
497 xsFacets.maxInclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
498 break;
499 case XSSimpleType.FACET_MINEXCLUSIVE:
500 xsFacets.minExclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
501 break;
502 case XSSimpleType.FACET_MININCLUSIVE:
503 xsFacets.minInclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
504 break;
505 case XSSimpleType.FACET_TOTALDIGITS:
506 xsFacets.totalDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
507 break;
508 case XSSimpleType.FACET_FRACTIONDIGITS:
509 xsFacets.fractionDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
510 break;
511 case XSSimpleType.FACET_WHITESPACE:
512 xsFacets.whiteSpace = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).shortValue();
513 break;
514 case XSSimpleType.FACET_LENGTH:
515 xsFacets.length = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
516 hasLengthFacet = true;
517 break;
518 }
519
520 Element child = DOMUtil.getFirstChildElement( content );
521 XSAnnotationImpl annotation = null;
522 if (child != null &&
523 DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
524 // traverse annotation if any
525 annotation = traverseAnnotationDecl(child, attrs, false, schemaDoc);
526 child = DOMUtil.getNextSiblingElement(child);
527 }
528 else {
529 String text = DOMUtil.getSyntheticAnnotation(content);
530 if (text != null) {
531 annotation = traverseSyntheticAnnotation(content, text, attrs, false, schemaDoc);
532 }
533 }
534 switch (currentFacet) {
535 case XSSimpleType.FACET_MINLENGTH:
536 xsFacets.minLengthAnnotation = annotation;
559 case XSSimpleType.FACET_WHITESPACE:
560 xsFacets.whiteSpaceAnnotation = annotation;
561 break;
562 case XSSimpleType.FACET_LENGTH:
563 xsFacets.lengthAnnotation = annotation;
564 break;
565 }
566 if (child != null) {
567 reportSchemaError("s4s-elt-must-match.1", new Object[]{facet, "(annotation?)", DOMUtil.getLocalName(child)}, child);
568 }
569 }
570 fAttrChecker.returnAttrArray (attrs, schemaDoc);
571 content = DOMUtil.getNextSiblingElement(content);
572 }
573 if (enumData !=null) {
574 facetsPresent |= XSSimpleType.FACET_ENUMERATION;
575 xsFacets.enumeration = enumData;
576 xsFacets.enumNSDecls = enumNSDecls;
577 xsFacets.enumAnnotations = enumAnnotations;
578 }
579 if (seenPattern) {
580 facetsPresent |= XSSimpleType.FACET_PATTERN;
581 xsFacets.pattern = fPattern.toString();
582 xsFacets.patternAnnotations = patternAnnotations;
583 }
584
585 fPattern.setLength(0);
586
587 // check if length, minLength and maxLength facets contradict with enumeration facets.
588 // currently considers the case when the baseValidator is a built-in type.
589 if (enumData != null) {
590 if (hasLengthFacet) {
591 checkEnumerationAndLengthInconsistency(baseValidator, enumData, contextNode, getSchemaTypeName(typeDef));
592 }
593 if (hasMinLengthFacet) {
594 checkEnumerationAndMinLengthInconsistency(baseValidator, enumData, contextNode, getSchemaTypeName(typeDef));
595 }
596 if (hasMaxLengthFacet) {
597 checkEnumerationAndMaxLengthInconsistency(baseValidator, enumData, contextNode, getSchemaTypeName(typeDef));
598 }
599 }
600
601 return new FacetInfo(xsFacets, content, facetsPresent, facetsFixed);
602 }
603
604 /*
605 * Get name of an XSD type definition as a string value (which will typically be the value of "name" attribute of a
606 * type definition, or an internal name determined by the validator for anonymous types).
607 */
608 public static String getSchemaTypeName(XSTypeDefinition typeDefn) {
609
610 String typeNameStr = "";
611 if (typeDefn instanceof XSSimpleTypeDefinition) {
612 typeNameStr = ((XSSimpleTypeDecl) typeDefn).getTypeName();
613 }
614 else {
615 typeNameStr = ((XSComplexTypeDecl) typeDefn).getTypeName();
616 }
617
618 return typeNameStr;
619
620 } // getSchemaTypeName
621
622 /*
623 * Check whether values of xs:maxLength and xs:enumeration are consistent. Report a warning message if they are not.
624 */
625 private void checkEnumerationAndMaxLengthInconsistency(XSSimpleType baseValidator, List<String> enumData, Element contextNode, String typeName) {
626 if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
627 SchemaSymbols.ATTVAL_HEXBINARY.equals(baseValidator.getName())) {
628 for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
629 String enumVal = (enumData.get(enumIdx));
630 if (enumVal.length() / 2 > xsFacets.maxLength) {
631 reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MAXLENGTH, typeName}, contextNode);
632 }
633 }
634 }
635 else if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
636 SchemaSymbols.ATTVAL_BASE64BINARY.equals(baseValidator.getName())) {
637 for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
638 String enumVal = (enumData.get(enumIdx));
639 byte[] decodedVal = Base64.decode(enumVal);
640 if (decodedVal != null && (new String(decodedVal)).length() > xsFacets.maxLength) {
641 reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MAXLENGTH, typeName}, contextNode);
642 }
643 }
644 }
645 else {
646 for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
647 String enumVal = (enumData.get(enumIdx));
648 if (enumVal.length() > xsFacets.maxLength) {
649 reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MAXLENGTH, typeName}, contextNode);
650 }
651 }
652 }
653 } // checkEnumerationAndMaxLengthInconsistency
654
655 /*
656 * Check whether values of xs:minLength and xs:enumeration are consistent. Report a warning message if they are not.
657 */
658 private void checkEnumerationAndMinLengthInconsistency(XSSimpleType baseValidator, List<String> enumData, Element contextNode, String typeName) {
659 if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
660 SchemaSymbols.ATTVAL_HEXBINARY.equals(baseValidator.getName())) {
661 for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
662 String enumVal = (enumData.get(enumIdx));
663 if (enumVal.length() / 2 < xsFacets.minLength) {
664 reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MINLENGTH, typeName}, contextNode);
665 }
666 }
667 }
668 else if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
669 SchemaSymbols.ATTVAL_BASE64BINARY.equals(baseValidator.getName())) {
670 for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
671 String enumVal = (enumData.get(enumIdx));
672 byte[] decodedVal = Base64.decode(enumVal);
673 if (decodedVal != null && (new String(decodedVal)).length() < xsFacets.minLength) {
674 reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MINLENGTH, typeName}, contextNode);
675 }
676 }
677 }
678 else {
679 for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
680 String enumVal = (enumData.get(enumIdx));
681 if (enumVal.length() < xsFacets.minLength) {
682 reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MINLENGTH, typeName}, contextNode);
683 }
684 }
685 }
686 } // checkEnumerationAndMinLengthInconsistency
687
688 /*
689 * Check whether values of xs:length and xs:enumeration are consistent. Report a warning message if they are not.
690 */
691 private void checkEnumerationAndLengthInconsistency(XSSimpleType baseValidator, List<String> enumData, Element contextNode, String typeName) {
692 if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
693 SchemaSymbols.ATTVAL_HEXBINARY.equals(baseValidator.getName())) {
694 for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
695 String enumVal = (enumData.get(enumIdx));
696 if (enumVal.length() / 2 != xsFacets.length) {
697 reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_LENGTH, typeName}, contextNode);
698 }
699 }
700 }
701 else if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
702 SchemaSymbols.ATTVAL_BASE64BINARY.equals(baseValidator.getName())) {
703 for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
704 String enumVal = (enumData.get(enumIdx));
705 byte[] decodedVal = Base64.decode(enumVal);
706 if (decodedVal != null && (new String(decodedVal)).length() != xsFacets.length) {
707 reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_LENGTH, typeName}, contextNode);
708 }
709 }
710 }
711 else {
712 for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
713 String enumVal = (enumData.get(enumIdx));
714 if (enumVal.length() != xsFacets.length) {
715 reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_LENGTH, typeName}, contextNode);
716 }
717 }
718 }
719 } // checkEnumerationAndLengthInconsistency
720
721
722 // return whether QName/NOTATION is part of the given type
723 private boolean containsQName(XSSimpleType type) {
724 if (type.getVariety() == XSSimpleType.VARIETY_ATOMIC) {
725 short primitive = type.getPrimitiveKind();
726 return (primitive == XSSimpleType.PRIMITIVE_QNAME ||
727 primitive == XSSimpleType.PRIMITIVE_NOTATION);
728 }
729 else if (type.getVariety() == XSSimpleType.VARIETY_LIST) {
730 return containsQName((XSSimpleType)type.getItemType());
731 }
732 else if (type.getVariety() == XSSimpleType.VARIETY_UNION) {
733 XSObjectList members = type.getMemberTypes();
734 for (int i = 0; i < members.getLength(); i++) {
735 if (containsQName((XSSimpleType)members.item(i)))
736 return true;
737 }
738 }
739 return false;
740 }
847 else {
848 attrGrp.fAttributeWC = tempAttrWC.
849 performIntersectionWith(attrGrp.fAttributeWC, tempAttrWC.fProcessContents);
850 if (attrGrp.fAttributeWC == null) {
851 String code = (enclosingCT == null) ? "src-attribute_group.2" : "src-ct.4";
852 String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
853 reportSchemaError(code, new Object[]{name}, child);
854 }
855 }
856 child = DOMUtil.getNextSiblingElement(child);
857 }
858 }
859
860 // Success
861 return child;
862
863 }
864
865 void reportSchemaError (String key, Object[] args, Element ele) {
866 fSchemaHandler.reportSchemaError(key, args, ele);
867 }
868
869 void reportSchemaWarning (String key, Object[] args, Element ele) {
870 fSchemaHandler.reportSchemaWarning(key, args, ele);
871 }
872
873 /**
874 * Element/Attribute traversers call this method to check whether
875 * the type is NOTATION without enumeration facet
876 */
877 void checkNotationType(String refName, XSTypeDefinition typeDecl, Element elem) {
878 if (typeDecl.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE &&
879 ((XSSimpleType)typeDecl).getVariety() == XSSimpleType.VARIETY_ATOMIC &&
880 ((XSSimpleType)typeDecl).getPrimitiveKind() == XSSimpleType.PRIMITIVE_NOTATION) {
881 if ((((XSSimpleType)typeDecl).getDefinedFacets() & XSSimpleType.FACET_ENUMERATION) == 0) {
882 reportSchemaError("enumeration-required-notation", new Object[]{typeDecl.getName(), refName, DOMUtil.getLocalName(elem)}, elem);
883 }
884 }
885 }
886
887 // Checks constraints for minOccurs, maxOccurs
888 protected XSParticleDecl checkOccurrences(XSParticleDecl particle,
889 String particleName, Element parent,
890 int allContextFlags,
|