PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Third_Party/piccolo/com/bluecast/xml/Piccolo.y

http://dataturbine.googlecode.com/
Happy | 1259 lines | 1075 code | 184 blank | 0 comment | 0 complexity | 2394c30ae073567d55f7331bf7d98f15 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1, BSD-3-Clause, GPL-2.0
  1. %{
  2. package com.bluecast.xml;
  3. import org.xml.sax.*;
  4. import org.xml.sax.helpers.*;
  5. import org.xml.sax.ext.*;
  6. import java.io.*;
  7. import java.net.MalformedURLException;
  8. import com.bluecast.util.*;
  9. import com.bluecast.io.*;
  10. import java.util.*;
  11. /*
  12. * $Id: Piccolo.y,v 1.10 2004/07/11 09:37:37 yuvalo Exp $
  13. *
  14. * 2003-06-10 - MODIFIED to provide access to <?xml?> definition
  15. * and startLocator
  16. *
  17. * (C) Copyright 2002-2004 by Yuval Oren. All rights reserved.
  18. *
  19. * Licensed under the Apache License, Version 2.0 (the "License");
  20. * you may not use this file except in compliance with the License.
  21. * You may obtain a copy of the License at
  22. *
  23. * http://www.apache.org/licenses/LICENSE-2.0
  24. *
  25. * Unless required by applicable law or agreed to in writing, software
  26. * distributed under the License is distributed on an "AS IS" BASIS,
  27. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  28. * See the License for the specific language governing permissions and
  29. * limitations under the License.
  30. */
  31. /**
  32. * Piccolo is a small, high-performance SAX1 and SAX2 XML parser.
  33. * As per the SAX2 specification, namespace handling is on by
  34. * default. You can improve performance by turning it off.
  35. *
  36. * Note that if used in SAX1 mode, namespace handling is
  37. * automatically turned off.
  38. */
  39. %}
  40. /* YACC generation options */
  41. %Jclass Piccolo
  42. %Jsemantic String
  43. %Jnorun
  44. %Jnodebug
  45. %Jthrows SAXException, IOException
  46. %Jimplements org.xml.sax.Parser,org.xml.sax.Locator,org.xml.sax.XMLReader
  47. %Jnoconstruct
  48. %Jfinal
  49. /* YACC Declarations */
  50. %token CDATA TAG_END
  51. %token PI NAME STRING EQ
  52. %token OPEN_TAG CLOSE_TAG EMPTY_TAG
  53. %token WHITESPACE
  54. %token DTD_START DTD_START_SKIPEXTERNAL SYSTEM PUBLIC REQUIRED IMPLIED FIXED LPAREN RPAREN LBRACKET
  55. %token PIPE ENTITY_DECL_START ATTLIST_START NOTATION_START
  56. %token RBRACKET_END DOUBLE_RBRACKET_END PERCENT
  57. %token ENUMERATION NOTATION CDATA ID IDREF IDREFS ENTITY ENTITIES NMTOKEN
  58. %token NMTOKENS ENTITY_REF ENTITY_END
  59. %token INTERNAL_ENTITY_REF EXTERNAL_ENTITY_REF SKIPPED_ENTITY_REF
  60. %token PREFIXED_NAME UNPREFIXED_NAME NDATA COMMENT
  61. %token CONDITIONAL_START IGNORED_CONDITIONAL_START INCLUDE IGNORE
  62. %token MODIFIER PCDATA ELEMENT_DECL_START EMPTY ANY
  63. %token STAR COMMA QUESTION PLUS
  64. /* %token XML_DECL_START XML_DECL_END VERSION ENCODING STANDALONE */
  65. %token XML_DOC_DECL XML_TEXT_DECL XML_DOC_OR_TEXT_DECL
  66. /* Grammar follows */
  67. %%
  68. document: xml_decl dtd body epilog
  69. | xml_decl body epilog
  70. ;
  71. xml_decl: XML_DOC_DECL | XML_DOC_OR_TEXT_DECL | /* empty */
  72. ;
  73. xml_text_decl: XML_TEXT_DECL | XML_DOC_OR_TEXT_DECL
  74. ;
  75. body: EMPTY_TAG
  76. | OPEN_TAG content CLOSE_TAG
  77. | misc body
  78. ;
  79. epilog: misc epilog
  80. | /* empty */
  81. ;
  82. misc: WHITESPACE
  83. | PI
  84. | COMMENT
  85. ;
  86. ws: WHITESPACE
  87. | ws WHITESPACE
  88. ;
  89. opt_ws: /* empty */
  90. | ws
  91. ;
  92. dtd:
  93. /* Internal/Name only */
  94. DTD_START NAME opt_ws TAG_END {
  95. dtdName = $2;
  96. lexer.yybegin(0);
  97. reportStartDTD(dtdName,null,null);
  98. reportEndDTD();
  99. }
  100. | dtd_only_internal_start dtd_content RBRACKET_END {
  101. // Internal subset only
  102. lexer.yybegin(0);
  103. reportEndDTD();
  104. }
  105. | dtd_with_external xml_text_decl dtd_content ENTITY_END {
  106. // Internal+External or External only with an <?xml?> declaration
  107. lexer.yybegin(0);
  108. reportEndDTD();
  109. }
  110. | dtd_with_external dtd_content ENTITY_END {
  111. // Internal+External or External only with no <?xml?> declaration
  112. lexer.yybegin(0);
  113. reportEndDTD();
  114. }
  115. | DTD_START_SKIPEXTERNAL NAME ws external_id opt_ws TAG_END {
  116. // External subset with no internal subset. Skip external
  117. dtdName = $2;
  118. lexer.yybegin(0);
  119. reportStartDTD(dtdName,pubID,sysID);
  120. reportEndDTD();
  121. }
  122. | misc dtd
  123. ;
  124. dtd_with_external: dtd_with_external_start TAG_END {
  125. // External subset with no internal subset
  126. lexer.pushEntity("[dtd]",dtdPubID,dtdSysID,false,true);
  127. lexer.yybegin(lexer.DTD);
  128. }
  129. | dtd_with_external_start LBRACKET dtd_content RBRACKET_END {
  130. // Both external and internal subsets. Internal comes first.
  131. lexer.pushEntity("[dtd]",dtdPubID,dtdSysID,false,true);
  132. lexer.yybegin(lexer.DTD);
  133. }
  134. ;
  135. dtd_with_external_start:
  136. DTD_START NAME ws SYSTEM ws STRING opt_ws {
  137. dtdName = lexer.normalizeValue($2);
  138. dtdPubID = null;
  139. dtdSysID = lexer.normalizeValue($6);
  140. reportStartDTD(dtdName,dtdPubID,dtdSysID);
  141. }
  142. | DTD_START NAME ws PUBLIC ws STRING ws STRING opt_ws {
  143. dtdName = $2;
  144. dtdPubID = lexer.normalizeValue($6);
  145. dtdSysID = lexer.normalizeValue($8);
  146. reportStartDTD(dtdName,dtdPubID,dtdSysID);
  147. }
  148. ;
  149. dtd_only_internal_start:
  150. DTD_START NAME LBRACKET {
  151. dtdName = $2;
  152. reportStartDTD(dtdName,null,null);
  153. }
  154. | DTD_START_SKIPEXTERNAL NAME LBRACKET {
  155. dtdName = $2;
  156. reportStartDTD(dtdName,null,null);
  157. }
  158. | DTD_START_SKIPEXTERNAL NAME ws external_id LBRACKET {
  159. dtdName = $2;
  160. reportStartDTD(dtdName,pubID,sysID);
  161. }
  162. ;
  163. external_id: SYSTEM ws STRING { pubID=null; sysID=lexer.normalizeValue($3); }
  164. | PUBLIC ws STRING ws STRING {
  165. pubID=lexer.normalizeValue($3);
  166. sysID=lexer.normalizeValue($5);
  167. }
  168. ;
  169. dtd_content: /* empty */
  170. | dtd_content dtd_conditional
  171. | dtd_content dtd_entity
  172. | dtd_content dtd_attlist
  173. | dtd_content dtd_notation
  174. | dtd_content misc
  175. | dtd_content dtd_element
  176. | dtd_content INTERNAL_ENTITY_REF dtd_content
  177. | dtd_content EXTERNAL_ENTITY_REF dtd_content
  178. | dtd_content EXTERNAL_ENTITY_REF xml_text_decl dtd_content
  179. ;
  180. dtd_conditional:
  181. CONDITIONAL_START dtd_include dtd_content DOUBLE_RBRACKET_END
  182. | CONDITIONAL_START dtd_ignore ignored_dtd_content DOUBLE_RBRACKET_END {
  183. lexer.yybegin(lexer.DTD);
  184. }
  185. dtd_include: INCLUDE opt_ws LBRACKET {
  186. lexer.yybegin(lexer.DTD);
  187. }
  188. | ws dtd_include
  189. ;
  190. dtd_ignore: IGNORE opt_ws LBRACKET {
  191. lexer.yybegin(lexer.DTD_IGNORE);
  192. }
  193. | ws dtd_ignore
  194. ;
  195. ignored_dtd_content: /* empty */
  196. | ignored_dtd_content IGNORED_CONDITIONAL_START ignored_dtd_content DOUBLE_RBRACKET_END
  197. ;
  198. dtd_entity:
  199. ENTITY_DECL_START ws NAME ws STRING opt_ws TAG_END {
  200. lexer.entityManager.putInternal($3,$5,EntityManager.GENERAL);
  201. if (declHandler != null)
  202. declHandler.internalEntityDecl($3,$5);
  203. }
  204. | ENTITY_DECL_START ws NAME ws external_id opt_ws TAG_END {
  205. try {
  206. lexer.entityManager.putExternal(lexer.currentEntity,$3,pubID,sysID,EntityManager.GENERAL);
  207. if (declHandler != null)
  208. declHandler.externalEntityDecl($3,pubID,resolveSystemID(sysID));
  209. }
  210. catch (MalformedURLException e) {
  211. reportFatalError("Invalid system identifier: "
  212. + sysID + "; " + e.getMessage());
  213. }
  214. }
  215. | ENTITY_DECL_START ws NAME ws external_id ws NDATA ws NAME opt_ws TAG_END {
  216. try {
  217. lexer.entityManager.putUnparsed(lexer.currentEntity,$3,pubID,sysID,$9,EntityManager.GENERAL);
  218. reportUnparsedEntityDecl($3,pubID,sysID,$9);
  219. }
  220. catch (MalformedURLException e) {
  221. reportFatalError("Invalid system identifier: "
  222. + sysID + "; " + e.getMessage());
  223. }
  224. }
  225. | ENTITY_DECL_START ws PERCENT NAME ws STRING opt_ws TAG_END {
  226. lexer.entityManager.putInternal($4,$6,EntityManager.PARAMETER);
  227. if (declHandler != null)
  228. declHandler.internalEntityDecl("%"+$4,$6);
  229. }
  230. | ENTITY_DECL_START ws PERCENT NAME ws external_id opt_ws TAG_END {
  231. try {
  232. lexer.entityManager.putExternal(lexer.currentEntity,$4,pubID,sysID,EntityManager.PARAMETER);
  233. if (declHandler != null)
  234. declHandler.externalEntityDecl("%"+$4,pubID,resolveSystemID(sysID));
  235. }
  236. catch (MalformedURLException e) {
  237. reportFatalError("Invalid system identifier: "
  238. + sysID + "; " + e.getMessage());
  239. }
  240. }
  241. | ENTITY_DECL_START ws PERCENT NAME external_id ws NDATA ws NAME opt_ws TAG_END {
  242. try {
  243. lexer.entityManager.putUnparsed(lexer.currentEntity,$4,pubID,sysID,$9,EntityManager.PARAMETER);
  244. reportUnparsedEntityDecl($4,pubID,sysID,$9);
  245. }
  246. catch (MalformedURLException e) {
  247. reportFatalError("Invalid system identifier: "
  248. + sysID + "; " + e.getMessage());
  249. }
  250. }
  251. ;
  252. dtd_notation: NOTATION_START ws NAME ws external_id opt_ws TAG_END {
  253. reportNotationDecl($3,pubID,sysID);
  254. }
  255. | NOTATION_START ws NAME ws PUBLIC ws STRING opt_ws TAG_END {
  256. reportNotationDecl($3,lexer.normalizeValue($7),null);
  257. }
  258. ;
  259. dtd_attlist: attlist_start att_def_list opt_ws TAG_END {
  260. lexer.defineElement(elementDefinition.getName(),elementDefinition);
  261. }
  262. ;
  263. attlist_start: ATTLIST_START ws NAME {
  264. // Look up this element. If we've seen previous ATTLIST definitions for it, we'll add these to it.
  265. elementDefinition = lexer.getElement($3);
  266. if (elementDefinition == null)
  267. elementDefinition = new ElementDefinition($3);
  268. }
  269. att_def_list: /* empty */
  270. | att_def_list ws att_def
  271. ;
  272. att_def:
  273. PREFIXED_NAME ws att_type ws REQUIRED {
  274. lexer.yybegin(lexer.DTD_ATT_NAME);
  275. addPrefixedAttributeDefinition($1,attributeType,AttributeDefinition.REQUIRED,null);
  276. }
  277. | UNPREFIXED_NAME ws att_type ws REQUIRED {
  278. lexer.yybegin(lexer.DTD_ATT_NAME);
  279. addAttributeDefinition($1,attributeType,AttributeDefinition.REQUIRED,null);
  280. }
  281. | PREFIXED_NAME ws att_type ws IMPLIED {
  282. lexer.yybegin(lexer.DTD_ATT_NAME);
  283. addPrefixedAttributeDefinition($1,attributeType,AttributeDefinition.IMPLIED,null);
  284. }
  285. | UNPREFIXED_NAME ws att_type ws IMPLIED {
  286. lexer.yybegin(lexer.DTD_ATT_NAME);
  287. addAttributeDefinition($1,attributeType,AttributeDefinition.IMPLIED,null);
  288. }
  289. | PREFIXED_NAME ws att_type ws FIXED ws STRING {
  290. lexer.yybegin(lexer.DTD_ATT_NAME);
  291. addPrefixedAttributeDefinition($1,attributeType,AttributeDefinition.FIXED,$7);
  292. }
  293. | UNPREFIXED_NAME ws att_type ws FIXED ws STRING {
  294. lexer.yybegin(lexer.DTD_ATT_NAME);
  295. addAttributeDefinition($1,attributeType,AttributeDefinition.FIXED,$7);
  296. }
  297. | PREFIXED_NAME ws att_type ws STRING {
  298. lexer.yybegin(lexer.DTD_ATT_NAME);
  299. addPrefixedAttributeDefinition($1,attributeType,0,$5);
  300. }
  301. | UNPREFIXED_NAME ws att_type ws STRING {
  302. lexer.yybegin(lexer.DTD_ATT_NAME);
  303. addAttributeDefinition($1,attributeType,0,$5);
  304. }
  305. ;
  306. att_type: CDATA { attributeType = AttributeDefinition.CDATA; }
  307. | ID { attributeType = AttributeDefinition.ID; }
  308. | IDREF { attributeType = AttributeDefinition.IDREF; }
  309. | IDREFS { attributeType = AttributeDefinition.IDREFS; }
  310. | ENTITY { attributeType = AttributeDefinition.ENTITY; }
  311. | ENTITIES { attributeType = AttributeDefinition.ENTITIES; }
  312. | NMTOKEN { attributeType = AttributeDefinition.NMTOKEN; }
  313. | NMTOKENS { attributeType = AttributeDefinition.NMTOKENS; }
  314. | LPAREN opt_ws word_list opt_ws RPAREN {
  315. attributeType = AttributeDefinition.ENUMERATION;
  316. }
  317. | NOTATION ws LPAREN opt_ws word_list opt_ws RPAREN {
  318. attributeType = AttributeDefinition.NOTATION;
  319. }
  320. ;
  321. word_list:
  322. NAME {
  323. if (declHandler != null)
  324. modelBuffer.append($1);
  325. }
  326. | word_list opt_ws PIPE opt_ws NAME {
  327. if (declHandler != null) {
  328. modelBuffer.append('|');
  329. modelBuffer.append($5);
  330. }
  331. }
  332. ;
  333. dtd_element: ELEMENT_DECL_START ws NAME ws element_spec opt_ws TAG_END {
  334. if (declHandler != null)
  335. declHandler.elementDecl($3,$5);
  336. }
  337. ;
  338. element_spec:
  339. EMPTY {
  340. if (declHandler != null)
  341. $$ = "EMPTY";
  342. }
  343. | ANY {
  344. if (declHandler != null)
  345. $$ = "ANY";
  346. }
  347. | element_spec_mixed {
  348. if (declHandler != null)
  349. $$ = $1;
  350. }
  351. | element_spec_children {
  352. if (declHandler != null)
  353. $$ = $1;
  354. }
  355. ;
  356. element_spec_mixed:
  357. LPAREN opt_ws PCDATA opt_ws RPAREN STAR {
  358. if (declHandler != null)
  359. $$ = "(#PCDATA)*";
  360. }
  361. | LPAREN opt_ws PCDATA opt_ws RPAREN {
  362. if (declHandler != null)
  363. $$ = "(#PCDATA)";
  364. }
  365. | LPAREN opt_ws PCDATA opt_ws PIPE opt_ws word_list opt_ws RPAREN STAR {
  366. if (declHandler != null)
  367. $$ = "(#PCDATA|" + modelBuffer.toString() + ")*";
  368. }
  369. | WHITESPACE element_spec_mixed {
  370. if (declHandler != null)
  371. $$ = $2;
  372. }
  373. ;
  374. element_spec_children:
  375. element_choice element_modifier {
  376. if (declHandler != null)
  377. $$ = $1 + $2;
  378. }
  379. | element_seq element_modifier {
  380. if (declHandler != null)
  381. $$ = $1 + $2;
  382. }
  383. | WHITESPACE element_spec_children {
  384. if (declHandler != null)
  385. $$ = $2;
  386. }
  387. ;
  388. element_cp_pipe_list:
  389. element_cp opt_ws PIPE opt_ws element_cp {
  390. if (declHandler != null)
  391. $$ = $1 + "|" + $5;
  392. }
  393. | element_cp opt_ws PIPE opt_ws element_cp_pipe_list {
  394. if (declHandler != null)
  395. $$ = $1 + "|" + $5;
  396. }
  397. ;
  398. element_cp_comma_list:
  399. element_cp {
  400. if (declHandler != null)
  401. $$ = $1;
  402. }
  403. | element_cp opt_ws COMMA element_cp_comma_list {
  404. if (declHandler != null)
  405. $$ = $1 + "," + $4;
  406. }
  407. ;
  408. element_cp:
  409. NAME element_modifier opt_ws {
  410. if (declHandler != null)
  411. $$ = $1 + $2;
  412. }
  413. | element_choice element_modifier opt_ws {
  414. if (declHandler != null)
  415. $$ = $1 + $2;
  416. }
  417. | element_seq element_modifier opt_ws {
  418. if (declHandler != null)
  419. $$ = $1 + $2;
  420. }
  421. | WHITESPACE element_cp {
  422. if (declHandler != null)
  423. $$ = $2;
  424. }
  425. ;
  426. element_choice:
  427. LPAREN element_cp_pipe_list opt_ws RPAREN {
  428. if (declHandler != null)
  429. $$ = "(" + $2 + ")";
  430. }
  431. | WHITESPACE element_choice {
  432. if (declHandler != null)
  433. $$ = $2;
  434. }
  435. ;
  436. element_seq:
  437. LPAREN element_cp_comma_list opt_ws RPAREN {
  438. if (declHandler != null)
  439. $$ = "(" + $2 + ")";
  440. }
  441. | WHITESPACE element_seq {
  442. if (declHandler != null)
  443. $$ = $2;
  444. }
  445. ;
  446. element_modifier:
  447. QUESTION {
  448. if (declHandler != null)
  449. $$ = "?";
  450. }
  451. | STAR {
  452. if (declHandler != null)
  453. $$ = "*";
  454. }
  455. | PLUS {
  456. if (declHandler != null)
  457. $$ = "+";
  458. }
  459. | /* empty */ {
  460. if (declHandler != null)
  461. $$ = "";
  462. }
  463. ;
  464. // All content except for entity references is not tokenized but
  465. // instead is handled within the lexer.
  466. content: /* empty */
  467. | content INTERNAL_ENTITY_REF content ENTITY_END {
  468. lexer.setTokenize(false);
  469. }
  470. | content EXTERNAL_ENTITY_REF content ENTITY_END {
  471. lexer.setTokenize(false);
  472. }
  473. | content EXTERNAL_ENTITY_REF xml_text_decl content ENTITY_END {
  474. lexer.setTokenize(false);
  475. }
  476. | content OPEN_TAG content CLOSE_TAG
  477. | content EMPTY_TAG
  478. | content PI
  479. | content COMMENT
  480. | content WHITESPACE {
  481. reportWhitespace();
  482. }
  483. | content CDATA
  484. ;
  485. %%
  486. DocumentHandler documentHandler = null;
  487. DTDHandler dtdHandler = null;
  488. ErrorHandler errorHandler = null;
  489. ContentHandler contentHandler = null;
  490. int saxVersion = 0;
  491. int attributeType=-1;
  492. StringBuffer modelBuffer = new StringBuffer(100);
  493. ElementDefinition elementDefinition=null;
  494. String pubID=null,sysID=null;
  495. String dtdName=null,dtdPubID=null,dtdSysID=null;
  496. PiccoloLexer lexer = new PiccoloLexer(this);
  497. DocumentEntity docEntity = new DocumentEntity();
  498. LexicalHandler lexHandler = null;
  499. DeclHandler declHandler = null;
  500. boolean parsingInProgress = false;
  501. /// Create an instance of the Piccolo parser
  502. public Piccolo() { }
  503. /**
  504. * Create an instance with the same configuration
  505. * as the given instance. ContentHandler, DTDHandler, etc.
  506. * will not be copied.
  507. */
  508. public Piccolo(Piccolo template) {
  509. fNamespaces = template.fNamespaces;
  510. fNamespacePrefixes = template.fNamespacePrefixes;
  511. fExternalGeneralEntities = template.fExternalGeneralEntities;
  512. fExternalParameterEntities = template.fExternalParameterEntities;
  513. fLexicalParameterEntities = template.fLexicalParameterEntities;
  514. lexer.enableNamespaces(fNamespaces);
  515. fResolveDTDURIs = template.fResolveDTDURIs;
  516. }
  517. private void reset() {
  518. modelBuffer.setLength(0);
  519. pubID = sysID = dtdName = dtdPubID = dtdSysID = null;
  520. elementDefinition = null;
  521. }
  522. // Make sure it's okay to start parsing
  523. private void validateParseState() throws SAXException {
  524. if (!fNamespaces && !fNamespacePrefixes) {
  525. throw new FatalParsingException("The 'namespaces' and 'namespace-prefixes' features must not both be false");
  526. }
  527. }
  528. public void setDebug(boolean debug) {
  529. yydebug = debug;
  530. }
  531. /************************************************************************
  532. * Methods common to both SAX1 and SAX2
  533. ************************************************************************/
  534. public void parse(InputSource source) throws IOException, SAXException {
  535. try {
  536. reset();
  537. validateParseState();
  538. try {
  539. docEntity.reset(source);
  540. lexer.reset(docEntity);
  541. }
  542. finally {
  543. reportStartDocument();
  544. }
  545. yyparse();
  546. }
  547. catch (IllegalCharException e) {
  548. reportFatalError(e.getMessage(),e);
  549. }
  550. catch (FileFormatException e) {
  551. reportFatalError(e.getMessage(),e);
  552. }
  553. catch (FatalParsingException e) {
  554. reportFatalError(e.getMessage(),e.getException());
  555. }
  556. finally {
  557. reportEndDocument();
  558. }
  559. }
  560. public void parse(String sysID) throws IOException, SAXException {
  561. try {
  562. reset();
  563. validateParseState();
  564. try {
  565. docEntity.reset(sysID);
  566. lexer.reset(docEntity);
  567. }
  568. finally {
  569. reportStartDocument();
  570. }
  571. yyparse();
  572. }
  573. catch (IllegalCharException e) {
  574. reportFatalError(e.getMessage(),e);
  575. }
  576. catch (FileFormatException e) {
  577. reportFatalError(e.getMessage(),e);
  578. }
  579. catch (FatalParsingException e) {
  580. reportFatalError(e.getMessage(),e.getException());
  581. }
  582. finally {
  583. reportEndDocument();
  584. }
  585. }
  586. /************************************************************************
  587. * SAX1 methods
  588. ************************************************************************/
  589. public void setDocumentHandler(DocumentHandler handler) {
  590. documentHandler = handler;
  591. if (documentHandler != null) {
  592. saxVersion = 1;
  593. fNamespaces = false;
  594. lexer.enableNamespaces(false);
  595. fNamespacePrefixes = true;
  596. documentHandler.setDocumentLocator(this);
  597. }
  598. else
  599. saxVersion = 0;
  600. }
  601. public void setDTDHandler(DTDHandler handler) {
  602. dtdHandler = handler;
  603. }
  604. public void setEntityResolver(EntityResolver resolver) {
  605. lexer.entityManager.setResolver(resolver);
  606. }
  607. public void setErrorHandler(ErrorHandler handler) {
  608. errorHandler = handler;
  609. }
  610. public void setLocale(java.util.Locale locale)
  611. throws SAXException {
  612. if (!("en".equals(locale.getLanguage())))
  613. throw new SAXException("Only English (EN) locales are supported");
  614. }
  615. // Locator
  616. public int getColumnNumber() { return lexer.getColumnNumber(); }
  617. public int getLineNumber() { return lexer.getLineNumber(); }
  618. public String getPublicId() { return lexer.getPublicID(); }
  619. public String getSystemId() { return lexer.getSystemID(); }
  620. // Locator which returns line/col info for the start of the token
  621. private class StartLocator implements org.xml.sax.Locator
  622. {
  623. public int getLineNumber ( ) { return Piccolo.this.lexer.tokenStartLine; }
  624. public int getColumnNumber ( ) { return -1; }
  625. public String getPublicId ( ) { return null; }
  626. public String getSystemId ( ) { return null; }
  627. }
  628. private StartLocator startLocator;
  629. public Locator getStartLocator ( )
  630. {
  631. if (startLocator == null)
  632. startLocator = new StartLocator();
  633. return startLocator;
  634. }
  635. public String getVersion ( )
  636. {
  637. return lexer.getVersion();
  638. }
  639. public String getEncoding ( )
  640. {
  641. return lexer.getEncoding();
  642. }
  643. /************************************************************************
  644. * SAX2 methods
  645. ************************************************************************/
  646. public ContentHandler getContentHandler() { return contentHandler; }
  647. public void setContentHandler(ContentHandler handler) {
  648. contentHandler = handler;
  649. if (contentHandler != null) {
  650. // Are we switching from SAX1? If so, turn namespace processing on
  651. if (saxVersion == 1) {
  652. fNamespaces = true;
  653. lexer.enableNamespaces(true);
  654. fNamespacePrefixes = false;
  655. }
  656. saxVersion = 2;
  657. contentHandler.setDocumentLocator(this);
  658. }
  659. else
  660. saxVersion = 0;
  661. }
  662. public DTDHandler getDTDHandler() { return dtdHandler; }
  663. public EntityResolver getEntityResolver() { return lexer.entityManager.getResolver(); }
  664. public ErrorHandler getErrorHandler() { return errorHandler; }
  665. // SAX2 Features
  666. boolean fNamespaces=true,fNamespacePrefixes=false,fResolveDTDURIs=true;
  667. boolean fExternalGeneralEntities=true,fExternalParameterEntities=true;
  668. boolean fLexicalParameterEntities = true;
  669. public boolean getFeature(String name)
  670. throws SAXNotSupportedException,SAXNotRecognizedException {
  671. if (name.equals("http://xml.org/sax/features/namespaces"))
  672. return fNamespaces;
  673. else if (name.equals("http://xml.org/sax/features/namespace-prefixes"))
  674. return fNamespacePrefixes;
  675. else if (name.equals("http://xml.org/sax/features/external-general-entities"))
  676. return fExternalGeneralEntities;
  677. else if (name.equals("http://xml.org/sax/features/external-parameter-entities"))
  678. return fExternalGeneralEntities;
  679. else if (name.equals("http://xml.org/sax/features/lexical-handler/parameter-entities"))
  680. return fLexicalParameterEntities;
  681. else if (name.equals("http://xml.org/sax/features/string-interning"))
  682. return true;
  683. else if (name.equals("http://xml.org/sax/features/is-standalone"))
  684. return docEntity.isStandalone();
  685. else if (name.equals("http://xml.org/sax/features/resolve-dtd-uris"))
  686. return fResolveDTDURIs;
  687. else if (name.equals("http://xml.org/sax/features/use-attributes2")
  688. || name.equals("http://xml.org/sax/features/validation")
  689. || name.equals("http://xml.org/sax/features/use-locator2")
  690. || name.equals("http://xml.org/sax/features/use-entity2")
  691. || name.equals("http://xml.org/sax/features/use-locator2"))
  692. return false;
  693. else
  694. throw new SAXNotRecognizedException(name);
  695. }
  696. public void setFeature(String name, boolean value)
  697. throws SAXNotSupportedException,SAXNotRecognizedException {
  698. if (name.equals("http://xml.org/sax/features/namespaces")) {
  699. if (parsingInProgress) {
  700. throw new SAXNotSupportedException("Can't change namespace settings while parsing");
  701. }
  702. fNamespaces = value;
  703. lexer.enableNamespaces(value);
  704. }
  705. else if (name.equals("http://xml.org/sax/features/namespace-prefixes")) {
  706. if (parsingInProgress) {
  707. throw new SAXNotSupportedException("Can't change namespace settings while parsing");
  708. }
  709. fNamespacePrefixes = value;
  710. }
  711. else if (name.equals("http://xml.org/sax/features/external-general-entities")) {
  712. fExternalGeneralEntities = value;
  713. }
  714. else if (name.equals("http://xml.org/sax/features/external-parameter-entities")) {
  715. fExternalParameterEntities = value;
  716. }
  717. else if (name.equals("http://xml.org/sax/features/lexical-handler/parameter-entities")) {
  718. fLexicalParameterEntities = value;
  719. }
  720. else if (name.equals("http://xml.org/sax/features/resolve-dtd-uris")) {
  721. fResolveDTDURIs = value;
  722. }
  723. else if (name.equals("http://xml.org/sax/features/validation")) {
  724. if (value)
  725. throw new SAXNotSupportedException("validation is not supported");
  726. }
  727. else if (name.equals("http://xml.org/sax/features/string-interning")) {
  728. if (!value)
  729. throw new SAXNotSupportedException("strings are always internalized");
  730. }
  731. else if (name.equals("http://xml.org/sax/features/use-attributes2")
  732. || name.equals("http://xml.org/sax/features/validation")
  733. || name.equals("http://xml.org/sax/features/use-locator2")
  734. || name.equals("http://xml.org/sax/features/use-entity2")
  735. || name.equals("http://xml.org/sax/features/use-locator2")) {
  736. if (value)
  737. throw new SAXNotSupportedException(name);
  738. }
  739. else
  740. throw new SAXNotRecognizedException(name);
  741. }
  742. public Object getProperty(String name)
  743. throws SAXNotRecognizedException, SAXNotSupportedException {
  744. if (name.equals("http://xml.org/sax/properties/declaration-handler"))
  745. return declHandler;
  746. else
  747. if (name.equals("http://xml.org/sax/properties/lexical-handler"))
  748. return lexHandler;
  749. else
  750. throw new SAXNotRecognizedException(name);
  751. }
  752. public void setProperty(String name,Object value)
  753. throws SAXNotRecognizedException, SAXNotSupportedException {
  754. if (name.equals("http://xml.org/sax/properties/declaration-handler")) {
  755. try {
  756. declHandler = (DeclHandler) value;
  757. }
  758. catch (ClassCastException e) {
  759. throw new SAXNotSupportedException("property value is not a DeclHandler");
  760. }
  761. }
  762. else
  763. if (name.equals("http://xml.org/sax/properties/lexical-handler")) {
  764. try {
  765. lexHandler = (LexicalHandler) value;
  766. }
  767. catch (ClassCastException e) {
  768. throw new SAXNotSupportedException("property value is not a LexicalHandler");
  769. }
  770. }
  771. else
  772. throw new SAXNotRecognizedException(name);
  773. }
  774. /************************************************************************
  775. * Methods used to call ContentHandlers or DocumentHandlers
  776. ************************************************************************/
  777. void reportCdata() throws SAXException {
  778. reportCdata(lexer.cdataBuffer,lexer.cdataStart,lexer.cdataLength);
  779. }
  780. private char[] oneCharBuffer = new char[1];
  781. void reportCdata(char c) throws SAXException {
  782. oneCharBuffer[0] = c;
  783. reportCdata(oneCharBuffer,0,1);
  784. }
  785. void reportCdata(char[] buf, int off, int len) throws SAXException {
  786. switch (saxVersion) {
  787. case 2:
  788. contentHandler.characters(buf,off,len);
  789. break;
  790. case 1:
  791. documentHandler.characters(buf,off,len);
  792. break;
  793. }
  794. }
  795. void reportWhitespace() throws SAXException {
  796. reportWhitespace(lexer.cdataBuffer,lexer.cdataStart,lexer.cdataLength);
  797. }
  798. void reportWhitespace(char[] buf, int off, int len) throws SAXException {
  799. switch (saxVersion) {
  800. case 2:
  801. contentHandler.characters(buf,off,len);
  802. break;
  803. case 1:
  804. documentHandler.characters(buf,off,len);
  805. break;
  806. }
  807. }
  808. void reportError(String msg) throws SAXException {
  809. if (errorHandler != null) {
  810. errorHandler.error(new SAXParseException(msg,getPublicId(),getSystemId(),getLineNumber(),getColumnNumber()));
  811. }
  812. }
  813. void reportFatalError(String msg) throws SAXException {
  814. reportFatalError(msg,null);
  815. }
  816. void reportFatalError(String msg, Exception e) throws SAXException {
  817. if (e != null) {
  818. StringWriter stackTrace = new StringWriter();
  819. e.printStackTrace(new PrintWriter(stackTrace));
  820. if (msg != null)
  821. msg += "\n" + stackTrace.toString();
  822. else
  823. msg = stackTrace.toString();
  824. }
  825. SAXParseException spe =
  826. new SAXParseException(msg,getPublicId(),
  827. getSystemId(),getLineNumber(),getColumnNumber(),e);
  828. if (errorHandler != null)
  829. errorHandler.fatalError(spe);
  830. else
  831. throw spe;
  832. }
  833. void reportSkippedEntity(String entity) throws SAXException {
  834. if (saxVersion == 2) {
  835. contentHandler.skippedEntity(entity);
  836. }
  837. }
  838. void reportPI(String entity, String data) throws SAXException {
  839. switch (saxVersion) {
  840. case 2:
  841. contentHandler.processingInstruction(entity,data);
  842. break;
  843. case 1:
  844. documentHandler.processingInstruction(entity,data);
  845. break;
  846. }
  847. }
  848. void reportUnparsedEntityDecl(String entity, String pubID, String sysID, String notation) throws SAXException {
  849. if (dtdHandler != null) {
  850. dtdHandler.unparsedEntityDecl(entity,pubID,resolveSystemID(sysID),notation);
  851. }
  852. }
  853. void reportNotationDecl(String name, String pubID, String sysID) throws SAXException {
  854. if (dtdHandler != null)
  855. dtdHandler.notationDecl(name,pubID,resolveSystemID(sysID));
  856. }
  857. void reportStartTag(String ns, String entity, String qEntity) throws SAXException {
  858. switch (saxVersion) {
  859. case 2:
  860. contentHandler.startElement(ns,entity,qEntity,lexer.attribs);
  861. break;
  862. case 1:
  863. documentHandler.startElement(qEntity,lexer.attribs);
  864. break;
  865. }
  866. }
  867. void reportEndTag(String ns, String entity, String qEntity) throws SAXException {
  868. switch (saxVersion) {
  869. case 2:
  870. contentHandler.endElement(ns,entity,qEntity);
  871. break;
  872. case 1:
  873. documentHandler.endElement(qEntity);
  874. break;
  875. }
  876. }
  877. void reportStartPrefixMapping(String prefix, String uri) throws SAXException {
  878. if (saxVersion == 2) {
  879. contentHandler.startPrefixMapping(prefix,uri);
  880. }
  881. }
  882. void reportEndPrefixMapping(String prefix) throws SAXException {
  883. if (saxVersion == 2) {
  884. contentHandler.endPrefixMapping(prefix);
  885. }
  886. }
  887. void reportStartDocument() throws SAXException {
  888. parsingInProgress = true;
  889. switch (saxVersion) {
  890. case 2:
  891. contentHandler.startDocument();
  892. break;
  893. case 1:
  894. documentHandler.startDocument();
  895. break;
  896. }
  897. }
  898. void reportEndDocument() throws SAXException {
  899. parsingInProgress = false;
  900. switch (saxVersion) {
  901. case 2:
  902. contentHandler.endDocument();
  903. break;
  904. case 1:
  905. documentHandler.endDocument();
  906. break;
  907. }
  908. }
  909. /************************************************************************
  910. * Methods used for SAX 2 extensions
  911. ************************************************************************/
  912. // *** LexicalHandler ***
  913. void reportStartDTD(String name, String pubID, String sysID)
  914. throws SAXException {
  915. if (lexHandler != null)
  916. lexHandler.startDTD(name,pubID,sysID);
  917. }
  918. void reportEndDTD()
  919. throws SAXException {
  920. if (lexHandler != null)
  921. lexHandler.endDTD();
  922. }
  923. void reportStartEntity(String name)
  924. throws SAXException {
  925. if (lexHandler != null) {
  926. if (fLexicalParameterEntities || name.charAt(0) != '%')
  927. lexHandler.startEntity(name);
  928. }
  929. }
  930. void reportEndEntity(String name)
  931. throws SAXException {
  932. if (lexHandler != null) {
  933. if (fLexicalParameterEntities || name.charAt(0) != '%')
  934. lexHandler.endEntity(name);
  935. }
  936. }
  937. void reportStartCdata()
  938. throws SAXException {
  939. if (lexHandler != null)
  940. lexHandler.startCDATA();
  941. }
  942. void reportEndCdata()
  943. throws SAXException {
  944. if (lexHandler != null)
  945. lexHandler.endCDATA();
  946. }
  947. void reportComment(char[] ch, int start, int length)
  948. throws SAXException {
  949. if (lexHandler != null)
  950. lexHandler.comment(ch,start,length);
  951. }
  952. /************************************************************************
  953. * Miscellaneous methods used internally
  954. ************************************************************************/
  955. private void addAttributeDefinition(String qName, int valueType, int defaultType, String defaultValue)
  956. throws SAXException, IOException {
  957. String prefix="", localName="";
  958. if (fNamespaces) {
  959. localName = qName;
  960. if (qName == "xmlns" && defaultValue != null) // Internalize all URIs
  961. defaultValue.intern();
  962. }
  963. saveAttributeDefinition(prefix,localName,qName,valueType,defaultType,defaultValue);
  964. }
  965. private void addPrefixedAttributeDefinition(String qName, int valueType, int defaultType, String defaultValue)
  966. throws SAXException, IOException {
  967. String prefix, localName;
  968. if (fNamespaces) {
  969. int colon = qName.indexOf(':');
  970. int len = qName.length();
  971. qName.getChars(0,len,lexer.cbuf,0);
  972. prefix = lexer.stringConverter.convert(lexer.cbuf,0,colon);
  973. localName = lexer.stringConverter.convert(lexer.cbuf,colon+1,len-(colon+1));
  974. }
  975. else {
  976. prefix=localName="";
  977. }
  978. saveAttributeDefinition(prefix,localName,qName,valueType,defaultType,defaultValue);
  979. }
  980. private void saveAttributeDefinition(String prefix,String localName,
  981. String qName, int valueType, int defaultType, String defaultValue)
  982. throws SAXException, IOException {
  983. try {
  984. if (defaultValue != null) {
  985. if (valueType == AttributeDefinition.NMTOKEN || valueType == AttributeDefinition.NMTOKENS)
  986. defaultValue = lexer.normalizeValue(defaultValue);
  987. defaultValue = lexer.rescanAttributeValue(defaultValue);
  988. }
  989. if (declHandler != null) {
  990. String valueTypeString = null;
  991. if (valueType == AttributeDefinition.NOTATION) {
  992. modelBuffer.insert(0,"NOTATION (");
  993. modelBuffer.append(')');
  994. valueTypeString = modelBuffer.toString();
  995. }
  996. else
  997. if (valueType == AttributeDefinition.ENUMERATION) {
  998. modelBuffer.insert(0,'(');
  999. modelBuffer.append(')');
  1000. valueTypeString = modelBuffer.toString();
  1001. }
  1002. else
  1003. valueTypeString = AttributeDefinition.getValueTypeString(valueType);
  1004. declHandler.attributeDecl(elementDefinition.getName(),qName,valueTypeString,
  1005. AttributeDefinition.getDefaultTypeString(defaultType),
  1006. defaultValue);
  1007. modelBuffer.setLength(0);
  1008. }
  1009. elementDefinition.addAttribute(
  1010. new AttributeDefinition(prefix,localName,qName,valueType,null,
  1011. defaultType,defaultValue));
  1012. }
  1013. catch (DuplicateKeyException e) { // Attribute already exists; XML spec says ignore it
  1014. }
  1015. }
  1016. private String resolveSystemID(String sysID) {
  1017. String resolvedSysID;
  1018. if (fResolveDTDURIs) {
  1019. try {
  1020. return EntityManager.resolveSystemID(docEntity.getSystemID(),sysID);
  1021. }
  1022. catch (MalformedURLException e) {
  1023. return sysID;
  1024. }
  1025. }
  1026. else
  1027. return sysID;
  1028. }
  1029. private int yylex() throws IOException, SAXException
  1030. {
  1031. try {
  1032. int tok = lexer.yylex();
  1033. yylval = lexer.stringValue;
  1034. lexer.stringValue = null;
  1035. /* Uncomment for serious debugging
  1036. if (yydebug) {
  1037. if (tok == CDATA)
  1038. System.out.println("Token: CDATA");
  1039. else
  1040. System.out.println("Token: " + yyname[tok] + " (" + yylval + ")");
  1041. System.out.println("\tlexical state is now " + lexer.yystate() + ", line number " + getLineNumber() );
  1042. }
  1043. */
  1044. return tok;
  1045. }
  1046. catch (IOException e) {
  1047. while (lexer.currentEntity == null && lexer.entityStack.size() > 0) {
  1048. lexer.currentEntity = (Entity) lexer.entityStack.pop();
  1049. try {
  1050. if (lexer.yymoreStreams())
  1051. lexer.yypopStream();
  1052. }
  1053. catch (IOException ie) {}
  1054. }
  1055. throw e;
  1056. }
  1057. catch (SAXException e) {
  1058. while (lexer.currentEntity == null && lexer.entityStack.size() > 0) {
  1059. lexer.currentEntity = (Entity) lexer.entityStack.pop();
  1060. try {
  1061. if (lexer.yymoreStreams())
  1062. lexer.yypopStream();
  1063. }
  1064. catch (IOException ie) {}
  1065. }
  1066. throw e;
  1067. }
  1068. }
  1069. void yyerror(String msg) throws SAXException {
  1070. // Check if this is because of an invalid entity reference
  1071. if (yychar <= 0)
  1072. throw new FatalParsingException("Unexpected end of file after " + yylval);
  1073. else
  1074. throw new FatalParsingException("Unexpected element: " + yyname[yychar]);
  1075. }