1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xerces" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 2001, International
  53. * Business Machines, Inc., http://www.apache.org. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package com.sun.org.apache.xerces.internal.impl.xs.traversers;
  58. import java.util.Vector;
  59. import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
  60. import com.sun.org.apache.xerces.internal.impl.dv.XSFacets;
  61. import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
  62. import com.sun.org.apache.xerces.internal.impl.validation.ValidationState;
  63. import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
  64. import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
  65. import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
  66. import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl;
  67. import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl;
  68. import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
  69. import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl;
  70. import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
  71. import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl;
  72. import com.sun.org.apache.xerces.internal.xs.XSObjectList;
  73. import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
  74. import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
  75. import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
  76. import com.sun.org.apache.xerces.internal.util.DOMUtil;
  77. import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
  78. import com.sun.org.apache.xerces.internal.util.SymbolTable;
  79. import com.sun.org.apache.xerces.internal.xni.QName;
  80. import org.w3c.dom.Element;
  81. import org.w3c.dom.Node;
  82. import org.w3c.dom.Text;
  83. /**
  84. * Class <code>XSDAbstractTraverser</code> serves as the base class for all
  85. * other <code>XSD???Traverser</code>s. It holds the common data and provide
  86. * a unified way to initialize these data.
  87. *
  88. * @author Elena Litani, IBM
  89. * @author Rahul Srivastava, Sun Microsystems Inc.
  90. * @author Neeraj Bajaj, Sun Microsystems Inc.
  91. *
  92. * @version $Id: XSDAbstractTraverser.java,v 1.35 2003/11/11 20:15:00 sandygao Exp $
  93. */
  94. abstract class XSDAbstractTraverser {
  95. protected static final String NO_NAME = "(no name)";
  96. // Flags for checkOccurrences to indicate any special
  97. // restrictions on minOccurs and maxOccurs relating to "all".
  98. // NOT_ALL_CONTEXT - not processing an <all>
  99. // PROCESSING_ALL_EL - processing an <element> in an <all>
  100. // GROUP_REF_WITH_ALL - processing <group> reference that contained <all>
  101. // CHILD_OF_GROUP - processing a child of a model group definition
  102. // PROCESSING_ALL_GP - processing an <all> group itself
  103. protected static final int NOT_ALL_CONTEXT = 0;
  104. protected static final int PROCESSING_ALL_EL = 1;
  105. protected static final int GROUP_REF_WITH_ALL = 2;
  106. protected static final int CHILD_OF_GROUP = 4;
  107. protected static final int PROCESSING_ALL_GP = 8;
  108. //Shared data
  109. protected XSDHandler fSchemaHandler = null;
  110. protected SymbolTable fSymbolTable = null;
  111. protected XSAttributeChecker fAttrChecker = null;
  112. // used to validate default/fixed attribute values
  113. ValidationState fValidationState = new ValidationState();
  114. XSDAbstractTraverser (XSDHandler handler,
  115. XSAttributeChecker attrChecker) {
  116. fSchemaHandler = handler;
  117. fAttrChecker = attrChecker;
  118. }
  119. void reset(SymbolTable symbolTable) {
  120. fSymbolTable = symbolTable;
  121. fValidationState.setExtraChecking(false);
  122. fValidationState.setSymbolTable(symbolTable);
  123. }
  124. // traverse the annotation declaration
  125. // REVISIT: how to pass the parentAttrs? as DOM attributes?
  126. // as name/value pairs (string)? in parsed form?
  127. // @return XSAnnotationImpl object
  128. XSAnnotationImpl traverseAnnotationDecl(Element annotationDecl, Object[] parentAttrs,
  129. boolean isGlobal, XSDocumentInfo schemaDoc) {
  130. // General Attribute Checking
  131. Object[] attrValues = fAttrChecker.checkAttributes(annotationDecl, isGlobal, schemaDoc);
  132. fAttrChecker.returnAttrArray(attrValues, schemaDoc);
  133. String contents = null;
  134. for (Element child = DOMUtil.getFirstChildElement(annotationDecl);
  135. child != null;
  136. child = DOMUtil.getNextSiblingElement(child)) {
  137. String name = DOMUtil.getLocalName(child);
  138. // the only valid children of "annotation" are
  139. // "appinfo" and "documentation"
  140. if (!((name.equals(SchemaSymbols.ELT_APPINFO)) ||
  141. (name.equals(SchemaSymbols.ELT_DOCUMENTATION)))) {
  142. reportSchemaError("src-annotation", new Object[]{name}, child);
  143. } else { // the annotation, as we currently know it, is a Text child
  144. Node textContent = child.getFirstChild();
  145. if(textContent != null && textContent.getNodeType() == Node.TEXT_NODE) {
  146. contents = ((Text)textContent).getData();
  147. }
  148. }
  149. // General Attribute Checking
  150. // There is no difference between global or local appinfo/documentation,
  151. // so we assume it's always global.
  152. attrValues = fAttrChecker.checkAttributes(child, true, schemaDoc);
  153. fAttrChecker.returnAttrArray(attrValues, schemaDoc);
  154. }
  155. // if contents was null, must have been some kind of error;
  156. // nothing to contribute to PSVI
  157. if (contents == null) return null;
  158. // find the grammar; fSchemaHandler must be known!
  159. SchemaGrammar grammar = fSchemaHandler.getGrammar(schemaDoc.fTargetNamespace);
  160. // fish out local attributes passed from parent
  161. Vector annotationLocalAttrs = (Vector)parentAttrs[XSAttributeChecker.ATTIDX_NONSCHEMA];
  162. // optimize for case where there are no local attributes
  163. if(annotationLocalAttrs != null && !annotationLocalAttrs.isEmpty()) {
  164. StringBuffer localStrBuffer = new StringBuffer(64);
  165. localStrBuffer.append(" ");
  166. // Vector should contain rawname value pairs
  167. int i=0;
  168. while(i<annotationLocalAttrs.size()) {
  169. String rawname = (String)annotationLocalAttrs.elementAt(i++);
  170. int colonIndex = rawname.indexOf(':');
  171. String prefix, localpart;
  172. if (colonIndex == -1) {
  173. prefix = "";
  174. localpart = rawname;
  175. }
  176. else {
  177. prefix = rawname.substring(0,colonIndex);
  178. localpart = rawname.substring(colonIndex+1);
  179. }
  180. String uri = schemaDoc.fNamespaceSupport.getURI(prefix.intern());
  181. if (!annotationDecl.getAttributeNS(uri, localpart).equals("")) {
  182. i++; // skip the next value, too
  183. continue;
  184. }
  185. localStrBuffer.append(rawname)
  186. .append("=\"");
  187. String value = (String)annotationLocalAttrs.elementAt(i++);
  188. // search for pesky "s and >s within attr value:
  189. value = processAttValue(value);
  190. localStrBuffer.append(value)
  191. .append("\" ");
  192. }
  193. // and now splice it into place; immediately after the annotation token, for simplicity's sake
  194. StringBuffer contentBuffer = new StringBuffer(contents.length() + localStrBuffer.length());
  195. int annotationTokenEnd = contents.indexOf(SchemaSymbols.ELT_ANNOTATION);
  196. // annotation must occur somewhere or we're in big trouble...
  197. if(annotationTokenEnd == -1) return null;
  198. annotationTokenEnd += SchemaSymbols.ELT_ANNOTATION.length();
  199. contentBuffer.append(contents.substring(0,annotationTokenEnd));
  200. contentBuffer.append(localStrBuffer.toString());
  201. contentBuffer.append(contents.substring(annotationTokenEnd, contents.length()));
  202. return new XSAnnotationImpl(contentBuffer.toString(), grammar);
  203. } else {
  204. return new XSAnnotationImpl(contents, grammar);
  205. }
  206. }
  207. // the QName simple type used to resolve qnames
  208. private static final XSSimpleType fQNameDV = (XSSimpleType)SchemaGrammar.SG_SchemaNS.getGlobalTypeDecl(SchemaSymbols.ATTVAL_QNAME);
  209. // Temp data structures to be re-used in traversing facets
  210. private StringBuffer fPattern = new StringBuffer();
  211. private final XSFacets xsFacets = new XSFacets();
  212. class FacetInfo {
  213. XSFacets facetdata;
  214. Element nodeAfterFacets;
  215. short fPresentFacets;
  216. short fFixedFacets;
  217. }
  218. FacetInfo traverseFacets(Element content,
  219. XSSimpleType baseValidator,
  220. XSDocumentInfo schemaDoc) {
  221. short facetsPresent = 0 ;
  222. short facetsFixed = 0; // facets that have fixed="true"
  223. String facet;
  224. boolean hasQName = containsQName(baseValidator);
  225. Vector enumData = null;
  226. XSObjectListImpl enumAnnotations = null;
  227. XSObjectListImpl patternAnnotations = null;
  228. Vector enumNSDecls = hasQName ? new Vector() : null;
  229. int currentFacet = 0;
  230. xsFacets.reset();
  231. while (content != null) {
  232. // General Attribute Checking
  233. Object[] attrs = null;
  234. facet = DOMUtil.getLocalName(content);
  235. if (facet.equals(SchemaSymbols.ELT_ENUMERATION)) {
  236. attrs = fAttrChecker.checkAttributes(content, false, schemaDoc, hasQName);
  237. String enumVal = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
  238. NamespaceSupport nsDecls = (NamespaceSupport)attrs[XSAttributeChecker.ATTIDX_ENUMNSDECLS];
  239. // for NOTATION types, need to check whether there is a notation
  240. // declared with the same name as the enumeration value.
  241. if (baseValidator.getVariety() == XSSimpleType.VARIETY_ATOMIC &&
  242. baseValidator.getPrimitiveKind() == XSSimpleType.PRIMITIVE_NOTATION) {
  243. // need to use the namespace context returned from checkAttributes
  244. schemaDoc.fValidationContext.setNamespaceSupport(nsDecls);
  245. try{
  246. QName temp = (QName)fQNameDV.validate(enumVal, schemaDoc.fValidationContext, null);
  247. // try to get the notation decl. if failed, getGlobalDecl
  248. // reports an error, so we don't need to report one again.
  249. fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.NOTATION_TYPE, temp, content);
  250. }catch(InvalidDatatypeValueException ex){
  251. reportSchemaError(ex.getKey(), ex.getArgs(), content);
  252. }
  253. // restore to the normal namespace context
  254. schemaDoc.fValidationContext.setNamespaceSupport(schemaDoc.fNamespaceSupport);
  255. }
  256. if (enumData == null){
  257. enumData = new Vector();
  258. enumAnnotations = new XSObjectListImpl();
  259. }
  260. enumData.addElement(enumVal);
  261. enumAnnotations.add(null);
  262. if (hasQName)
  263. enumNSDecls.addElement(nsDecls);
  264. Element child = DOMUtil.getFirstChildElement( content );
  265. if (child != null) {
  266. // traverse annotation if any
  267. if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
  268. enumAnnotations.add(enumAnnotations.getLength()-1,traverseAnnotationDecl(child, attrs, false, schemaDoc));
  269. child = DOMUtil.getNextSiblingElement(child);
  270. }
  271. if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
  272. reportSchemaError("s4s-elt-must-match.1", new Object[]{"enumeration", "(annotation?)", DOMUtil.getLocalName(child)}, child);
  273. }
  274. }
  275. }
  276. else if (facet.equals(SchemaSymbols.ELT_PATTERN)) {
  277. attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
  278. if (fPattern.length() == 0) {
  279. fPattern.append((String)attrs[XSAttributeChecker.ATTIDX_VALUE]);
  280. } else {
  281. // ---------------------------------------------
  282. //datatypes: 5.2.4 pattern: src-multiple-pattern
  283. // ---------------------------------------------
  284. fPattern.append("|");
  285. fPattern.append((String)attrs[XSAttributeChecker.ATTIDX_VALUE]);
  286. }
  287. Element child = DOMUtil.getFirstChildElement( content );
  288. if (child != null) {
  289. // traverse annotation if any
  290. if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
  291. if (patternAnnotations == null){
  292. patternAnnotations = new XSObjectListImpl();
  293. }
  294. patternAnnotations.add(traverseAnnotationDecl(child, attrs, false, schemaDoc));
  295. child = DOMUtil.getNextSiblingElement(child);
  296. }
  297. if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
  298. reportSchemaError("s4s-elt-must-match.1", new Object[]{"pattern", "(annotation?)", DOMUtil.getLocalName(child)}, child);
  299. }
  300. }
  301. }
  302. else {
  303. if (facet.equals(SchemaSymbols.ELT_MINLENGTH)) {
  304. currentFacet = XSSimpleType.FACET_MINLENGTH;
  305. }
  306. else if (facet.equals(SchemaSymbols.ELT_MAXLENGTH)) {
  307. currentFacet = XSSimpleType.FACET_MAXLENGTH;
  308. }
  309. else if (facet.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
  310. currentFacet = XSSimpleType.FACET_MAXEXCLUSIVE;
  311. }
  312. else if (facet.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
  313. currentFacet = XSSimpleType.FACET_MAXINCLUSIVE;
  314. }
  315. else if (facet.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
  316. currentFacet = XSSimpleType.FACET_MINEXCLUSIVE;
  317. }
  318. else if (facet.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
  319. currentFacet = XSSimpleType.FACET_MININCLUSIVE;
  320. }
  321. else if (facet.equals(SchemaSymbols.ELT_TOTALDIGITS)) {
  322. currentFacet = XSSimpleType.FACET_TOTALDIGITS;
  323. }
  324. else if (facet.equals(SchemaSymbols.ELT_FRACTIONDIGITS)) {
  325. currentFacet = XSSimpleType.FACET_FRACTIONDIGITS;
  326. }
  327. else if (facet.equals(SchemaSymbols.ELT_WHITESPACE)) {
  328. currentFacet = XSSimpleType.FACET_WHITESPACE;
  329. }
  330. else if (facet.equals(SchemaSymbols.ELT_LENGTH)) {
  331. currentFacet = XSSimpleType.FACET_LENGTH;
  332. }
  333. else {
  334. break; // a non-facet
  335. }
  336. attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
  337. // check for duplicate facets
  338. if ((facetsPresent & currentFacet) != 0) {
  339. reportSchemaError("src-single-facet-value", new Object[]{facet}, content);
  340. } else if (attrs[XSAttributeChecker.ATTIDX_VALUE] != null) {
  341. facetsPresent |= currentFacet;
  342. // check for fixed facet
  343. if (((Boolean)attrs[XSAttributeChecker.ATTIDX_FIXED]).booleanValue()) {
  344. facetsFixed |= currentFacet;
  345. }
  346. switch (currentFacet) {
  347. case XSSimpleType.FACET_MINLENGTH:
  348. xsFacets.minLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
  349. break;
  350. case XSSimpleType.FACET_MAXLENGTH:
  351. xsFacets.maxLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
  352. break;
  353. case XSSimpleType.FACET_MAXEXCLUSIVE:
  354. xsFacets.maxExclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
  355. break;
  356. case XSSimpleType.FACET_MAXINCLUSIVE:
  357. xsFacets.maxInclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
  358. break;
  359. case XSSimpleType.FACET_MINEXCLUSIVE:
  360. xsFacets.minExclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
  361. break;
  362. case XSSimpleType.FACET_MININCLUSIVE:
  363. xsFacets.minInclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
  364. break;
  365. case XSSimpleType.FACET_TOTALDIGITS:
  366. xsFacets.totalDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
  367. break;
  368. case XSSimpleType.FACET_FRACTIONDIGITS:
  369. xsFacets.fractionDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
  370. break;
  371. case XSSimpleType.FACET_WHITESPACE:
  372. xsFacets.whiteSpace = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).shortValue();
  373. break;
  374. case XSSimpleType.FACET_LENGTH:
  375. xsFacets.length = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
  376. break;
  377. }
  378. }
  379. Element child = DOMUtil.getFirstChildElement( content );
  380. if (child != null) {
  381. // traverse annotation if any
  382. if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
  383. XSAnnotationImpl annotation = traverseAnnotationDecl(child, attrs, false, schemaDoc);
  384. switch (currentFacet) {
  385. case XSSimpleType.FACET_MINLENGTH:
  386. xsFacets.minLengthAnnotation = annotation;
  387. break;
  388. case XSSimpleType.FACET_MAXLENGTH:
  389. xsFacets.maxLengthAnnotation = annotation;
  390. break;
  391. case XSSimpleType.FACET_MAXEXCLUSIVE:
  392. xsFacets.maxExclusiveAnnotation = annotation;
  393. break;
  394. case XSSimpleType.FACET_MAXINCLUSIVE:
  395. xsFacets.maxInclusiveAnnotation = annotation;
  396. break;
  397. case XSSimpleType.FACET_MINEXCLUSIVE:
  398. xsFacets.minExclusiveAnnotation = annotation;
  399. break;
  400. case XSSimpleType.FACET_MININCLUSIVE:
  401. xsFacets.minInclusiveAnnotation = annotation;
  402. break;
  403. case XSSimpleType.FACET_TOTALDIGITS:
  404. xsFacets.totalDigitsAnnotation = annotation;
  405. break;
  406. case XSSimpleType.FACET_FRACTIONDIGITS:
  407. xsFacets.fractionDigitsAnnotation = annotation;
  408. break;
  409. case XSSimpleType.FACET_WHITESPACE:
  410. xsFacets.whiteSpaceAnnotation = annotation;
  411. break;
  412. case XSSimpleType.FACET_LENGTH:
  413. xsFacets.lengthAnnotation = annotation;
  414. break;
  415. }
  416. child = DOMUtil.getNextSiblingElement(child);
  417. }
  418. if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
  419. reportSchemaError("s4s-elt-must-match.1", new Object[]{facet, "(annotation?)", DOMUtil.getLocalName(child)}, child);
  420. }
  421. }
  422. }
  423. fAttrChecker.returnAttrArray (attrs, schemaDoc);
  424. content = DOMUtil.getNextSiblingElement(content);
  425. }
  426. if (enumData !=null) {
  427. facetsPresent |= XSSimpleType.FACET_ENUMERATION;
  428. xsFacets.enumeration = enumData;
  429. xsFacets.enumNSDecls = enumNSDecls;
  430. xsFacets.enumAnnotations = enumAnnotations;
  431. }
  432. if (fPattern.length() != 0) {
  433. facetsPresent |= XSSimpleType.FACET_PATTERN;
  434. xsFacets.pattern = fPattern.toString();
  435. xsFacets.patternAnnotations = patternAnnotations;
  436. }
  437. fPattern.setLength(0);
  438. FacetInfo fi = new FacetInfo();
  439. fi.facetdata = xsFacets;
  440. fi.nodeAfterFacets = content;
  441. fi.fPresentFacets = facetsPresent;
  442. fi.fFixedFacets = facetsFixed;
  443. return fi;
  444. }
  445. // return whether QName/NOTATION is part of the given type
  446. private boolean containsQName(XSSimpleType type) {
  447. if (type.getVariety() == XSSimpleType.VARIETY_ATOMIC) {
  448. short primitive = type.getPrimitiveKind();
  449. return (primitive == XSSimpleType.PRIMITIVE_QNAME ||
  450. primitive == XSSimpleType.PRIMITIVE_NOTATION);
  451. }
  452. else if (type.getVariety() == XSSimpleType.VARIETY_LIST) {
  453. return containsQName((XSSimpleType)type.getItemType());
  454. }
  455. else if (type.getVariety() == XSSimpleType.VARIETY_UNION) {
  456. XSObjectList members = type.getMemberTypes();
  457. for (int i = 0; i < members.getLength(); i++) {
  458. if (containsQName((XSSimpleType)members.item(i)))
  459. return true;
  460. }
  461. }
  462. return false;
  463. }
  464. //
  465. // Traverse a set of attribute and attribute group elements
  466. // Needed by complexType and attributeGroup traversal
  467. // This method will return the first non-attribute/attrgrp found
  468. //
  469. Element traverseAttrsAndAttrGrps(Element firstAttr, XSAttributeGroupDecl attrGrp,
  470. XSDocumentInfo schemaDoc, SchemaGrammar grammar,
  471. XSComplexTypeDecl enclosingCT) {
  472. Element child=null;
  473. XSAttributeGroupDecl tempAttrGrp = null;
  474. XSAttributeUseImpl tempAttrUse = null;
  475. String childName;
  476. for (child=firstAttr; child!=null; child=DOMUtil.getNextSiblingElement(child)) {
  477. childName = DOMUtil.getLocalName(child);
  478. if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
  479. tempAttrUse = fSchemaHandler.fAttributeTraverser.traverseLocal(child,
  480. schemaDoc,
  481. grammar,
  482. enclosingCT);
  483. if (tempAttrUse == null) break;
  484. if (attrGrp.getAttributeUse(tempAttrUse.fAttrDecl.getNamespace(),
  485. tempAttrUse.fAttrDecl.getName())==null) {
  486. String idName = attrGrp.addAttributeUse(tempAttrUse);
  487. if (idName != null) {
  488. String code = (enclosingCT == null) ? "ag-props-correct.3" : "ct-props-correct.5";
  489. String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
  490. reportSchemaError(code, new Object[]{name, tempAttrUse.fAttrDecl.getName(), idName}, child);
  491. }
  492. }
  493. else {
  494. // REVISIT: what if one of the attribute uses is "prohibited"
  495. String code = (enclosingCT == null) ? "ag-props-correct.2" : "ct-props-correct.4";
  496. String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
  497. reportSchemaError(code, new Object[]{name, tempAttrUse.fAttrDecl.getName()}, child);
  498. }
  499. }
  500. else if (childName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
  501. //REVISIT: do we need to save some state at this point??
  502. tempAttrGrp = fSchemaHandler.fAttributeGroupTraverser.traverseLocal(
  503. child, schemaDoc, grammar);
  504. if(tempAttrGrp == null ) break;
  505. XSObjectList attrUseS = tempAttrGrp.getAttributeUses();
  506. XSAttributeUseImpl existingAttrUse = null, oneAttrUse;
  507. int attrCount = attrUseS.getLength();
  508. for (int i=0; i<attrCount; i++) {
  509. oneAttrUse = (XSAttributeUseImpl)attrUseS.item(i);
  510. if (existingAttrUse == attrGrp.getAttributeUse(oneAttrUse.fAttrDecl.getNamespace(),
  511. oneAttrUse.fAttrDecl.getName())) {
  512. String idName = attrGrp.addAttributeUse(oneAttrUse);
  513. if (idName != null) {
  514. String code = (enclosingCT == null) ? "ag-props-correct.3" : "ct-props-correct.5";
  515. String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
  516. reportSchemaError(code, new Object[]{name, oneAttrUse.fAttrDecl.getName(), idName}, child);
  517. }
  518. }
  519. else {
  520. // REVISIT: what if one of the attribute uses is "prohibited"
  521. String code = (enclosingCT == null) ? "ag-props-correct.2" : "ct-props-correct.4";
  522. String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
  523. reportSchemaError(code, new Object[]{name, oneAttrUse.fAttrDecl.getName()}, child);
  524. }
  525. }
  526. if (tempAttrGrp.fAttributeWC != null) {
  527. if (attrGrp.fAttributeWC == null) {
  528. attrGrp.fAttributeWC = tempAttrGrp.fAttributeWC;
  529. }
  530. // perform intersection of attribute wildcard
  531. else {
  532. attrGrp.fAttributeWC = attrGrp.fAttributeWC.
  533. performIntersectionWith(tempAttrGrp.fAttributeWC, attrGrp.fAttributeWC.fProcessContents);
  534. if (attrGrp.fAttributeWC == null) {
  535. String code = (enclosingCT == null) ? "src-attribute_group.2" : "src-ct.4";
  536. String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
  537. reportSchemaError(code, new Object[]{name}, child);
  538. }
  539. }
  540. }
  541. }
  542. else
  543. break;
  544. } // for
  545. if (child != null) {
  546. childName = DOMUtil.getLocalName(child);
  547. if (childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE)) {
  548. XSWildcardDecl tempAttrWC = fSchemaHandler.fWildCardTraverser.
  549. traverseAnyAttribute(child, schemaDoc, grammar);
  550. if (attrGrp.fAttributeWC == null) {
  551. attrGrp.fAttributeWC = tempAttrWC;
  552. }
  553. // perform intersection of attribute wildcard
  554. else {
  555. attrGrp.fAttributeWC = tempAttrWC.
  556. performIntersectionWith(attrGrp.fAttributeWC, tempAttrWC.fProcessContents);
  557. if (attrGrp.fAttributeWC == null) {
  558. String code = (enclosingCT == null) ? "src-attribute_group.2" : "src-ct.4";
  559. String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
  560. reportSchemaError(code, new Object[]{name}, child);
  561. }
  562. }
  563. child = DOMUtil.getNextSiblingElement(child);
  564. }
  565. }
  566. // Success
  567. return child;
  568. }
  569. void reportSchemaError (String key, Object[] args, Element ele) {
  570. fSchemaHandler.reportSchemaError(key, args, ele);
  571. }
  572. /**
  573. * Element/Attribute traversers call this method to check whether
  574. * the type is NOTATION without enumeration facet
  575. */
  576. void checkNotationType(String refName, XSTypeDefinition typeDecl, Element elem) {
  577. if (typeDecl.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE &&
  578. ((XSSimpleType)typeDecl).getVariety() == XSSimpleType.VARIETY_ATOMIC &&
  579. ((XSSimpleType)typeDecl).getPrimitiveKind() == XSSimpleType.PRIMITIVE_NOTATION) {
  580. if ((((XSSimpleType)typeDecl).getDefinedFacets() & XSSimpleType.FACET_ENUMERATION) == 0) {
  581. reportSchemaError("enumeration-required-notation", new Object[]{typeDecl.getName(), refName, DOMUtil.getLocalName(elem)}, elem);
  582. }
  583. }
  584. }
  585. // Checks constraints for minOccurs, maxOccurs
  586. protected XSParticleDecl checkOccurrences(XSParticleDecl particle,
  587. String particleName, Element parent,
  588. int allContextFlags,
  589. long defaultVals) {
  590. int min = particle.fMinOccurs;
  591. int max = particle.fMaxOccurs;
  592. boolean defaultMin = (defaultVals & (1 << XSAttributeChecker.ATTIDX_MINOCCURS)) != 0;
  593. boolean defaultMax = (defaultVals & (1 << XSAttributeChecker.ATTIDX_MAXOCCURS)) != 0;
  594. boolean processingAllEl = ((allContextFlags & PROCESSING_ALL_EL) != 0);
  595. boolean processingAllGP = ((allContextFlags & PROCESSING_ALL_GP) != 0);
  596. boolean groupRefWithAll = ((allContextFlags & GROUP_REF_WITH_ALL) != 0);
  597. boolean isGroupChild = ((allContextFlags & CHILD_OF_GROUP) != 0);
  598. // Neither minOccurs nor maxOccurs may be specified
  599. // for the child of a model group definition.
  600. if (isGroupChild) {
  601. if (!defaultMin) {
  602. Object[] args = new Object[]{particleName, "minOccurs"};
  603. reportSchemaError("s4s-att-not-allowed", args, parent);
  604. min = 1;
  605. }
  606. if (!defaultMax) {
  607. Object[] args = new Object[]{particleName, "maxOccurs"};
  608. reportSchemaError("s4s-att-not-allowed", args, parent);
  609. max = 1;
  610. }
  611. }
  612. // If minOccurs=maxOccurs=0, no component is specified
  613. if (min == 0 && max== 0) {
  614. particle.fType = XSParticleDecl.PARTICLE_EMPTY;
  615. return null;
  616. }
  617. // For the elements referenced in an <all>, minOccurs attribute
  618. // must be zero or one, and maxOccurs attribute must be one.
  619. // For a complex type definition that contains an <all> or a
  620. // reference a <group> whose model group is an all model group,
  621. // minOccurs and maxOccurs must be one.
  622. if (processingAllEl) {
  623. if (max != 1) {
  624. reportSchemaError("cos-all-limited.2", new Object[]{new Integer(max),
  625. ((XSElementDecl)particle.fValue).getName()}, parent);
  626. max = 1;
  627. if (min > 1)
  628. min = 1;
  629. }
  630. }
  631. else if (processingAllGP || groupRefWithAll) {
  632. if (max != 1) {
  633. reportSchemaError("cos-all-limited.1.2", null, parent);
  634. if (min > 1)
  635. min = 1;
  636. max = 1;
  637. }
  638. }
  639. particle.fMaxOccurs = min;
  640. particle.fMaxOccurs = max;
  641. return particle;
  642. }
  643. // this is not terribly performant!
  644. private static String processAttValue(String original) {
  645. // normally, nothing will happen
  646. StringBuffer newVal = new StringBuffer(original.length());
  647. for(int i=0; i<original.length(); i++) {
  648. char currChar = original.charAt(i);
  649. if(currChar == '"') {
  650. newVal.append(""");
  651. } else if (currChar == '>') {
  652. newVal.append(">");
  653. } else if (currChar == '&') {
  654. newVal.append("&");
  655. } else {
  656. newVal.append(currChar);
  657. }
  658. }
  659. return newVal.toString();
  660. }
  661. }