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 com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException;
  59. import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory;
  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.xs.SchemaGrammar;
  63. import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
  64. import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
  65. import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl;
  66. import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl;
  67. import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
  68. import com.sun.org.apache.xerces.internal.impl.xs.XSConstraints;
  69. import com.sun.org.apache.xerces.internal.impl.xs.XSModelGroupImpl;
  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.XSAttributeUse;
  73. import com.sun.org.apache.xerces.internal.xs.XSConstants;
  74. import com.sun.org.apache.xerces.internal.xs.XSObjectList;
  75. import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
  76. import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
  77. import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
  78. import com.sun.org.apache.xerces.internal.util.DOMUtil;
  79. import com.sun.org.apache.xerces.internal.xni.QName;
  80. import org.w3c.dom.Element;
  81. /**
  82. * A complex type definition schema component traverser.
  83. *
  84. * <complexType
  85. * abstract = boolean : false
  86. * block = (#all | List of (extension | restriction))
  87. * final = (#all | List of (extension | restriction))
  88. * id = ID
  89. * mixed = boolean : false
  90. * name = NCName
  91. * {any attributes with non-schema namespace . . .}>
  92. * Content: (annotation?, (simpleContent | complexContent |
  93. * ((group | all | choice | sequence)?,
  94. * ((attribute | attributeGroup)*, anyAttribute?))))
  95. * </complexType>
  96. * @version $Id: XSDComplexTypeTraverser.java,v 1.41 2003/11/11 20:15:00 sandygao Exp $
  97. */
  98. class XSDComplexTypeTraverser extends XSDAbstractParticleTraverser {
  99. // size of stack to hold globals:
  100. private final static int GLOBAL_NUM = 11;
  101. // globals for building XSComplexTypeDecls
  102. private String fName = null;
  103. private String fTargetNamespace = null;
  104. private short fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
  105. private short fFinal = XSConstants.DERIVATION_NONE;
  106. private short fBlock = XSConstants.DERIVATION_NONE;
  107. private short fContentType = XSComplexTypeDecl.CONTENTTYPE_EMPTY;
  108. private XSTypeDefinition fBaseType = null;
  109. private XSAttributeGroupDecl fAttrGrp = null;
  110. private XSSimpleType fXSSimpleType = null;
  111. private XSParticleDecl fParticle = null;
  112. private boolean fIsAbstract = false;
  113. private XSComplexTypeDecl fComplexTypeDecl = null;
  114. private XSAnnotationImpl [] fAnnotations = null;
  115. private XSParticleDecl fEmptyParticle = null;
  116. // our own little stack to retain state when getGlobalDecls is called:
  117. private Object [] fGlobalStore = null;
  118. private int fGlobalStorePos = 0;
  119. XSDComplexTypeTraverser (XSDHandler handler,
  120. XSAttributeChecker gAttrCheck) {
  121. super(handler, gAttrCheck);
  122. }
  123. private static final boolean DEBUG=false;
  124. private SchemaDVFactory schemaFactory = SchemaDVFactory.getInstance();
  125. private class ComplexTypeRecoverableError extends Exception {
  126. Object[] errorSubstText=null;
  127. Element errorElem = null;
  128. ComplexTypeRecoverableError() {
  129. super();
  130. }
  131. ComplexTypeRecoverableError(String msgKey, Object[] args, Element e) {
  132. super(msgKey);
  133. errorSubstText=args;
  134. errorElem = e;
  135. }
  136. }
  137. /**
  138. * Traverse local complexType declarations
  139. *
  140. * @param Element
  141. * @param XSDocumentInfo
  142. * @param SchemaGrammar
  143. * @return XSComplexTypeDecl
  144. */
  145. XSComplexTypeDecl traverseLocal(Element complexTypeNode,
  146. XSDocumentInfo schemaDoc,
  147. SchemaGrammar grammar) {
  148. Object[] attrValues = fAttrChecker.checkAttributes(complexTypeNode, false,
  149. schemaDoc);
  150. String complexTypeName = genAnonTypeName(complexTypeNode);
  151. contentBackup();
  152. XSComplexTypeDecl type = traverseComplexTypeDecl (complexTypeNode,
  153. complexTypeName, attrValues, schemaDoc, grammar);
  154. contentRestore();
  155. // need to add the type to the grammar for later constraint checking
  156. grammar.addComplexTypeDecl(type, fSchemaHandler.element2Locator(complexTypeNode));
  157. type.setIsAnonymous();
  158. fAttrChecker.returnAttrArray(attrValues, schemaDoc);
  159. return type;
  160. }
  161. /**
  162. * Traverse global complexType declarations
  163. *
  164. * @param Element
  165. * @param XSDocumentInfo
  166. * @param SchemaGrammar
  167. * @return XSComplexTypeDecXSComplexTypeDecl
  168. */
  169. XSComplexTypeDecl traverseGlobal (Element complexTypeNode,
  170. XSDocumentInfo schemaDoc,
  171. SchemaGrammar grammar) {
  172. Object[] attrValues = fAttrChecker.checkAttributes(complexTypeNode, true,
  173. schemaDoc);
  174. String complexTypeName = (String) attrValues[XSAttributeChecker.ATTIDX_NAME];
  175. contentBackup();
  176. XSComplexTypeDecl type = traverseComplexTypeDecl (complexTypeNode,
  177. complexTypeName, attrValues, schemaDoc, grammar);
  178. contentRestore();
  179. if (complexTypeName == null) {
  180. reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_COMPLEXTYPE, SchemaSymbols.ATT_NAME}, complexTypeNode);
  181. } else {
  182. grammar.addGlobalTypeDecl(type);
  183. }
  184. // need to add the type to the grammar for later constraint checking
  185. grammar.addComplexTypeDecl(type, fSchemaHandler.element2Locator(complexTypeNode));
  186. fAttrChecker.returnAttrArray(attrValues, schemaDoc);
  187. return type;
  188. }
  189. private XSComplexTypeDecl traverseComplexTypeDecl(Element complexTypeDecl,
  190. String complexTypeName,
  191. Object[] attrValues,
  192. XSDocumentInfo schemaDoc,
  193. SchemaGrammar grammar) {
  194. fComplexTypeDecl = new XSComplexTypeDecl();
  195. fAttrGrp = new XSAttributeGroupDecl();
  196. Boolean abstractAtt = (Boolean) attrValues[XSAttributeChecker.ATTIDX_ABSTRACT];
  197. XInt blockAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_BLOCK];
  198. Boolean mixedAtt = (Boolean) attrValues[XSAttributeChecker.ATTIDX_MIXED];
  199. XInt finalAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_FINAL];
  200. fName = complexTypeName;
  201. fComplexTypeDecl.setName(fName);
  202. fTargetNamespace = schemaDoc.fTargetNamespace;
  203. fBlock = blockAtt == null ? schemaDoc.fBlockDefault : blockAtt.shortValue();
  204. fFinal = finalAtt == null ? schemaDoc.fFinalDefault : finalAtt.shortValue();
  205. //discard valid Block/Final 'Default' values that are invalid for Block/Final
  206. fBlock &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION);
  207. fFinal &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION);
  208. if (abstractAtt != null && abstractAtt.booleanValue())
  209. fIsAbstract = true;
  210. Element child = null;
  211. try {
  212. // ---------------------------------------------------------------
  213. // First, handle any ANNOTATION declaration and get next child
  214. // ---------------------------------------------------------------
  215. child = DOMUtil.getFirstChildElement(complexTypeDecl);
  216. if (child != null) {
  217. // traverse annotation if any
  218. if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
  219. addAnnotation(traverseAnnotationDecl(child, attrValues, false, schemaDoc));
  220. child = DOMUtil.getNextSiblingElement(child);
  221. }
  222. if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
  223. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  224. new Object[]{fName,SchemaSymbols.ELT_ANNOTATION},
  225. child);
  226. }
  227. }
  228. // ---------------------------------------------------------------
  229. // Process the content of the complex type definition
  230. // ---------------------------------------------------------------
  231. if (child==null) {
  232. //
  233. // EMPTY complexType with complexContent
  234. //
  235. // set the base to the anyType
  236. fBaseType = SchemaGrammar.fAnyType;
  237. processComplexContent(child, mixedAtt.booleanValue(), false,
  238. schemaDoc, grammar);
  239. }
  240. else if (DOMUtil.getLocalName(child).equals
  241. (SchemaSymbols.ELT_SIMPLECONTENT)) {
  242. //
  243. // SIMPLE CONTENT
  244. //
  245. traverseSimpleContent(child, schemaDoc, grammar);
  246. Element elemTmp = DOMUtil.getNextSiblingElement(child);
  247. if (elemTmp != null) {
  248. String siblingName = DOMUtil.getLocalName(elemTmp);
  249. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  250. new Object[]{fName,siblingName},
  251. elemTmp);
  252. }
  253. }
  254. else if (DOMUtil.getLocalName(child).equals
  255. (SchemaSymbols.ELT_COMPLEXCONTENT)) {
  256. traverseComplexContent(child, mixedAtt.booleanValue(),
  257. schemaDoc, grammar);
  258. Element elemTmp = DOMUtil.getNextSiblingElement(child);
  259. if (elemTmp != null) {
  260. String siblingName = DOMUtil.getLocalName(elemTmp);
  261. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  262. new Object[]{fName,siblingName},
  263. elemTmp);
  264. }
  265. }
  266. else {
  267. //
  268. // We must have ....
  269. // GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes
  270. // Note that it's possible that only attributes are specified.
  271. //
  272. // set the base to the anyType
  273. fBaseType = SchemaGrammar.fAnyType;
  274. processComplexContent(child, mixedAtt.booleanValue(), false,
  275. schemaDoc, grammar);
  276. }
  277. }
  278. catch (ComplexTypeRecoverableError e) {
  279. handleComplexTypeError(e.getMessage(), e.errorSubstText,
  280. e.errorElem);
  281. }
  282. if (DEBUG) {
  283. System.out.println(fName);
  284. }
  285. fComplexTypeDecl.setValues(fName, fTargetNamespace, fBaseType,
  286. fDerivedBy, fFinal, fBlock, fContentType, fIsAbstract,
  287. fAttrGrp, fXSSimpleType, fParticle, new XSObjectListImpl(fAnnotations,
  288. fAnnotations == null? 0 : fAnnotations.length));
  289. return fComplexTypeDecl;
  290. }
  291. private void traverseSimpleContent(Element simpleContentElement,
  292. XSDocumentInfo schemaDoc,
  293. SchemaGrammar grammar)
  294. throws ComplexTypeRecoverableError {
  295. Object[] simpleContentAttrValues = fAttrChecker.checkAttributes(simpleContentElement, false,
  296. schemaDoc);
  297. // -----------------------------------------------------------------------
  298. // Set content type
  299. // -----------------------------------------------------------------------
  300. fContentType = XSComplexTypeDecl.CONTENTTYPE_SIMPLE;
  301. fParticle = null;
  302. Element simpleContent = DOMUtil.getFirstChildElement(simpleContentElement);
  303. if (simpleContent != null) {
  304. // traverse annotation if any
  305. if (DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)) {
  306. addAnnotation(traverseAnnotationDecl(simpleContent, simpleContentAttrValues, false, schemaDoc));
  307. simpleContent = DOMUtil.getNextSiblingElement(simpleContent);
  308. }
  309. }
  310. // If there are no children, return
  311. if (simpleContent==null) {
  312. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  313. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.2",
  314. new Object[]{fName,SchemaSymbols.ELT_SIMPLECONTENT},
  315. simpleContentElement);
  316. }
  317. // -----------------------------------------------------------------------
  318. // The content should be either "restriction" or "extension"
  319. // -----------------------------------------------------------------------
  320. String simpleContentName = DOMUtil.getLocalName(simpleContent);
  321. if (simpleContentName.equals(SchemaSymbols.ELT_RESTRICTION))
  322. fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
  323. else if (simpleContentName.equals(SchemaSymbols.ELT_EXTENSION))
  324. fDerivedBy = XSConstants.DERIVATION_EXTENSION;
  325. else {
  326. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  327. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  328. new Object[]{fName,simpleContentName},
  329. simpleContent);
  330. }
  331. Element elemTmp = DOMUtil.getNextSiblingElement(simpleContent);
  332. if (elemTmp != null) {
  333. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  334. String siblingName = DOMUtil.getLocalName(elemTmp);
  335. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  336. new Object[]{fName,siblingName},
  337. elemTmp);
  338. }
  339. Object [] derivationTypeAttrValues = fAttrChecker.checkAttributes(simpleContent, false,
  340. schemaDoc);
  341. QName baseTypeName = (QName) derivationTypeAttrValues[XSAttributeChecker.ATTIDX_BASE];
  342. // -----------------------------------------------------------------------
  343. // Need a base type.
  344. // -----------------------------------------------------------------------
  345. if (baseTypeName==null) {
  346. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  347. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  348. throw new ComplexTypeRecoverableError("s4s-att-must-appear",
  349. new Object[]{simpleContentName, "base"}, simpleContent);
  350. }
  351. XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc,
  352. XSDHandler.TYPEDECL_TYPE, baseTypeName,
  353. simpleContent);
  354. if (type==null) {
  355. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  356. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  357. throw new ComplexTypeRecoverableError();
  358. }
  359. fBaseType = type;
  360. XSSimpleType baseValidator = null;
  361. XSComplexTypeDecl baseComplexType = null;
  362. int baseFinalSet = 0;
  363. // If the base type is complex, it must have simpleContent
  364. if ((type.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE)) {
  365. baseComplexType = (XSComplexTypeDecl)type;
  366. baseFinalSet = baseComplexType.getFinal();
  367. // base is a CT with simple content (both restriction and extension are OK)
  368. if (baseComplexType.getContentType() == XSComplexTypeDecl.CONTENTTYPE_SIMPLE) {
  369. baseValidator = (XSSimpleType)baseComplexType.getSimpleType();
  370. }
  371. // base is a CT with mixed/emptiable content (only restriction is OK)
  372. else if (fDerivedBy == XSConstants.DERIVATION_RESTRICTION &&
  373. baseComplexType.getContentType() == XSComplexTypeDecl.CONTENTTYPE_MIXED &&
  374. ((XSParticleDecl)baseComplexType.getParticle()).emptiable()) {
  375. }
  376. else {
  377. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  378. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  379. throw new ComplexTypeRecoverableError("src-ct.2.1",
  380. new Object[]{fName, baseComplexType.getName()}, simpleContent);
  381. }
  382. }
  383. else {
  384. baseValidator = (XSSimpleType)type;
  385. // base is a ST (only extension is OK)
  386. if (fDerivedBy == XSConstants.DERIVATION_RESTRICTION) {
  387. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  388. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  389. throw new ComplexTypeRecoverableError("src-ct.2.1",
  390. new Object[]{fName, baseValidator.getName()}, simpleContent);
  391. }
  392. baseFinalSet=baseValidator.getFinal();
  393. }
  394. // -----------------------------------------------------------------------
  395. // Check that the base permits the derivation
  396. // -----------------------------------------------------------------------
  397. if ((baseFinalSet & fDerivedBy)!=0) {
  398. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  399. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  400. String errorKey = (fDerivedBy==XSConstants.DERIVATION_EXTENSION) ?
  401. "cos-ct-extends.1.1" : "derivation-ok-restriction.1";
  402. throw new ComplexTypeRecoverableError(errorKey,
  403. new Object[]{fName, fBaseType.getName()}, simpleContent);
  404. }
  405. // -----------------------------------------------------------------------
  406. // Skip over any potential annotations
  407. // -----------------------------------------------------------------------
  408. simpleContent = DOMUtil.getFirstChildElement(simpleContent);
  409. if (simpleContent != null) {
  410. // traverse annotation if any
  411. if (DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)) {
  412. addAnnotation(traverseAnnotationDecl(simpleContent, derivationTypeAttrValues, false, schemaDoc));
  413. simpleContent = DOMUtil.getNextSiblingElement(simpleContent);
  414. }
  415. if (simpleContent !=null &&
  416. DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)){
  417. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  418. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  419. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  420. new Object[]{fName,SchemaSymbols.ELT_ANNOTATION},
  421. simpleContent);
  422. }
  423. }
  424. // -----------------------------------------------------------------------
  425. // Process a RESTRICTION
  426. // -----------------------------------------------------------------------
  427. if (fDerivedBy == XSConstants.DERIVATION_RESTRICTION) {
  428. // -----------------------------------------------------------------------
  429. // There may be a simple type definition in the restriction element
  430. // The data type validator will be based on it, if specified
  431. // -----------------------------------------------------------------------
  432. if (simpleContent !=null &&
  433. DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_SIMPLETYPE )) {
  434. XSSimpleType dv = fSchemaHandler.fSimpleTypeTraverser.traverseLocal(
  435. simpleContent, schemaDoc, grammar);
  436. if (dv == null) {
  437. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  438. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  439. throw new ComplexTypeRecoverableError();
  440. }
  441. //check that this datatype validator is validly derived from the base
  442. //according to derivation-ok-restriction 5.1.2.1
  443. if (baseValidator != null &&
  444. !XSConstraints.checkSimpleDerivationOk(dv, baseValidator,
  445. baseValidator.getFinal())) {
  446. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  447. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  448. throw new ComplexTypeRecoverableError("derivation-ok-restriction.5.2.2.1",
  449. new Object[]{fName, dv.getName(), baseValidator.getName()},
  450. simpleContent);
  451. }
  452. baseValidator = dv;
  453. simpleContent = DOMUtil.getNextSiblingElement(simpleContent);
  454. }
  455. // this only happens when restricting a mixed/emptiable CT
  456. // but there is no <simpleType>, which is required
  457. if (baseValidator == null) {
  458. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  459. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  460. throw new ComplexTypeRecoverableError("src-ct.2.2",
  461. new Object[]{fName}, simpleContent);
  462. }
  463. // -----------------------------------------------------------------------
  464. // Traverse any facets
  465. // -----------------------------------------------------------------------
  466. Element attrNode = null;
  467. XSFacets facetData = null;
  468. short presentFacets = 0 ;
  469. short fixedFacets = 0 ;
  470. if (simpleContent!=null) {
  471. FacetInfo fi = traverseFacets(simpleContent, baseValidator, schemaDoc);
  472. attrNode = fi.nodeAfterFacets;
  473. facetData = fi.facetdata;
  474. presentFacets = fi.fPresentFacets;
  475. fixedFacets = fi.fFixedFacets;
  476. }
  477. fXSSimpleType = schemaFactory.createTypeRestriction(null,schemaDoc.fTargetNamespace,(short)0,baseValidator,null);
  478. try{
  479. fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport);
  480. fXSSimpleType.applyFacets(facetData, presentFacets, fixedFacets, fValidationState);
  481. }catch(InvalidDatatypeFacetException ex){
  482. reportSchemaError(ex.getKey(), ex.getArgs(), simpleContent);
  483. }
  484. // -----------------------------------------------------------------------
  485. // Traverse any attributes
  486. // -----------------------------------------------------------------------
  487. if (attrNode != null) {
  488. if (!isAttrOrAttrGroup(attrNode)) {
  489. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  490. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  491. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  492. new Object[]{fName,DOMUtil.getLocalName(attrNode)},
  493. attrNode);
  494. }
  495. Element node=traverseAttrsAndAttrGrps(attrNode,fAttrGrp,
  496. schemaDoc,grammar,fComplexTypeDecl);
  497. if (node!=null) {
  498. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  499. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  500. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  501. new Object[]{fName,DOMUtil.getLocalName(node)},
  502. node);
  503. }
  504. }
  505. try {
  506. mergeAttributes(baseComplexType.getAttrGrp(), fAttrGrp, fName, false, simpleContentElement);
  507. } catch (ComplexTypeRecoverableError e) {
  508. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  509. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  510. throw e;
  511. }
  512. // Prohibited uses must be removed after merge for RESTRICTION
  513. fAttrGrp.removeProhibitedAttrs();
  514. Object[] errArgs=fAttrGrp.validRestrictionOf(fName, baseComplexType.getAttrGrp());
  515. if (errArgs != null) {
  516. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  517. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  518. throw new ComplexTypeRecoverableError((String)errArgs[errArgs.length-1],
  519. errArgs, attrNode);
  520. }
  521. }
  522. // -----------------------------------------------------------------------
  523. // Process a EXTENSION
  524. // -----------------------------------------------------------------------
  525. else {
  526. fXSSimpleType = baseValidator;
  527. if (simpleContent != null) {
  528. // -----------------------------------------------------------------------
  529. // Traverse any attributes
  530. // -----------------------------------------------------------------------
  531. Element attrNode = simpleContent;
  532. if (!isAttrOrAttrGroup(attrNode)) {
  533. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  534. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  535. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  536. new Object[]{fName,DOMUtil.getLocalName(attrNode)},
  537. attrNode);
  538. }
  539. Element node=traverseAttrsAndAttrGrps(attrNode,fAttrGrp,
  540. schemaDoc,grammar,fComplexTypeDecl);
  541. if (node!=null) {
  542. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  543. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  544. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  545. new Object[]{fName,DOMUtil.getLocalName(node)},
  546. node);
  547. }
  548. // Remove prohibited uses. Should be done prior to any merge.
  549. fAttrGrp.removeProhibitedAttrs();
  550. }
  551. if (baseComplexType != null) {
  552. try {
  553. mergeAttributes(baseComplexType.getAttrGrp(), fAttrGrp, fName, true, simpleContentElement);
  554. } catch (ComplexTypeRecoverableError e) {
  555. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  556. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  557. throw e;
  558. }
  559. }
  560. }
  561. // and finally, since we've nothing more to traverse, we can
  562. // return the attributes (and thereby reset the namespace support)
  563. fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
  564. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  565. }
  566. private void traverseComplexContent(Element complexContentElement,
  567. boolean mixedOnType, XSDocumentInfo schemaDoc,
  568. SchemaGrammar grammar)
  569. throws ComplexTypeRecoverableError {
  570. Object[] complexContentAttrValues = fAttrChecker.checkAttributes(complexContentElement, false,
  571. schemaDoc);
  572. // -----------------------------------------------------------------------
  573. // Determine if this is mixed content
  574. // -----------------------------------------------------------------------
  575. boolean mixedContent = mixedOnType;
  576. Boolean mixedAtt = (Boolean) complexContentAttrValues[XSAttributeChecker.ATTIDX_MIXED];
  577. if (mixedAtt != null) {
  578. mixedContent = mixedAtt.booleanValue();
  579. }
  580. // -----------------------------------------------------------------------
  581. // Since the type must have complex content, set the simple type validators
  582. // to null
  583. // -----------------------------------------------------------------------
  584. fXSSimpleType = null;
  585. Element complexContent = DOMUtil.getFirstChildElement(complexContentElement);
  586. if (complexContent != null) {
  587. // traverse annotation if any
  588. if (DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)) {
  589. addAnnotation(traverseAnnotationDecl(complexContent, complexContentAttrValues, false, schemaDoc));
  590. complexContent = DOMUtil.getNextSiblingElement(complexContent);
  591. }
  592. }
  593. // If there are no children, return
  594. if (complexContent==null) {
  595. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  596. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.2",
  597. new Object[]{fName,SchemaSymbols.ELT_COMPLEXCONTENT},
  598. complexContentElement);
  599. }
  600. // -----------------------------------------------------------------------
  601. // The content should be either "restriction" or "extension"
  602. // -----------------------------------------------------------------------
  603. String complexContentName = DOMUtil.getLocalName(complexContent);
  604. if (complexContentName.equals(SchemaSymbols.ELT_RESTRICTION))
  605. fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
  606. else if (complexContentName.equals(SchemaSymbols.ELT_EXTENSION))
  607. fDerivedBy = XSConstants.DERIVATION_EXTENSION;
  608. else {
  609. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  610. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  611. new Object[]{fName, complexContentName}, complexContent);
  612. }
  613. Element elemTmp = DOMUtil.getNextSiblingElement(complexContent);
  614. if (elemTmp != null) {
  615. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  616. String siblingName = DOMUtil.getLocalName(elemTmp);
  617. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  618. new Object[]{fName, siblingName}, elemTmp);
  619. }
  620. Object[] derivationTypeAttrValues = fAttrChecker.checkAttributes(complexContent, false,
  621. schemaDoc);
  622. QName baseTypeName = (QName) derivationTypeAttrValues[XSAttributeChecker.ATTIDX_BASE];
  623. // -----------------------------------------------------------------------
  624. // Need a base type. Check that it's a complex type
  625. // -----------------------------------------------------------------------
  626. if (baseTypeName==null) {
  627. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  628. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  629. throw new ComplexTypeRecoverableError("s4s-att-must-appear",
  630. new Object[]{complexContentName, "base"}, complexContent);
  631. }
  632. XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc,
  633. XSDHandler.TYPEDECL_TYPE,
  634. baseTypeName,
  635. complexContent);
  636. if (type==null) {
  637. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  638. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  639. throw new ComplexTypeRecoverableError();
  640. }
  641. if (! (type instanceof XSComplexTypeDecl)) {
  642. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  643. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  644. throw new ComplexTypeRecoverableError("src-ct.1",
  645. new Object[]{fName, type.getName()}, complexContent);
  646. }
  647. XSComplexTypeDecl baseType = (XSComplexTypeDecl)type;
  648. fBaseType = baseType;
  649. // -----------------------------------------------------------------------
  650. // Check that the base permits the derivation
  651. // -----------------------------------------------------------------------
  652. if ((baseType.getFinal() & fDerivedBy)!=0) {
  653. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  654. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  655. String errorKey = (fDerivedBy==XSConstants.DERIVATION_EXTENSION) ?
  656. "cos-ct-extends.1.1" : "derivation-ok-restriction.1";
  657. throw new ComplexTypeRecoverableError(errorKey,
  658. new Object[]{fName, fBaseType.getName()}, complexContent);
  659. }
  660. // -----------------------------------------------------------------------
  661. // Skip over any potential annotations
  662. // -----------------------------------------------------------------------
  663. complexContent = DOMUtil.getFirstChildElement(complexContent);
  664. if (complexContent != null) {
  665. // traverse annotation if any
  666. if (DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)) {
  667. addAnnotation(traverseAnnotationDecl(complexContent, derivationTypeAttrValues, false, schemaDoc));
  668. complexContent = DOMUtil.getNextSiblingElement(complexContent);
  669. }
  670. if (complexContent !=null &&
  671. DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)){
  672. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  673. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  674. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  675. new Object[]{fName,SchemaSymbols.ELT_ANNOTATION}, complexContent);
  676. }
  677. }
  678. // -----------------------------------------------------------------------
  679. // Process the content. Note: should I try to catch any complexType errors
  680. // here in order to return the attr array?
  681. // -----------------------------------------------------------------------
  682. try {
  683. processComplexContent(complexContent, mixedContent, true, schemaDoc,
  684. grammar);
  685. } catch (ComplexTypeRecoverableError e) {
  686. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  687. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  688. throw e;
  689. }
  690. // -----------------------------------------------------------------------
  691. // Compose the final content and attribute uses
  692. // -----------------------------------------------------------------------
  693. XSParticleDecl baseContent = (XSParticleDecl)baseType.getParticle();
  694. if (fDerivedBy==XSConstants.DERIVATION_RESTRICTION) {
  695. // This is an RESTRICTION
  696. // N.B. derivation-ok-restriction.5.3 is checked under schema
  697. // full checking. That's because we need to wait until locals are
  698. // traversed so that occurrence information is correct.
  699. if (fContentType == XSComplexTypeDecl.CONTENTTYPE_MIXED &&
  700. baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_MIXED) {
  701. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  702. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  703. throw new ComplexTypeRecoverableError("derivation-ok-restriction.5.4.1.2",
  704. new Object[]{fName, baseType.getName()},
  705. complexContent);
  706. }
  707. try {
  708. mergeAttributes(baseType.getAttrGrp(), fAttrGrp, fName, false, complexContent);
  709. } catch (ComplexTypeRecoverableError e) {
  710. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  711. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  712. throw e;
  713. }
  714. // Remove prohibited uses. Must be done after merge for RESTRICTION.
  715. fAttrGrp.removeProhibitedAttrs();
  716. if (baseType != SchemaGrammar.fAnyType) {
  717. Object[] errArgs = fAttrGrp.validRestrictionOf(fName, baseType.getAttrGrp());
  718. if (errArgs != null) {
  719. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  720. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  721. throw new ComplexTypeRecoverableError((String)errArgs[errArgs.length-1],
  722. errArgs, complexContent);
  723. }
  724. }
  725. }
  726. else {
  727. // This is an EXTENSION
  728. // Create the particle
  729. if (fParticle == null) {
  730. fContentType = baseType.getContentType();
  731. fXSSimpleType = (XSSimpleType)baseType.getSimpleType();
  732. fParticle = baseContent;
  733. }
  734. else if (baseType.getContentType() == XSComplexTypeDecl.CONTENTTYPE_EMPTY) {
  735. }
  736. else {
  737. //
  738. // Check if the contentType of the base is consistent with the new type
  739. // cos-ct-extends.1.4.3.2
  740. if (fContentType == XSComplexTypeDecl.CONTENTTYPE_ELEMENT &&
  741. baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_ELEMENT) {
  742. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  743. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  744. throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.3.2.2.1.a",
  745. new Object[]{fName}, complexContent);
  746. }
  747. else if (fContentType == XSComplexTypeDecl.CONTENTTYPE_MIXED &&
  748. baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_MIXED) {
  749. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  750. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  751. throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.3.2.2.1.b",
  752. new Object[]{fName}, complexContent);
  753. }
  754. // if the content of either type is an "all" model group, error.
  755. if (fParticle.fType == XSParticleDecl.PARTICLE_MODELGROUP &&
  756. ((XSModelGroupImpl)fParticle.fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL ||
  757. ((XSParticleDecl)baseType.getParticle()).fType == XSParticleDecl.PARTICLE_MODELGROUP &&
  758. ((XSModelGroupImpl)(((XSParticleDecl)baseType.getParticle())).fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL) {
  759. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  760. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  761. throw new ComplexTypeRecoverableError("cos-all-limited.1.2",
  762. new Object[]{}, complexContent);
  763. }
  764. // the "sequence" model group to contain both particles
  765. XSModelGroupImpl group = new XSModelGroupImpl();
  766. group.fCompositor = XSModelGroupImpl.MODELGROUP_SEQUENCE;
  767. group.fParticleCount = 2;
  768. group.fParticles = new XSParticleDecl[2];
  769. group.fParticles[0] = (XSParticleDecl)baseType.getParticle();
  770. group.fParticles[1] = fParticle;
  771. // the particle to contain the above sequence
  772. XSParticleDecl particle = new XSParticleDecl();
  773. particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
  774. particle.fValue = group;
  775. fParticle = particle;
  776. }
  777. // Remove prohibited uses. Must be done before merge for EXTENSION.
  778. fAttrGrp.removeProhibitedAttrs();
  779. try {
  780. mergeAttributes(baseType.getAttrGrp(), fAttrGrp, fName, true, complexContent);
  781. } catch (ComplexTypeRecoverableError e) {
  782. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  783. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  784. throw e;
  785. }
  786. }
  787. // and *finally* we can legitimately return the attributes!
  788. fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
  789. fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
  790. } // end of traverseComplexContent
  791. // This method merges attribute uses from the base, into the derived set.
  792. // The first duplicate attribute, if any, is returned.
  793. // LM: may want to merge with attributeGroup processing.
  794. private void mergeAttributes(XSAttributeGroupDecl fromAttrGrp,
  795. XSAttributeGroupDecl toAttrGrp,
  796. String typeName,
  797. boolean extension,
  798. Element elem)
  799. throws ComplexTypeRecoverableError {
  800. XSObjectList attrUseS = fromAttrGrp.getAttributeUses();
  801. XSAttributeUseImpl duplicateAttrUse = null, oneAttrUse = null;
  802. int attrCount = attrUseS.getLength();
  803. for (int i=0; i<attrCount; i++) {
  804. oneAttrUse = (XSAttributeUseImpl)attrUseS.item(i);
  805. XSAttributeUse existingAttrUse = toAttrGrp.getAttributeUse(oneAttrUse.fAttrDecl.getNamespace(),
  806. oneAttrUse.fAttrDecl.getName());
  807. if (existingAttrUse == null) {
  808. String idName = toAttrGrp.addAttributeUse(oneAttrUse);
  809. if (idName != null) {
  810. throw new ComplexTypeRecoverableError("ct-props-correct.5",
  811. new Object[]{typeName, idName, oneAttrUse.fAttrDecl.getName()},
  812. elem);
  813. }
  814. }
  815. else {
  816. if (extension) {
  817. throw new ComplexTypeRecoverableError("ct-props-correct.4",
  818. new Object[]{typeName, oneAttrUse.fAttrDecl.getName()},
  819. elem);
  820. }
  821. }
  822. }
  823. // For extension, the wildcard must be formed by doing a union of the wildcards
  824. if (extension) {
  825. if (toAttrGrp.fAttributeWC==null) {
  826. toAttrGrp.fAttributeWC = fromAttrGrp.fAttributeWC;
  827. }
  828. else if (fromAttrGrp.fAttributeWC != null) {
  829. toAttrGrp.fAttributeWC = toAttrGrp.fAttributeWC.performUnionWith(fromAttrGrp.fAttributeWC, toAttrGrp.fAttributeWC.fProcessContents);
  830. }
  831. }
  832. }
  833. private void processComplexContent(Element complexContentChild,
  834. boolean isMixed, boolean isDerivation,
  835. XSDocumentInfo schemaDoc, SchemaGrammar grammar)
  836. throws ComplexTypeRecoverableError {
  837. Element attrNode = null;
  838. XSParticleDecl particle = null;
  839. // whether there is a particle with empty model group
  840. boolean emptyParticle = false;
  841. if (complexContentChild != null) {
  842. // -------------------------------------------------------------
  843. // GROUP, ALL, SEQUENCE or CHOICE, followed by attributes, if specified.
  844. // Note that it's possible that only attributes are specified.
  845. // -------------------------------------------------------------
  846. String childName = DOMUtil.getLocalName(complexContentChild);
  847. if (childName.equals(SchemaSymbols.ELT_GROUP)) {
  848. particle = fSchemaHandler.fGroupTraverser.traverseLocal(complexContentChild,
  849. schemaDoc, grammar);
  850. attrNode = DOMUtil.getNextSiblingElement(complexContentChild);
  851. }
  852. else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
  853. particle = traverseSequence(complexContentChild,schemaDoc,grammar,
  854. NOT_ALL_CONTEXT,fComplexTypeDecl);
  855. if (particle != null) {
  856. XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue;
  857. if (group.fParticleCount == 0)
  858. emptyParticle = true;
  859. }
  860. attrNode = DOMUtil.getNextSiblingElement(complexContentChild);
  861. }
  862. else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
  863. particle = traverseChoice(complexContentChild,schemaDoc,grammar,
  864. NOT_ALL_CONTEXT,fComplexTypeDecl);
  865. if (particle != null && particle.fMinOccurs == 0) {
  866. XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue;
  867. if (group.fParticleCount == 0)
  868. emptyParticle = true;
  869. }
  870. attrNode = DOMUtil.getNextSiblingElement(complexContentChild);
  871. }
  872. else if (childName.equals(SchemaSymbols.ELT_ALL)) {
  873. particle = traverseAll(complexContentChild,schemaDoc,grammar,
  874. PROCESSING_ALL_GP,fComplexTypeDecl);
  875. if (particle != null) {
  876. XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue;
  877. if (group.fParticleCount == 0)
  878. emptyParticle = true;
  879. }
  880. attrNode = DOMUtil.getNextSiblingElement(complexContentChild);
  881. }
  882. else {
  883. // Should be attributes here - will check below...
  884. attrNode = complexContentChild;
  885. }
  886. }
  887. // if the particle is empty because there is no non-annotation chidren,
  888. // we need to make the particle itself null (so that the effective
  889. // content is empty).
  890. if (emptyParticle) {
  891. // get the first child
  892. Element child = DOMUtil.getFirstChildElement(complexContentChild);
  893. // if it's annotation, get the next one
  894. if (child != null) {
  895. if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
  896. child = DOMUtil.getNextSiblingElement(child);
  897. }
  898. }
  899. // if there is no (non-annotation) children, mark particle empty
  900. if (child == null)
  901. particle = null;
  902. // child != null means we might have seen an element with
  903. // minOccurs == maxOccurs == 0
  904. }
  905. if (particle == null && isMixed) {
  906. if (fEmptyParticle == null) {
  907. XSModelGroupImpl group = new XSModelGroupImpl();
  908. group.fCompositor = XSModelGroupImpl.MODELGROUP_SEQUENCE;
  909. group.fParticleCount = 0;
  910. group.fParticles = null;
  911. fEmptyParticle = new XSParticleDecl();
  912. fEmptyParticle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
  913. fEmptyParticle.fValue = group;
  914. }
  915. particle = fEmptyParticle;
  916. }
  917. fParticle = particle;
  918. // -----------------------------------------------------------------------
  919. // Set the content type
  920. // -----------------------------------------------------------------------
  921. if (fParticle == null)
  922. fContentType = XSComplexTypeDecl.CONTENTTYPE_EMPTY;
  923. else if (isMixed)
  924. fContentType = XSComplexTypeDecl.CONTENTTYPE_MIXED;
  925. else
  926. fContentType = XSComplexTypeDecl.CONTENTTYPE_ELEMENT;
  927. // -------------------------------------------------------------
  928. // Now, process attributes
  929. // -------------------------------------------------------------
  930. if (attrNode != null) {
  931. if (!isAttrOrAttrGroup(attrNode)) {
  932. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  933. new Object[]{fName,DOMUtil.getLocalName(attrNode)},
  934. attrNode);
  935. }
  936. Element node =
  937. traverseAttrsAndAttrGrps(attrNode,fAttrGrp,schemaDoc,grammar,fComplexTypeDecl);
  938. if (node!=null) {
  939. throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
  940. new Object[]{fName,DOMUtil.getLocalName(node)},
  941. node);
  942. }
  943. // Only remove prohibited attribute uses if this isn't a derived type
  944. // Derivation-specific code worries about this elsewhere
  945. if (!isDerivation) {
  946. fAttrGrp.removeProhibitedAttrs();
  947. }
  948. }
  949. } // end processComplexContent
  950. private boolean isAttrOrAttrGroup(Element e) {
  951. String elementName = DOMUtil.getLocalName(e);
  952. if (elementName.equals(SchemaSymbols.ELT_ATTRIBUTE) ||
  953. elementName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) ||
  954. elementName.equals(SchemaSymbols.ELT_ANYATTRIBUTE))
  955. return true;
  956. else
  957. return false;
  958. }
  959. private void traverseSimpleContentDecl(Element simpleContentDecl) {
  960. }
  961. private void traverseComplexContentDecl(Element complexContentDecl,
  962. boolean mixedOnComplexTypeDecl) {
  963. }
  964. /*
  965. * Generate a name for an anonymous type
  966. */
  967. private String genAnonTypeName(Element complexTypeDecl) {
  968. // Generate a unique name for the anonymous type by concatenating together the
  969. // names of parent nodes
  970. // The name is quite good for debugging/error purposes, but we may want to
  971. // revisit how this is done for performance reasons (LM).
  972. String typeName;
  973. Element node = DOMUtil.getParent(complexTypeDecl);
  974. typeName="#AnonType_";
  975. while (node != null && (node != DOMUtil.getRoot(DOMUtil.getDocument(node)))) {
  976. typeName = typeName+node.getAttribute(SchemaSymbols.ATT_NAME);
  977. node = DOMUtil.getParent(node);
  978. }
  979. return typeName;
  980. }
  981. private void handleComplexTypeError(String messageId,Object[] args,
  982. Element e) {
  983. if (messageId!=null) {
  984. reportSchemaError(messageId, args, e);
  985. }
  986. //
  987. // Mock up the typeInfo structure so that there won't be problems during
  988. // validation
  989. //
  990. fBaseType = SchemaGrammar.fAnyType;
  991. fContentType = XSComplexTypeDecl.CONTENTTYPE_MIXED;
  992. fParticle = getErrorContent();
  993. // REVISIT: do we need to remove all attribute uses already added into
  994. // the attribute group? maybe it's ok to leave them there. -SG
  995. fAttrGrp.fAttributeWC = getErrorWildcard();
  996. return;
  997. }
  998. private XSParticleDecl getErrorContent() {
  999. XSParticleDecl particle = new XSParticleDecl();
  1000. particle.fType = XSParticleDecl.PARTICLE_WILDCARD;
  1001. particle.fValue = getErrorWildcard();
  1002. particle.fMinOccurs = 0;
  1003. particle.fMaxOccurs = SchemaSymbols.OCCURRENCE_UNBOUNDED;
  1004. XSModelGroupImpl group = new XSModelGroupImpl();
  1005. group.fCompositor = XSModelGroupImpl.MODELGROUP_SEQUENCE;
  1006. group.fParticleCount = 1;
  1007. group.fParticles = new XSParticleDecl[1];
  1008. group.fParticles[0] = particle;
  1009. XSParticleDecl errorContent = new XSParticleDecl();
  1010. errorContent.fType = XSParticleDecl.PARTICLE_MODELGROUP;
  1011. errorContent.fValue = group;
  1012. return errorContent;
  1013. }
  1014. private XSWildcardDecl getErrorWildcard() {
  1015. XSWildcardDecl errorWildcard = new XSWildcardDecl();
  1016. errorWildcard.fProcessContents = XSWildcardDecl.PC_SKIP;
  1017. return errorWildcard;
  1018. }
  1019. private void contentBackup() {
  1020. if(fGlobalStore == null) {
  1021. fGlobalStore = new Object [GLOBAL_NUM];
  1022. fGlobalStorePos = 0;
  1023. }
  1024. if(fGlobalStorePos == fGlobalStore.length) {
  1025. Object [] newArray = new Object[fGlobalStorePos+GLOBAL_NUM];
  1026. System.arraycopy(fGlobalStore, 0, newArray, 0, fGlobalStorePos);
  1027. fGlobalStore = newArray;
  1028. }
  1029. fGlobalStore[fGlobalStorePos++] = fComplexTypeDecl;
  1030. fGlobalStore[fGlobalStorePos++] = fIsAbstract?Boolean.TRUE:Boolean.FALSE;
  1031. fGlobalStore[fGlobalStorePos++] = fName ;
  1032. fGlobalStore[fGlobalStorePos++] = fTargetNamespace;
  1033. // let's save ourselves a couple of objects...
  1034. fGlobalStore[fGlobalStorePos++] = new Integer((fDerivedBy << 16) + fFinal);
  1035. fGlobalStore[fGlobalStorePos++] = new Integer((fBlock << 16) + fContentType);
  1036. fGlobalStore[fGlobalStorePos++] = fBaseType;
  1037. fGlobalStore[fGlobalStorePos++] = fAttrGrp;
  1038. fGlobalStore[fGlobalStorePos++] = fParticle;
  1039. fGlobalStore[fGlobalStorePos++] = fXSSimpleType;
  1040. fGlobalStore[fGlobalStorePos++] = fAnnotations;
  1041. }
  1042. private void contentRestore() {
  1043. fAnnotations = (XSAnnotationImpl [])fGlobalStore[--fGlobalStorePos];
  1044. fXSSimpleType = (XSSimpleType)fGlobalStore[--fGlobalStorePos];
  1045. fParticle = (XSParticleDecl)fGlobalStore[--fGlobalStorePos];
  1046. fAttrGrp = (XSAttributeGroupDecl)fGlobalStore[--fGlobalStorePos];
  1047. fBaseType = (XSTypeDefinition)fGlobalStore[--fGlobalStorePos];
  1048. int i = ((Integer)(fGlobalStore[--fGlobalStorePos])).intValue();
  1049. fBlock = (short)(i >> 16);
  1050. fContentType = (short)i;
  1051. i = ((Integer)(fGlobalStore[--fGlobalStorePos])).intValue();
  1052. fDerivedBy = (short)(i >> 16);
  1053. fFinal = (short)i;
  1054. fTargetNamespace = (String)fGlobalStore[--fGlobalStorePos];
  1055. fName = (String)fGlobalStore[--fGlobalStorePos];
  1056. fIsAbstract = ((Boolean)fGlobalStore[--fGlobalStorePos]).booleanValue();
  1057. fComplexTypeDecl = (XSComplexTypeDecl)fGlobalStore[--fGlobalStorePos];
  1058. }
  1059. private void addAnnotation(XSAnnotationImpl annotation) {
  1060. if(annotation == null)
  1061. return;
  1062. // it isn't very likely that there will be more than one annotation
  1063. // in a complexType decl. This saves us fromhaving to push/pop
  1064. // one more object from the fGlobalStore, and that's bound
  1065. // to be a savings for most applications
  1066. if(fAnnotations == null) {
  1067. fAnnotations = new XSAnnotationImpl[1];
  1068. } else {
  1069. XSAnnotationImpl [] tempArray = new XSAnnotationImpl[fAnnotations.length + 1];
  1070. System.arraycopy(fAnnotations, 0, tempArray, 0, fAnnotations.length);
  1071. fAnnotations = tempArray;
  1072. }
  1073. fAnnotations[fAnnotations.length-1] = annotation;
  1074. }
  1075. }