XMLSchemaBuilder.java 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. /* XMLSchemaBuilder.java --
  2. Copyright (C) 2006 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package gnu.xml.validation.xmlschema;
  32. import java.util.LinkedHashSet;
  33. import java.util.Set;
  34. import java.util.StringTokenizer;
  35. import javax.xml.XMLConstants;
  36. import javax.xml.namespace.QName;
  37. import org.relaxng.datatype.DatatypeException;
  38. import org.relaxng.datatype.DatatypeLibrary;
  39. import org.relaxng.datatype.helpers.DatatypeLibraryLoader;
  40. import org.w3c.dom.NamedNodeMap;
  41. import org.w3c.dom.Node;
  42. import gnu.xml.validation.datatype.Annotation;
  43. import gnu.xml.validation.datatype.SimpleType;
  44. import gnu.xml.validation.datatype.Type;
  45. /**
  46. * Parses an XML Schema DOM tree, constructing a compiled internal
  47. * representation.
  48. *
  49. * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
  50. */
  51. class XMLSchemaBuilder
  52. {
  53. XMLSchema schema;
  54. final DatatypeLibrary typeLibrary;
  55. XMLSchemaBuilder()
  56. {
  57. final String ns = XMLConstants.W3C_XML_SCHEMA_NS_URI;
  58. typeLibrary = new DatatypeLibraryLoader().createDatatypeLibrary(ns);
  59. }
  60. void parseSchema(Node node)
  61. throws DatatypeException
  62. {
  63. String uri = node.getNamespaceURI();
  64. String name = node.getLocalName();
  65. if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
  66. node.getNodeType() == Node.ELEMENT_NODE)
  67. {
  68. if ("schema".equals(name))
  69. {
  70. NamedNodeMap attrs = node.getAttributes();
  71. String targetNamespace = getAttribute(attrs, "targetNamespace");
  72. String version = getAttribute(attrs, "version");
  73. String fd = getAttribute(attrs, "finalDefault");
  74. int finalDefault = parseFullDerivationSet(fd);
  75. String bd = getAttribute(attrs, "blockDefault");
  76. int blockDefault = parseBlockSet(bd);
  77. String afd = getAttribute(attrs, "attributeFormDefault");
  78. boolean attributeFormQualified = "qualified".equals(afd);
  79. String efd = getAttribute(attrs, "elementFormDefault");
  80. boolean elementFormQualified = "qualified".equals(efd);
  81. schema = new XMLSchema(targetNamespace, version,
  82. finalDefault, blockDefault,
  83. attributeFormQualified,
  84. elementFormQualified);
  85. for (Node child = node.getFirstChild(); child != null;
  86. child = child.getNextSibling())
  87. {
  88. parseTopLevelElement(child);
  89. }
  90. return;
  91. }
  92. }
  93. // TODO throw schema exception
  94. }
  95. void parseTopLevelElement(Node node)
  96. throws DatatypeException
  97. {
  98. String uri = node.getNamespaceURI();
  99. String name = node.getLocalName();
  100. if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
  101. node.getNodeType() == Node.ELEMENT_NODE)
  102. {
  103. if ("element".equals(name))
  104. {
  105. ElementDeclaration ed =
  106. (ElementDeclaration) parseElement(node, null);
  107. schema.elementDeclarations.put(ed.name, ed);
  108. // TODO
  109. }
  110. else if ("attribute".equals(name))
  111. {
  112. AttributeDeclaration ad =
  113. (AttributeDeclaration) parseAttribute(node, true);
  114. schema.attributeDeclarations.put(ad.name, ad);
  115. // TODO
  116. }
  117. else if ("type".equals(name))
  118. {
  119. // TODO
  120. }
  121. else if ("group".equals(name))
  122. {
  123. // TODO
  124. }
  125. else if ("attributeGroup".equals(name))
  126. {
  127. // TODO
  128. }
  129. else if ("notation".equals(name))
  130. {
  131. // TODO
  132. }
  133. else if ("identityConstraint".equals(name))
  134. {
  135. // TODO
  136. }
  137. }
  138. // TODO throw schema exception
  139. }
  140. Object parseAttribute(Node node, boolean scope)
  141. throws DatatypeException
  142. {
  143. NamedNodeMap attrs = node.getAttributes();
  144. String def = getAttribute(attrs, "default");
  145. String fixed = getAttribute(attrs, "fixed");
  146. int constraintType = AttributeDeclaration.NONE;
  147. String constraintValue = null;
  148. if (def != null)
  149. {
  150. constraintType = AttributeDeclaration.DEFAULT;
  151. constraintValue = def;
  152. }
  153. else if (fixed != null)
  154. {
  155. constraintType = AttributeDeclaration.FIXED;
  156. constraintValue = fixed;
  157. }
  158. // TODO form = (qualified | unqualified)
  159. String attrName = getAttribute(attrs, "name");
  160. String attrNamespace = getAttribute(attrs, "targetNamespace");
  161. String ref = getAttribute(attrs, "ref");
  162. String use = getAttribute(attrs, "use");
  163. String type = getAttribute(attrs, "type");
  164. SimpleType datatype = (type == null) ? null :
  165. parseSimpleType(asQName(type, node));
  166. Annotation annotation = null;
  167. for (Node child = node.getFirstChild(); child != null;
  168. child = child.getNextSibling())
  169. {
  170. String uri = child.getNamespaceURI();
  171. String name = child.getLocalName();
  172. if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
  173. child.getNodeType() == Node.ELEMENT_NODE)
  174. {
  175. if ("annotation".equals(name))
  176. {
  177. annotation = parseAnnotation(child);
  178. }
  179. else if ("simpleType".equals(name))
  180. {
  181. datatype = parseSimpleType(child);
  182. }
  183. else
  184. {
  185. // TODO throw schema exception
  186. }
  187. }
  188. }
  189. if (scope)
  190. {
  191. return new AttributeDeclaration(scope,
  192. constraintType,
  193. constraintValue,
  194. new QName(attrNamespace, attrName),
  195. datatype,
  196. annotation);
  197. }
  198. else
  199. {
  200. boolean required = "required".equals(use);
  201. // TODO ref
  202. AttributeDeclaration decl = (ref == null) ?
  203. new AttributeDeclaration(scope,
  204. AttributeDeclaration.NONE,
  205. null,
  206. new QName(attrNamespace, attrName),
  207. datatype,
  208. annotation) :
  209. /*schema.getAttributeDeclaration(ref)*/ null;
  210. return new AttributeUse(required,
  211. constraintType,
  212. constraintValue,
  213. decl);
  214. }
  215. }
  216. int parseFullDerivationSet(String value)
  217. {
  218. int ret = XMLSchema.FINAL_NONE;
  219. if ("#all".equals(value))
  220. {
  221. ret = XMLSchema.FINAL_ALL;
  222. }
  223. else
  224. {
  225. StringTokenizer st = new StringTokenizer(value, " ");
  226. while (st.hasMoreTokens())
  227. {
  228. String token = st.nextToken();
  229. if ("extension".equals(token))
  230. {
  231. ret |= XMLSchema.FINAL_EXTENSION;
  232. }
  233. else if ("restriction".equals(token))
  234. {
  235. ret |= XMLSchema.FINAL_RESTRICTION;
  236. }
  237. else if ("list".equals(token))
  238. {
  239. ret |= XMLSchema.FINAL_LIST;
  240. }
  241. else if ("union".equals(token))
  242. {
  243. ret |= XMLSchema.FINAL_UNION;
  244. }
  245. }
  246. }
  247. return ret;
  248. }
  249. int parseSimpleTypeDerivationSet(String value)
  250. {
  251. int ret = XMLSchema.FINAL_NONE;
  252. if ("#all".equals(value))
  253. {
  254. ret = XMLSchema.FINAL_LIST |
  255. XMLSchema.FINAL_UNION |
  256. XMLSchema.FINAL_RESTRICTION;
  257. }
  258. else
  259. {
  260. StringTokenizer st = new StringTokenizer(value, " ");
  261. while (st.hasMoreTokens())
  262. {
  263. String token = st.nextToken();
  264. if ("list".equals(token))
  265. {
  266. ret |= XMLSchema.FINAL_LIST;
  267. }
  268. else if ("union".equals(token))
  269. {
  270. ret |= XMLSchema.FINAL_UNION;
  271. }
  272. else if ("restriction".equals(token))
  273. {
  274. ret |= XMLSchema.FINAL_RESTRICTION;
  275. }
  276. }
  277. }
  278. return ret;
  279. }
  280. int parseComplexTypeDerivationSet(String value)
  281. {
  282. int ret = XMLSchema.FINAL_NONE;
  283. if ("#all".equals(value))
  284. {
  285. ret = XMLSchema.FINAL_EXTENSION | XMLSchema.FINAL_RESTRICTION;
  286. }
  287. else
  288. {
  289. StringTokenizer st = new StringTokenizer(value, " ");
  290. while (st.hasMoreTokens())
  291. {
  292. String token = st.nextToken();
  293. if ("extension".equals(token))
  294. {
  295. ret |= XMLSchema.FINAL_EXTENSION;
  296. }
  297. else if ("restriction".equals(token))
  298. {
  299. ret |= XMLSchema.FINAL_RESTRICTION;
  300. }
  301. }
  302. }
  303. return ret;
  304. }
  305. int parseBlockSet(String value)
  306. {
  307. int ret = XMLSchema.BLOCK_NONE;
  308. if ("#all".equals(value))
  309. {
  310. ret = XMLSchema.BLOCK_ALL;
  311. }
  312. else
  313. {
  314. StringTokenizer st = new StringTokenizer(value, " ");
  315. while (st.hasMoreTokens())
  316. {
  317. String token = st.nextToken();
  318. if ("extension".equals(token))
  319. {
  320. ret |= XMLSchema.BLOCK_EXTENSION;
  321. }
  322. else if ("restriction".equals(token))
  323. {
  324. ret |= XMLSchema.BLOCK_RESTRICTION;
  325. }
  326. else if ("substitution".equals(token))
  327. {
  328. ret |= XMLSchema.BLOCK_SUBSTITUTION;
  329. }
  330. }
  331. }
  332. return ret;
  333. }
  334. int parseComplexTypeBlockSet(String value)
  335. {
  336. int ret = XMLSchema.BLOCK_NONE;
  337. if ("#all".equals(value))
  338. {
  339. ret = XMLSchema.BLOCK_EXTENSION | XMLSchema.BLOCK_RESTRICTION;
  340. }
  341. else
  342. {
  343. StringTokenizer st = new StringTokenizer(value, " ");
  344. while (st.hasMoreTokens())
  345. {
  346. String token = st.nextToken();
  347. if ("extension".equals(token))
  348. {
  349. ret |= XMLSchema.BLOCK_EXTENSION;
  350. }
  351. else if ("restriction".equals(token))
  352. {
  353. ret |= XMLSchema.BLOCK_RESTRICTION;
  354. }
  355. }
  356. }
  357. return ret;
  358. }
  359. Object parseElement(Node node, ElementDeclaration parent)
  360. throws DatatypeException
  361. {
  362. NamedNodeMap attrs = node.getAttributes();
  363. Integer minOccurs = null;
  364. Integer maxOccurs = null;
  365. Node parentNode = node.getParentNode();
  366. boolean notTopLevel = !"schema".equals(parentNode.getLocalName());
  367. if (notTopLevel)
  368. {
  369. String ref = getAttribute(attrs, "ref");
  370. if (ref != null)
  371. {
  372. minOccurs = getOccurrence(getAttribute(attrs, "minOccurs"));
  373. maxOccurs = getOccurrence(getAttribute(attrs, "maxOccurs"));
  374. // TODO resolve top-level element declaration
  375. ElementDeclaration ad = null;
  376. return new Particle(minOccurs, maxOccurs, ad);
  377. }
  378. }
  379. String elementName = getAttribute(attrs, "name");
  380. String elementNamespace = getAttribute(attrs, "targetNamespace");
  381. String type = getAttribute(attrs, "type");
  382. Type datatype = (type != null) ?
  383. parseSimpleType(asQName(type, node)) : null;
  384. int scope = (parent == null) ?
  385. XMLSchema.GLOBAL :
  386. XMLSchema.LOCAL;
  387. String def = getAttribute(attrs, "default");
  388. String fixed = getAttribute(attrs, "fixed");
  389. int constraintType = AttributeDeclaration.NONE;
  390. String constraintValue = null;
  391. if (def != null)
  392. {
  393. constraintType = AttributeDeclaration.DEFAULT;
  394. constraintValue = def;
  395. }
  396. else if (fixed != null)
  397. {
  398. constraintType = AttributeDeclaration.FIXED;
  399. constraintValue = fixed;
  400. }
  401. String sg = getAttribute(attrs, "substitutionGroup");
  402. QName substitutionGroup = QName.valueOf(sg);
  403. String sgPrefix = substitutionGroup.getPrefix();
  404. if (sgPrefix != null && !"".equals(sgPrefix))
  405. {
  406. String sgName = substitutionGroup.getLocalPart();
  407. String sgNamespace = node.lookupNamespaceURI(sgPrefix);
  408. substitutionGroup = new QName(sgNamespace, sgName);
  409. }
  410. String block = getAttribute(attrs, "block");
  411. int substitutionGroupExclusions = (block == null) ?
  412. schema.blockDefault :
  413. parseBlockSet(block);
  414. String final_ = getAttribute(attrs, "final");
  415. int disallowedSubstitutions = (final_ == null) ?
  416. schema.finalDefault :
  417. parseFullDerivationSet(final_);
  418. boolean nillable = "true".equals(getAttribute(attrs, "nillable"));
  419. boolean isAbstract = "true".equals(getAttribute(attrs, "abstract"));
  420. if (notTopLevel)
  421. {
  422. minOccurs = getOccurrence(getAttribute(attrs, "minOccurs"));
  423. maxOccurs = getOccurrence(getAttribute(attrs, "maxOccurs"));
  424. String form = getAttribute(attrs, "form");
  425. if (form != null)
  426. {
  427. if ("qualified".equals(form))
  428. {
  429. elementNamespace = schema.targetNamespace;
  430. }
  431. }
  432. else if (schema.elementFormQualified)
  433. {
  434. elementNamespace = schema.targetNamespace;
  435. }
  436. }
  437. ElementDeclaration ed =
  438. new ElementDeclaration(new QName(elementNamespace, elementName),
  439. datatype,
  440. scope, parent,
  441. constraintType, constraintValue,
  442. nillable,
  443. substitutionGroup,
  444. substitutionGroupExclusions,
  445. disallowedSubstitutions,
  446. isAbstract);
  447. for (Node child = node.getFirstChild(); child != null;
  448. child = child.getNextSibling())
  449. {
  450. String uri = child.getNamespaceURI();
  451. String name = child.getLocalName();
  452. if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
  453. child.getNodeType() == Node.ELEMENT_NODE)
  454. {
  455. if ("annotation".equals(name))
  456. {
  457. ed.annotation = parseAnnotation(child);
  458. }
  459. else if ("simpleType".equals(name) && datatype == null)
  460. {
  461. ed.datatype = parseSimpleType(child);
  462. }
  463. else if ("complexType".equals(name) && datatype == null)
  464. {
  465. ed.datatype = parseComplexType(child, ed);
  466. }
  467. else
  468. {
  469. // throw schema exception
  470. }
  471. }
  472. }
  473. if (notTopLevel)
  474. {
  475. return new Particle(minOccurs, maxOccurs, ed);
  476. }
  477. else
  478. {
  479. return ed;
  480. }
  481. }
  482. Integer getOccurrence(String value)
  483. {
  484. if (value == null)
  485. {
  486. return new Integer(1);
  487. }
  488. else if ("unbounded".equals(value))
  489. {
  490. return null;
  491. }
  492. else
  493. {
  494. return new Integer(value);
  495. }
  496. }
  497. SimpleType parseSimpleType(QName typeName)
  498. throws DatatypeException
  499. {
  500. SimpleType type = (SimpleType) schema.types.get(typeName);
  501. if (!XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(typeName.getNamespaceURI()))
  502. return null;
  503. String localName = typeName.getLocalPart();
  504. return (SimpleType) typeLibrary.createDatatype(localName);
  505. }
  506. SimpleType parseSimpleType(Node simpleType)
  507. throws DatatypeException
  508. {
  509. NamedNodeMap attrs = simpleType.getAttributes();
  510. String typeFinal = getAttribute(attrs, "final");
  511. if (typeFinal == null)
  512. {
  513. Node schema = simpleType.getParentNode();
  514. while (schema != null && !"schema".equals(schema.getLocalName()))
  515. {
  516. schema = schema.getParentNode();
  517. }
  518. if (schema != null)
  519. {
  520. NamedNodeMap schemaAttrs = schema.getAttributes();
  521. typeFinal = getAttribute(schemaAttrs, "finalDefault");
  522. }
  523. }
  524. int typeFinality = parseSimpleTypeDerivationSet(typeFinal);
  525. QName typeName = asQName(getAttribute(attrs, "name"), simpleType);
  526. int variety = 0;
  527. Set facets = new LinkedHashSet();
  528. int fundamentalFacets = 0; // TODO
  529. SimpleType baseType = null; // TODO
  530. Annotation annotation = null;
  531. // TODO use DatatypeBuilder
  532. for (Node child = simpleType.getFirstChild(); child != null;
  533. child = child.getNextSibling())
  534. {
  535. String uri = child.getNamespaceURI();
  536. String name = child.getLocalName();
  537. if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
  538. child.getNodeType() == Node.ELEMENT_NODE)
  539. {
  540. if ("annotation".equals(name))
  541. {
  542. annotation = parseAnnotation(child);
  543. }
  544. else if ("restriction".equals(name))
  545. {
  546. // TODO
  547. }
  548. else if ("list".equals(name))
  549. {
  550. variety = SimpleType.LIST;
  551. // TODO
  552. }
  553. else if ("union".equals(name))
  554. {
  555. variety = SimpleType.UNION;
  556. // TODO
  557. }
  558. }
  559. }
  560. return new SimpleType(typeName, variety, facets, fundamentalFacets,
  561. baseType, annotation);
  562. }
  563. Type parseComplexType(Node complexType, ElementDeclaration parent)
  564. throws DatatypeException
  565. {
  566. NamedNodeMap attrs = complexType.getAttributes();
  567. QName typeName = asQName(getAttribute(attrs, "name"), complexType);
  568. boolean isAbstract = "true".equals(getAttribute(attrs, "abstract"));
  569. String block = getAttribute(attrs, "block");
  570. int prohibitedSubstitutions = (block == null) ?
  571. schema.blockDefault :
  572. parseComplexTypeBlockSet(block);
  573. String final_ = getAttribute(attrs, "final");
  574. int finality = (final_ == null) ?
  575. schema.finalDefault :
  576. parseComplexTypeDerivationSet(final_);
  577. ComplexType type = new ComplexType(typeName, isAbstract,
  578. prohibitedSubstitutions, finality);
  579. boolean mixed = "true".equals(getAttribute(attrs, "mixed"));
  580. for (Node child = complexType.getFirstChild(); child != null;
  581. child = child.getNextSibling())
  582. {
  583. String uri = child.getNamespaceURI();
  584. String name = child.getLocalName();
  585. if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
  586. child.getNodeType() == Node.ELEMENT_NODE)
  587. {
  588. if ("simpleContent".equals(name))
  589. {
  590. parseSimpleContent(child, type);
  591. }
  592. }
  593. }
  594. if (mixed)
  595. {
  596. type.contentType = XMLSchema.CONTENT_MIXED;
  597. }
  598. return type;
  599. }
  600. void parseSimpleContent(Node simpleContent, ComplexType type)
  601. throws DatatypeException
  602. {
  603. for (Node child = simpleContent.getFirstChild(); child != null;
  604. child = child.getNextSibling())
  605. {
  606. String uri = child.getNamespaceURI();
  607. String name = child.getLocalName();
  608. if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
  609. child.getNodeType() == Node.ELEMENT_NODE)
  610. {
  611. if ("annotation".equals(name))
  612. {
  613. type.annotations.add(parseAnnotation(child));
  614. }
  615. else if ("restriction".equals(name))
  616. {
  617. type.derivationMethod = XMLSchema.FINAL_RESTRICTION;
  618. parseRestriction(child, type);
  619. }
  620. else if ("extension".equals(name))
  621. {
  622. type.derivationMethod = XMLSchema.FINAL_EXTENSION;
  623. parseExtension(child, type);
  624. }
  625. }
  626. }
  627. }
  628. void parseRestriction(Node restriction, ComplexType type)
  629. throws DatatypeException
  630. {
  631. NamedNodeMap attrs = restriction.getAttributes();
  632. String base = getAttribute(attrs, "base");
  633. QName baseType = asQName(base, restriction);
  634. SimpleType simpleType = null;
  635. for (Node child = restriction.getFirstChild(); child != null;
  636. child = child.getNextSibling())
  637. {
  638. String uri = child.getNamespaceURI();
  639. String name = child.getLocalName();
  640. if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
  641. child.getNodeType() == Node.ELEMENT_NODE)
  642. {
  643. if ("annotation".equals(name))
  644. {
  645. type.annotations.add(parseAnnotation(child));
  646. }
  647. else if ("simpleType".equals(name))
  648. {
  649. type.contentType = XMLSchema.CONTENT_SIMPLE;
  650. simpleType = parseSimpleType(child);
  651. }
  652. else if ("minExclusive".equals(name))
  653. {
  654. }
  655. else if ("minInclusive".equals(name))
  656. {
  657. }
  658. else if ("maxExclusive".equals(name))
  659. {
  660. }
  661. else if ("maxInclusive".equals(name))
  662. {
  663. }
  664. else if ("totalDigits".equals(name))
  665. {
  666. }
  667. else if ("fractionDigits".equals(name))
  668. {
  669. }
  670. else if ("length".equals(name))
  671. {
  672. }
  673. else if ("minLength".equals(name))
  674. {
  675. }
  676. else if ("maxLength".equals(name))
  677. {
  678. }
  679. else if ("enumeration".equals(name))
  680. {
  681. }
  682. else if ("whiteSpace".equals(name))
  683. {
  684. }
  685. else if ("pattern".equals(name))
  686. {
  687. }
  688. else if ("attribute".equals(name))
  689. {
  690. AttributeUse use =
  691. (AttributeUse) parseAttribute(child, false);
  692. schema.attributeDeclarations.put(use.declaration.name,
  693. use.declaration);
  694. type.attributeUses.add(use);
  695. }
  696. else if ("attributeGroup".equals(name))
  697. {
  698. NamedNodeMap agAttrs = child.getAttributes();
  699. String ref = getAttribute(agAttrs, "ref");
  700. QName ag = asQName(ref, child);
  701. type.attributeUses.add(ag);
  702. }
  703. else if ("anyAttribute".equals(name))
  704. {
  705. type.attributeWildcard = parseAnyAttribute(child);
  706. }
  707. }
  708. }
  709. }
  710. void parseExtension(Node extension, ComplexType type)
  711. throws DatatypeException
  712. {
  713. NamedNodeMap attrs = extension.getAttributes();
  714. String base = getAttribute(attrs, "base");
  715. QName baseType = asQName(base, extension);
  716. for (Node child = extension.getFirstChild(); child != null;
  717. child = child.getNextSibling())
  718. {
  719. String uri = child.getNamespaceURI();
  720. String name = child.getLocalName();
  721. if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
  722. child.getNodeType() == Node.ELEMENT_NODE)
  723. {
  724. if ("annotation".equals(name))
  725. {
  726. type.annotations.add(parseAnnotation(child));
  727. }
  728. else if ("attribute".equals(name))
  729. {
  730. AttributeUse use =
  731. (AttributeUse) parseAttribute(child, false);
  732. schema.attributeDeclarations.put(use.declaration.name,
  733. use.declaration);
  734. type.attributeUses.add(use);
  735. }
  736. else if ("attributeGroup".equals(name))
  737. {
  738. NamedNodeMap agAttrs = child.getAttributes();
  739. String ref = getAttribute(agAttrs, "ref");
  740. QName ag = asQName(ref, child);
  741. type.attributeUses.add(ag);
  742. }
  743. else if ("anyAttribute".equals(name))
  744. {
  745. type.attributeWildcard = parseAnyAttribute(child);
  746. }
  747. }
  748. }
  749. }
  750. AnyAttribute parseAnyAttribute(Node node)
  751. {
  752. NamedNodeMap attrs = node.getAttributes();
  753. String namespace = getAttribute(attrs, "namespace");
  754. String pc = getAttribute(attrs, "processContents");
  755. int processContents = AnyAttribute.STRICT;
  756. if ("lax".equals(pc))
  757. {
  758. processContents = AnyAttribute.LAX;
  759. }
  760. else if ("skip".equals(pc))
  761. {
  762. processContents = AnyAttribute.SKIP;
  763. }
  764. AnyAttribute ret = new AnyAttribute(namespace, processContents);
  765. for (Node child = node.getFirstChild(); child != null;
  766. child = child.getNextSibling())
  767. {
  768. String uri = child.getNamespaceURI();
  769. String name = child.getLocalName();
  770. if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
  771. child.getNodeType() == Node.ELEMENT_NODE)
  772. {
  773. if ("annotation".equals(name))
  774. {
  775. ret.annotation = parseAnnotation(child);
  776. }
  777. }
  778. }
  779. return ret;
  780. }
  781. Annotation parseAnnotation(Node node)
  782. {
  783. // TODO
  784. return null;
  785. }
  786. private static String getAttribute(NamedNodeMap attrs, String name)
  787. {
  788. Node attr = attrs.getNamedItem(name);
  789. return (attr == null) ? null : attr.getNodeValue();
  790. }
  791. private static QName asQName(String text, Node resolver)
  792. {
  793. QName name = QName.valueOf(text);
  794. String prefix = name.getPrefix();
  795. if (prefix != null && prefix.length() > 0)
  796. {
  797. String uri = resolver.lookupNamespaceURI(prefix);
  798. name = new QName(uri, name.getLocalPart());
  799. }
  800. return name;
  801. }
  802. }