xmlj_sax.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. /* xmlj_sax.c -
  2. Copyright (C) 2004 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. #include "xmlj_sax.h"
  32. #include "xmlj_io.h"
  33. #include "xmlj_util.h"
  34. #include <unistd.h>
  35. #include <string.h>
  36. xmlExternalEntityLoader defaultLoader = NULL;
  37. void
  38. xmljDispatchError (xmlParserCtxtPtr ctx,
  39. xmlSAXLocatorPtr loc,
  40. JNIEnv *env,
  41. jobject target,
  42. jmethodID method,
  43. const char *msg,
  44. va_list args);
  45. /* -- GnomeLocator -- */
  46. JNIEXPORT jstring JNICALL
  47. Java_gnu_xml_libxmlj_sax_GnomeLocator_publicId (JNIEnv * env,
  48. jobject self
  49. __attribute__((__unused__)),
  50. jobject j_ctx,
  51. jobject j_loc)
  52. {
  53. xmlParserCtxtPtr ctx;
  54. xmlSAXLocatorPtr loc;
  55. SAXParseContext *sax;
  56. ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
  57. loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
  58. sax = (SAXParseContext *) ctx->_private;
  59. return sax->publicId;
  60. }
  61. JNIEXPORT jstring JNICALL
  62. Java_gnu_xml_libxmlj_sax_GnomeLocator_systemId (JNIEnv * env,
  63. jobject self
  64. __attribute__((__unused__)),
  65. jobject j_ctx,
  66. jobject j_loc)
  67. {
  68. xmlParserCtxtPtr ctx;
  69. xmlSAXLocatorPtr loc;
  70. SAXParseContext *sax;
  71. ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
  72. loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
  73. sax = (SAXParseContext *) ctx->_private;
  74. return sax->systemId;
  75. }
  76. JNIEXPORT jint JNICALL
  77. Java_gnu_xml_libxmlj_sax_GnomeLocator_lineNumber (JNIEnv * env,
  78. jobject self
  79. __attribute__((__unused__)),
  80. jobject j_ctx,
  81. jobject j_loc)
  82. {
  83. xmlParserCtxtPtr ctx;
  84. xmlSAXLocatorPtr loc;
  85. ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
  86. loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
  87. if (ctx == NULL || ctx->input == NULL)
  88. {
  89. return -1;
  90. }
  91. return ctx->input->line;
  92. }
  93. JNIEXPORT jint JNICALL
  94. Java_gnu_xml_libxmlj_sax_GnomeLocator_columnNumber (JNIEnv * env,
  95. jobject self
  96. __attribute__((__unused__)),
  97. jobject j_ctx,
  98. jobject j_loc)
  99. {
  100. xmlParserCtxtPtr ctx;
  101. xmlSAXLocatorPtr loc;
  102. ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
  103. loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
  104. if (ctx == NULL || ctx->input == NULL)
  105. {
  106. return -1;
  107. }
  108. return ctx->input->col;
  109. }
  110. /* -- GnomeXMLReader -- */
  111. /*
  112. * Entry point for SAX parsing.
  113. */
  114. JNIEXPORT void JNICALL
  115. Java_gnu_xml_libxmlj_sax_GnomeXMLReader_parseStream (JNIEnv * env,
  116. jobject self,
  117. jobject in,
  118. jbyteArray detectBuffer,
  119. jstring publicId,
  120. jstring systemId,
  121. jstring base,
  122. jboolean validate,
  123. jboolean contentHandler,
  124. jboolean dtdHandler,
  125. jboolean entityResolver,
  126. jboolean errorHandler,
  127. jboolean
  128. declarationHandler,
  129. jboolean lexicalHandler)
  130. {
  131. xmljParseDocument (env,
  132. self,
  133. in,
  134. detectBuffer,
  135. publicId,
  136. systemId,
  137. base,
  138. validate,
  139. 0,
  140. 0,
  141. contentHandler,
  142. dtdHandler,
  143. entityResolver,
  144. errorHandler,
  145. declarationHandler,
  146. lexicalHandler,
  147. 0);
  148. }
  149. xmlParserInputPtr
  150. xmljExternalEntityLoader (const char *url, const char *id,
  151. xmlParserCtxtPtr ctx)
  152. {
  153. const xmlChar *systemId;
  154. const xmlChar *publicId;
  155. xmlParserInputPtr ret;
  156. systemId = xmlCharStrdup (url);
  157. publicId = xmlCharStrdup (id);
  158. /* TODO convert systemId to absolute URI */
  159. ret = xmljSAXResolveEntity (ctx, publicId, systemId);
  160. if (ret == NULL)
  161. {
  162. ret = defaultLoader (url, id, ctx);
  163. }
  164. return ret;
  165. }
  166. /*
  167. * Allocates and configures a SAX handler that can report the various
  168. * classes of callback.
  169. */
  170. xmlSAXHandlerPtr
  171. xmljNewSAXHandler (jboolean contentHandler,
  172. jboolean dtdHandler,
  173. jboolean entityResolver,
  174. jboolean errorHandler,
  175. jboolean declarationHandler,
  176. jboolean lexicalHandler)
  177. {
  178. xmlSAXHandlerPtr sax;
  179. sax = (xmlSAXHandlerPtr) malloc (sizeof (xmlSAXHandler));
  180. if (sax == NULL)
  181. {
  182. return NULL;
  183. }
  184. memset (sax, 0, sizeof (xmlSAXHandler));
  185. xmlSAXVersion (sax, 1); /* TODO SAX2 */
  186. if (dtdHandler)
  187. {
  188. sax->internalSubset = &xmljSAXInternalSubset;
  189. }
  190. if (defaultLoader == NULL)
  191. {
  192. defaultLoader = xmlGetExternalEntityLoader ();
  193. xmlSetExternalEntityLoader (xmljExternalEntityLoader);
  194. }
  195. if (entityResolver)
  196. {
  197. sax->resolveEntity = &xmljSAXResolveEntity;
  198. }
  199. if (declarationHandler)
  200. {
  201. sax->entityDecl = &xmljSAXEntityDecl;
  202. sax->notationDecl = &xmljSAXNotationDecl;
  203. sax->attributeDecl = &xmljSAXAttributeDecl;
  204. sax->elementDecl = &xmljSAXElementDecl;
  205. sax->unparsedEntityDecl = &xmljSAXUnparsedEntityDecl;
  206. }
  207. /* We always listen for the locator callback */
  208. sax->setDocumentLocator = &xmljSAXSetDocumentLocator;
  209. if (contentHandler)
  210. {
  211. sax->startDocument = &xmljSAXStartDocument;
  212. sax->endDocument = &xmljSAXEndDocument;
  213. sax->startElement = &xmljSAXStartElement;
  214. sax->endElement = &xmljSAXEndElement;
  215. sax->characters = &xmljSAXCharacters;
  216. sax->ignorableWhitespace = &xmljSAXIgnorableWhitespace;
  217. sax->processingInstruction = &xmljSAXProcessingInstruction;
  218. }
  219. /* We always intercept getEntity */
  220. /* TODO this should only be if lexicalHandler */
  221. sax->getEntity = &xmljSAXGetEntity;
  222. if (lexicalHandler)
  223. {
  224. sax->getEntity = &xmljSAXGetEntity;
  225. sax->reference = &xmljSAXReference;
  226. sax->comment = &xmljSAXComment;
  227. sax->cdataBlock = &xmljSAXCDataBlock;
  228. }
  229. else if (contentHandler)
  230. {
  231. sax->cdataBlock = &xmljSAXCharacters;
  232. }
  233. if (errorHandler)
  234. {
  235. sax->warning = &xmljSAXWarning;
  236. sax->error = &xmljSAXError;
  237. sax->fatalError = &xmljSAXFatalError;
  238. }
  239. return sax;
  240. }
  241. /* -- Callback functions -- */
  242. void
  243. xmljSAXInternalSubset (void *vctx,
  244. const xmlChar * name,
  245. const xmlChar * publicId, const xmlChar * systemId)
  246. {
  247. xmlParserCtxtPtr ctx;
  248. SAXParseContext *sax;
  249. JNIEnv *env;
  250. jobject target;
  251. jstring j_name;
  252. jstring j_publicId;
  253. jstring j_systemId;
  254. xmlSAX2InternalSubset (vctx, name, publicId, systemId);
  255. ctx = (xmlParserCtxtPtr) vctx;
  256. sax = (SAXParseContext *) ctx->_private;
  257. env = sax->env;
  258. target = sax->obj;
  259. xmljCheckWellFormed (ctx);
  260. if ((*env)->ExceptionOccurred (env))
  261. {
  262. return;
  263. }
  264. if (sax->startDTD == NULL)
  265. {
  266. sax->startDTD =
  267. xmljGetMethodID (env,
  268. target,
  269. "startDTD",
  270. "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
  271. if (sax->startDTD == NULL)
  272. {
  273. return;
  274. }
  275. }
  276. j_name = xmljNewString (env, name);
  277. j_publicId = xmljNewString (env, publicId);
  278. j_systemId = xmljNewString (env, systemId);
  279. (*env)->CallVoidMethod (env,
  280. target,
  281. sax->startDTD,
  282. j_name,
  283. j_publicId,
  284. j_systemId);
  285. }
  286. xmlParserInputPtr
  287. xmljSAXResolveEntity (void *vctx,
  288. const xmlChar * publicId, const xmlChar * systemId)
  289. {
  290. xmlParserCtxtPtr ctx;
  291. SAXParseContext *sax;
  292. JNIEnv *env;
  293. jobject target;
  294. jstring j_publicId;
  295. jstring j_systemId;
  296. jobject inputStream;
  297. /* xmlSAX2ResolveEntity (vctx, publicId, systemId); */
  298. ctx = (xmlParserCtxtPtr) vctx;
  299. if (ctx->_private == NULL)
  300. {
  301. /* Not in Kansas */
  302. return NULL;
  303. }
  304. sax = (SAXParseContext *) ctx->_private;
  305. env = sax->env;
  306. target = sax->obj;
  307. if ((*env)->ExceptionOccurred (env))
  308. {
  309. return NULL;
  310. }
  311. if (sax->resolveEntity == NULL)
  312. {
  313. sax->resolveEntity =
  314. xmljGetMethodID (env,
  315. target,
  316. "resolveEntity",
  317. "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/io/InputStream;");
  318. if (sax->resolveEntity == NULL)
  319. {
  320. return NULL;
  321. }
  322. }
  323. j_publicId = xmljNewString (env, publicId);
  324. j_systemId = xmljNewString (env, systemId);
  325. inputStream = (*env)->CallObjectMethod (env,
  326. target,
  327. sax->resolveEntity,
  328. j_publicId,
  329. j_systemId,
  330. sax->systemId);
  331. /* Return an xmlParserInputPtr corresponding to the input stream */
  332. if (inputStream != NULL)
  333. {
  334. jbyteArray detectBuffer;
  335. jmethodID getDetectBuffer;
  336. /* Get the detect buffer from the NamedInputStream */
  337. getDetectBuffer = xmljGetMethodID (env, inputStream, "getDetectBuffer",
  338. "()[B");
  339. if (getDetectBuffer == NULL)
  340. {
  341. return NULL;
  342. }
  343. detectBuffer = (*env)->CallObjectMethod (env, inputStream,
  344. getDetectBuffer);
  345. return xmljNewParserInput (env, inputStream, detectBuffer, ctx);
  346. }
  347. else
  348. {
  349. return NULL;
  350. }
  351. }
  352. xmlEntityPtr
  353. xmljSAXGetEntity (void *vctx __attribute__((__unused__)), const xmlChar * name)
  354. {
  355. xmlEntityPtr ret;
  356. /* TODO */
  357. /* ret = xmlSAX2GetEntity (vctx, name); */
  358. ret = NULL;
  359. return ret;
  360. }
  361. void
  362. xmljSAXEntityDecl (void *vctx,
  363. const xmlChar * name,
  364. int type,
  365. const xmlChar * publicId,
  366. const xmlChar * systemId,
  367. xmlChar * content)
  368. {
  369. xmlParserCtxtPtr ctx;
  370. SAXParseContext *sax;
  371. JNIEnv *env;
  372. jobject target;
  373. jstring j_name;
  374. jstring j_publicId;
  375. jstring j_systemId;
  376. jstring j_value;
  377. xmlSAX2EntityDecl (vctx, name, type, publicId, systemId, content);
  378. ctx = (xmlParserCtxtPtr) vctx;
  379. sax = (SAXParseContext *) ctx->_private;
  380. env = sax->env;
  381. target = sax->obj;
  382. xmljCheckWellFormed (ctx);
  383. if ((*env)->ExceptionOccurred (env))
  384. {
  385. return;
  386. }
  387. j_name = xmljNewString (env, name);
  388. switch (type)
  389. {
  390. case XML_INTERNAL_GENERAL_ENTITY:
  391. case XML_INTERNAL_PARAMETER_ENTITY:
  392. case XML_INTERNAL_PREDEFINED_ENTITY:
  393. if (sax->internalEntityDecl == NULL)
  394. {
  395. sax->internalEntityDecl =
  396. xmljGetMethodID (env,
  397. target,
  398. "internalEntityDecl",
  399. "(Ljava/lang/String;Ljava/lang/String;)V");
  400. if (sax->internalEntityDecl == NULL)
  401. {
  402. return;
  403. }
  404. }
  405. j_value = xmljNewString (env, content);
  406. (*env)->CallVoidMethod (env,
  407. target,
  408. sax->internalEntityDecl,
  409. j_name,
  410. j_value);
  411. break;
  412. default:
  413. if (sax->externalEntityDecl == NULL)
  414. {
  415. sax->externalEntityDecl =
  416. xmljGetMethodID (env,
  417. target,
  418. "externalEntityDecl",
  419. "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
  420. if (sax->externalEntityDecl == NULL)
  421. {
  422. return;
  423. }
  424. }
  425. j_publicId = xmljNewString (env, publicId);
  426. j_systemId = xmljNewString (env, systemId);
  427. (*env)->CallVoidMethod (env,
  428. target,
  429. sax->externalEntityDecl,
  430. j_name,
  431. j_publicId,
  432. j_systemId);
  433. }
  434. }
  435. void
  436. xmljSAXNotationDecl (void *vctx,
  437. const xmlChar * name,
  438. const xmlChar * publicId,
  439. const xmlChar * systemId)
  440. {
  441. xmlParserCtxtPtr ctx;
  442. SAXParseContext *sax;
  443. JNIEnv *env;
  444. jobject target;
  445. jstring j_name;
  446. jstring j_publicId;
  447. jstring j_systemId;
  448. xmlSAX2NotationDecl (vctx, name, publicId, systemId);
  449. ctx = (xmlParserCtxtPtr) vctx;
  450. sax = (SAXParseContext *) ctx->_private;
  451. env = sax->env;
  452. target = sax->obj;
  453. xmljCheckWellFormed (ctx);
  454. if ((*env)->ExceptionOccurred (env))
  455. {
  456. return;
  457. }
  458. if (sax->notationDecl == NULL)
  459. {
  460. sax->notationDecl =
  461. xmljGetMethodID (env,
  462. target,
  463. "notationDecl",
  464. "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
  465. if (sax->notationDecl == NULL)
  466. {
  467. return;
  468. }
  469. }
  470. j_name = xmljNewString (env, name);
  471. j_publicId = xmljNewString (env, publicId);
  472. j_systemId = xmljNewString (env, systemId);
  473. /* Invoke the method */
  474. (*env)->CallVoidMethod (env,
  475. target,
  476. sax->notationDecl,
  477. j_name,
  478. j_publicId,
  479. j_systemId);
  480. }
  481. void
  482. xmljSAXAttributeDecl (void *vctx,
  483. const xmlChar * elem,
  484. const xmlChar * fullName,
  485. int type,
  486. int def,
  487. const xmlChar * defaultValue,
  488. xmlEnumerationPtr tree)
  489. {
  490. xmlParserCtxtPtr ctx;
  491. SAXParseContext *sax;
  492. JNIEnv *env;
  493. jobject target;
  494. jstring j_eName;
  495. jstring j_aName;
  496. jstring j_type;
  497. jstring j_mode;
  498. jstring j_value;
  499. xmlSAX2AttributeDecl (vctx, elem, fullName, type, def, defaultValue, tree);
  500. ctx = (xmlParserCtxtPtr) vctx;
  501. sax = (SAXParseContext *) ctx->_private;
  502. env = sax->env;
  503. target = sax->obj;
  504. xmljCheckWellFormed (ctx);
  505. if ((*env)->ExceptionOccurred (env))
  506. {
  507. return;
  508. }
  509. if (sax->attributeDecl == NULL)
  510. {
  511. sax->attributeDecl =
  512. xmljGetMethodID (env,
  513. target,
  514. "attributeDecl",
  515. "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
  516. if (sax->attributeDecl == NULL)
  517. {
  518. return;
  519. }
  520. }
  521. j_eName = xmljNewString (env, elem);
  522. j_aName = xmljNewString (env, fullName);
  523. j_type = xmljAttributeTypeName (env, type);
  524. j_mode = xmljAttributeModeName (env, def);
  525. j_value = xmljNewString (env, defaultValue);
  526. (*env)->CallVoidMethod (env,
  527. target,
  528. sax->attributeDecl,
  529. j_eName,
  530. j_aName,
  531. j_type,
  532. j_mode,
  533. j_value);
  534. }
  535. void
  536. xmljSAXElementDecl (void *vctx,
  537. const xmlChar * name,
  538. int type,
  539. xmlElementContentPtr content)
  540. {
  541. xmlParserCtxtPtr ctx;
  542. SAXParseContext *sax;
  543. JNIEnv *env;
  544. jobject target;
  545. jstring j_name;
  546. jstring j_model;
  547. xmlSAX2ElementDecl (vctx, name, type, content);
  548. ctx = (xmlParserCtxtPtr) vctx;
  549. sax = (SAXParseContext *) ctx->_private;
  550. env = sax->env;
  551. target = sax->obj;
  552. xmljCheckWellFormed (ctx);
  553. if ((*env)->ExceptionOccurred (env))
  554. {
  555. return;
  556. }
  557. if (sax->elementDecl == NULL)
  558. {
  559. sax->elementDecl =
  560. xmljGetMethodID (env,
  561. target,
  562. "elementDecl",
  563. "(Ljava/lang/String;Ljava/lang/String;)V");
  564. if (sax->elementDecl == NULL)
  565. {
  566. return;
  567. }
  568. }
  569. j_name = xmljNewString (env, name);
  570. j_model = NULL; /* TODO */
  571. (*env)->CallVoidMethod (env,
  572. target,
  573. sax->elementDecl,
  574. j_name,
  575. j_model);
  576. }
  577. void
  578. xmljSAXUnparsedEntityDecl (void *vctx,
  579. const xmlChar * name,
  580. const xmlChar * publicId,
  581. const xmlChar * systemId,
  582. const xmlChar * notationName)
  583. {
  584. xmlParserCtxtPtr ctx;
  585. SAXParseContext *sax;
  586. JNIEnv *env;
  587. jobject target;
  588. jstring j_name;
  589. jstring j_publicId;
  590. jstring j_systemId;
  591. jstring j_notationName;
  592. xmlSAX2UnparsedEntityDecl (vctx, name, publicId, systemId, notationName);
  593. ctx = (xmlParserCtxtPtr) vctx;
  594. sax = (SAXParseContext *) ctx->_private;
  595. env = sax->env;
  596. target = sax->obj;
  597. xmljCheckWellFormed (ctx);
  598. if ((*env)->ExceptionOccurred (env))
  599. {
  600. return;
  601. }
  602. if (sax->unparsedEntityDecl == NULL)
  603. {
  604. sax->unparsedEntityDecl =
  605. xmljGetMethodID (env,
  606. target,
  607. "unparsedEntityDecl",
  608. "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
  609. if (sax->unparsedEntityDecl == NULL)
  610. {
  611. return;
  612. }
  613. }
  614. j_name = xmljNewString (env, name);
  615. j_publicId = xmljNewString (env, publicId);
  616. j_systemId = xmljNewString (env, systemId);
  617. j_notationName = xmljNewString (env, notationName);
  618. (*env)->CallVoidMethod (env,
  619. target,
  620. sax->unparsedEntityDecl,
  621. j_name,
  622. j_publicId,
  623. j_systemId,
  624. j_notationName);
  625. }
  626. void
  627. xmljSAXSetDocumentLocator (void *vctx, xmlSAXLocatorPtr loc)
  628. {
  629. xmlParserCtxtPtr ctx;
  630. SAXParseContext *sax;
  631. JNIEnv *env;
  632. jobject target;
  633. xmlSAX2SetDocumentLocator (vctx, loc);
  634. ctx = (xmlParserCtxtPtr) vctx;
  635. sax = (SAXParseContext *) ctx->_private;
  636. env = sax->env;
  637. target = sax->obj;
  638. if (target == NULL)
  639. {
  640. /* No Java parse context */
  641. return;
  642. }
  643. /* Update locator on sax context */
  644. sax->loc = loc;
  645. if ((*env)->ExceptionOccurred (env))
  646. {
  647. return;
  648. }
  649. if (sax->setDocumentLocator == NULL)
  650. {
  651. sax->setDocumentLocator = xmljGetMethodID (env,
  652. target,
  653. "setDocumentLocator",
  654. "(Ljava/lang/Object;Ljava/lang/Object;)V");
  655. if (sax->setDocumentLocator == NULL)
  656. {
  657. return;
  658. }
  659. }
  660. (*env)->CallVoidMethod (env,
  661. target,
  662. sax->setDocumentLocator,
  663. xmljAsField (env, ctx),
  664. xmljAsField (env, loc));
  665. }
  666. void
  667. xmljSAXStartDocument (void *vctx)
  668. {
  669. xmlParserCtxtPtr ctx;
  670. SAXParseContext *sax;
  671. JNIEnv *env;
  672. jobject target;
  673. xmlSAX2StartDocument (vctx);
  674. ctx = (xmlParserCtxtPtr) vctx;
  675. sax = (SAXParseContext *) ctx->_private;
  676. env = sax->env;
  677. target = sax->obj;
  678. xmljCheckWellFormed (ctx);
  679. if ((*env)->ExceptionOccurred (env))
  680. {
  681. return;
  682. }
  683. if (sax->startDocument == NULL)
  684. {
  685. sax->startDocument = xmljGetMethodID (env,
  686. target,
  687. "startDocument",
  688. "(Z)V");
  689. if (sax->startDocument == NULL)
  690. {
  691. return;
  692. }
  693. }
  694. (*env)->CallVoidMethod (env,
  695. target,
  696. sax->startDocument,
  697. ctx->standalone);
  698. }
  699. void
  700. xmljSAXEndDocument (void *vctx)
  701. {
  702. xmlParserCtxtPtr ctx;
  703. SAXParseContext *sax;
  704. JNIEnv *env;
  705. jobject target;
  706. xmlSAX2EndDocument (vctx);
  707. ctx = (xmlParserCtxtPtr) vctx;
  708. sax = (SAXParseContext *) ctx->_private;
  709. env = sax->env;
  710. target = sax->obj;
  711. xmljCheckWellFormed (ctx);
  712. if ((*env)->ExceptionOccurred (env))
  713. {
  714. return;
  715. }
  716. if (sax->endDocument == NULL)
  717. {
  718. sax->endDocument = xmljGetMethodID (env,
  719. target,
  720. "endDocument",
  721. "()V");
  722. if (sax->endDocument == NULL)
  723. {
  724. return;
  725. }
  726. }
  727. (*env)->CallVoidMethod (env,
  728. target,
  729. sax->endDocument);
  730. }
  731. void
  732. xmljSAXStartElement (void *vctx,
  733. const xmlChar * name,
  734. const xmlChar ** attrs)
  735. {
  736. xmlParserCtxtPtr ctx;
  737. SAXParseContext *sax;
  738. JNIEnv *env;
  739. jobject target;
  740. jstring j_name;
  741. jobjectArray j_attrs;
  742. jstring j_attr;
  743. jsize len;
  744. xmlSAX2StartElement (vctx, name, attrs);
  745. ctx = (xmlParserCtxtPtr) vctx;
  746. sax = (SAXParseContext *) ctx->_private;
  747. env = sax->env;
  748. target = sax->obj;
  749. xmljCheckWellFormed (ctx);
  750. if ((*env)->ExceptionOccurred (env))
  751. {
  752. return;
  753. }
  754. if (sax->startElement == NULL)
  755. {
  756. sax->startElement =
  757. xmljGetMethodID (env,
  758. target,
  759. "startElement",
  760. "(Ljava/lang/String;[Ljava/lang/String;)V");
  761. if (sax->startElement == NULL)
  762. {
  763. return;
  764. }
  765. }
  766. j_name = xmljNewString (env, name);
  767. /* build attributes array */
  768. len = 0;
  769. for (len = 0; attrs && attrs[len]; len++)
  770. {
  771. }
  772. if (len)
  773. {
  774. if (sax->stringClass == NULL)
  775. {
  776. sax->stringClass = (*env)->FindClass (env, "java/lang/String");
  777. if (sax->stringClass == NULL)
  778. {
  779. fprintf (stderr, "Can't find java.lang.String class!\n");
  780. return;
  781. }
  782. }
  783. j_attrs = (*env)->NewObjectArray (env, len, sax->stringClass, NULL);
  784. if (j_attrs == NULL)
  785. {
  786. fprintf (stderr, "Can't allocate attributes array!\n");
  787. return;
  788. }
  789. len = 0;
  790. for (len = 0; attrs && attrs[len]; len++)
  791. {
  792. j_attr = xmljNewString (env, attrs[len]);
  793. (*env)->SetObjectArrayElement (env, j_attrs, len, j_attr);
  794. }
  795. (*env)->CallVoidMethod (env,
  796. target,
  797. sax->startElement,
  798. j_name,
  799. j_attrs);
  800. (*env)->DeleteLocalRef (env, j_attrs);
  801. }
  802. else
  803. {
  804. (*env)->CallVoidMethod (env,
  805. target,
  806. sax->startElement,
  807. j_name,
  808. NULL);
  809. }
  810. }
  811. void
  812. xmljSAXEndElement (void *vctx,
  813. const xmlChar * name)
  814. {
  815. xmlParserCtxtPtr ctx;
  816. SAXParseContext *sax;
  817. JNIEnv *env;
  818. jobject target;
  819. jstring j_name;
  820. xmlSAX2EndElement (vctx, name);
  821. ctx = (xmlParserCtxtPtr) vctx;
  822. sax = (SAXParseContext *) ctx->_private;
  823. env = sax->env;
  824. target = sax->obj;
  825. xmljCheckWellFormed (ctx);
  826. if ((*env)->ExceptionOccurred (env))
  827. {
  828. return;
  829. }
  830. if (sax->endElement == NULL)
  831. {
  832. sax->endElement = xmljGetMethodID (env,
  833. target,
  834. "endElement",
  835. "(Ljava/lang/String;)V");
  836. if (sax->endElement == NULL)
  837. {
  838. return;
  839. }
  840. }
  841. j_name = xmljNewString (env, name);
  842. (*env)->CallVoidMethod (env,
  843. target,
  844. sax->endElement,
  845. j_name);
  846. }
  847. void
  848. xmljSAXReference (void *vctx,
  849. const xmlChar * name)
  850. {
  851. xmlSAX2Reference (vctx, name);
  852. }
  853. void
  854. xmljSAXCharacters (void *vctx,
  855. const xmlChar * ch,
  856. int len)
  857. {
  858. xmlParserCtxtPtr ctx;
  859. SAXParseContext *sax;
  860. JNIEnv *env;
  861. jobject target;
  862. jstring j_ch;
  863. xmlChar *dup;
  864. xmlSAX2Characters (vctx, ch, len);
  865. ctx = (xmlParserCtxtPtr) vctx;
  866. sax = (SAXParseContext *) ctx->_private;
  867. env = sax->env;
  868. target = sax->obj;
  869. xmljCheckWellFormed (ctx);
  870. if ((*env)->ExceptionOccurred (env))
  871. {
  872. return;
  873. }
  874. if (sax->characters == NULL)
  875. {
  876. sax->characters = xmljGetMethodID (env,
  877. target,
  878. "characters",
  879. "(Ljava/lang/String;)V");
  880. if (sax->characters == NULL)
  881. {
  882. return;
  883. }
  884. }
  885. dup = xmlStrndup (ch, len);
  886. j_ch = xmljNewString (env, dup);
  887. (*env)->CallVoidMethod (env,
  888. target,
  889. sax->characters,
  890. j_ch);
  891. xmlFree (dup);
  892. }
  893. void
  894. xmljSAXIgnorableWhitespace (void *vctx,
  895. const xmlChar * ch,
  896. int len)
  897. {
  898. xmlParserCtxtPtr ctx;
  899. SAXParseContext *sax;
  900. JNIEnv *env;
  901. jobject target;
  902. jstring j_ch;
  903. xmlChar *dup;
  904. xmlSAX2IgnorableWhitespace (vctx, ch, len);
  905. ctx = (xmlParserCtxtPtr) vctx;
  906. sax = (SAXParseContext *) ctx->_private;
  907. env = sax->env;
  908. target = sax->obj;
  909. xmljCheckWellFormed (ctx);
  910. if ((*env)->ExceptionOccurred (env))
  911. {
  912. return;
  913. }
  914. if (sax->ignorableWhitespace == NULL)
  915. {
  916. sax->ignorableWhitespace = xmljGetMethodID (env,
  917. target,
  918. "ignorableWhitespace",
  919. "(Ljava/lang/String;)V");
  920. if (sax->ignorableWhitespace == NULL)
  921. {
  922. return;
  923. }
  924. }
  925. dup = xmlStrndup (ch, len);
  926. j_ch = xmljNewString (env, dup);
  927. (*env)->CallVoidMethod (env,
  928. target,
  929. sax->ignorableWhitespace,
  930. j_ch);
  931. xmlFree (dup);
  932. }
  933. void
  934. xmljSAXProcessingInstruction (void *vctx,
  935. const xmlChar * targ,
  936. const xmlChar * data)
  937. {
  938. xmlParserCtxtPtr ctx;
  939. SAXParseContext *sax;
  940. JNIEnv *env;
  941. jobject target;
  942. jstring j_targ;
  943. jstring j_data;
  944. xmlSAX2ProcessingInstruction (vctx, targ, data);
  945. ctx = (xmlParserCtxtPtr) vctx;
  946. sax = (SAXParseContext *) ctx->_private;
  947. env = sax->env;
  948. target = sax->obj;
  949. xmljCheckWellFormed (ctx);
  950. if ((*env)->ExceptionOccurred (env))
  951. {
  952. return;
  953. }
  954. if (sax->processingInstruction == NULL)
  955. {
  956. sax->processingInstruction =
  957. xmljGetMethodID (env,
  958. target,
  959. "processingInstruction",
  960. "(Ljava/lang/String;Ljava/lang/String;)V");
  961. if (sax->processingInstruction == NULL)
  962. {
  963. return;
  964. }
  965. }
  966. j_targ = xmljNewString (env, targ);
  967. j_data = xmljNewString (env, data);
  968. (*env)->CallVoidMethod (env,
  969. target,
  970. sax->processingInstruction,
  971. j_targ,
  972. j_data);
  973. }
  974. void
  975. xmljSAXComment (void *vctx,
  976. const xmlChar * value)
  977. {
  978. xmlParserCtxtPtr ctx;
  979. SAXParseContext *sax;
  980. JNIEnv *env;
  981. jobject target;
  982. jstring j_text;
  983. xmlSAX2Comment (vctx, value);
  984. ctx = (xmlParserCtxtPtr) vctx;
  985. sax = (SAXParseContext *) ctx->_private;
  986. env = sax->env;
  987. target = sax->obj;
  988. xmljCheckWellFormed (ctx);
  989. if ((*env)->ExceptionOccurred (env))
  990. {
  991. return;
  992. }
  993. if (sax->comment == NULL)
  994. {
  995. sax->comment =
  996. xmljGetMethodID (env,
  997. target,
  998. "comment",
  999. "(Ljava/lang/String;)V");
  1000. if (sax->comment == NULL)
  1001. {
  1002. return;
  1003. }
  1004. }
  1005. j_text = xmljNewString (env, value);
  1006. (*env)->CallVoidMethod (env,
  1007. target,
  1008. sax->comment,
  1009. j_text);
  1010. }
  1011. void
  1012. xmljSAXCDataBlock (void *vctx,
  1013. const xmlChar * ch,
  1014. int len)
  1015. {
  1016. xmlParserCtxtPtr ctx;
  1017. SAXParseContext *sax;
  1018. JNIEnv *env;
  1019. jobject target;
  1020. jstring j_ch;
  1021. xmlChar *dup;
  1022. xmlSAX2CDataBlock (vctx, ch, len);
  1023. ctx = (xmlParserCtxtPtr) vctx;
  1024. sax = (SAXParseContext *) ctx->_private;
  1025. env = sax->env;
  1026. target = sax->obj;
  1027. xmljCheckWellFormed (ctx);
  1028. if ((*env)->ExceptionOccurred (env))
  1029. {
  1030. return;
  1031. }
  1032. if (sax->cdataBlock == NULL)
  1033. {
  1034. sax->cdataBlock =
  1035. xmljGetMethodID (env,
  1036. target,
  1037. "cdataBlock",
  1038. "(Ljava/lang/String;)V");
  1039. if (sax->cdataBlock == NULL)
  1040. {
  1041. return;
  1042. }
  1043. }
  1044. dup = xmlStrndup (ch, len);
  1045. j_ch = xmljNewString (env, dup);
  1046. (*env)->CallVoidMethod (env,
  1047. target,
  1048. sax->cdataBlock,
  1049. j_ch);
  1050. xmlFree (dup);
  1051. }
  1052. void
  1053. xmljDispatchError (xmlParserCtxtPtr ctx,
  1054. xmlSAXLocatorPtr loc,
  1055. JNIEnv *env,
  1056. jobject target,
  1057. jmethodID method,
  1058. const char *msg,
  1059. va_list args)
  1060. {
  1061. jint lineNumber;
  1062. jint columnNumber;
  1063. jstring publicId;
  1064. jstring systemId;
  1065. char buffer[2048] = "";
  1066. if (msg != NULL)
  1067. {
  1068. vsnprintf (buffer, sizeof buffer, msg, args);
  1069. }
  1070. lineNumber = loc->getLineNumber (ctx);
  1071. columnNumber = loc->getColumnNumber (ctx);
  1072. publicId = xmljNewString (env, loc->getPublicId (ctx));
  1073. systemId = xmljNewString (env, loc->getSystemId (ctx));
  1074. (*env)->CallVoidMethod (env,
  1075. target,
  1076. method,
  1077. (*env)->NewStringUTF (env, buffer),
  1078. lineNumber,
  1079. columnNumber,
  1080. publicId,
  1081. systemId);
  1082. }
  1083. void
  1084. xmljSAXWarning (void *vctx,
  1085. const char *msg,
  1086. ...)
  1087. {
  1088. va_list args;
  1089. xmlParserCtxtPtr ctx;
  1090. SAXParseContext *sax;
  1091. xmlSAXLocatorPtr loc;
  1092. JNIEnv *env;
  1093. jobject target;
  1094. ctx = (xmlParserCtxtPtr) vctx;
  1095. sax = (SAXParseContext *) ctx->_private;
  1096. loc = (xmlSAXLocatorPtr) sax->loc;
  1097. env = sax->env;
  1098. target = sax->obj;
  1099. if ((*env)->ExceptionOccurred (env))
  1100. {
  1101. return;
  1102. }
  1103. if (sax->warning == NULL)
  1104. {
  1105. sax->warning =
  1106. xmljGetMethodID (env,
  1107. target,
  1108. "warning",
  1109. "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
  1110. if (sax->warning == NULL)
  1111. {
  1112. return;
  1113. }
  1114. }
  1115. va_start (args, msg);
  1116. /* xmlParserWarning (vctx, msg, args); */
  1117. xmljDispatchError (ctx, loc, env, target, sax->warning, msg, args);
  1118. va_end (args);
  1119. }
  1120. void
  1121. xmljSAXError (void *vctx,
  1122. const char *msg,
  1123. ...)
  1124. {
  1125. va_list args;
  1126. xmlParserCtxtPtr ctx;
  1127. SAXParseContext *sax;
  1128. xmlSAXLocatorPtr loc;
  1129. JNIEnv *env;
  1130. jobject target;
  1131. ctx = (xmlParserCtxtPtr) vctx;
  1132. sax = (SAXParseContext *) ctx->_private;
  1133. loc = (xmlSAXLocatorPtr) sax->loc;
  1134. env = sax->env;
  1135. target = sax->obj;
  1136. if ((*env)->ExceptionOccurred (env))
  1137. {
  1138. return;
  1139. }
  1140. if (sax->error == NULL)
  1141. {
  1142. sax->error =
  1143. xmljGetMethodID (env,
  1144. target,
  1145. "error",
  1146. "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
  1147. if (sax->error == NULL)
  1148. {
  1149. return;
  1150. }
  1151. }
  1152. va_start (args, msg);
  1153. /* xmlParserError (vctx, msg, args); */
  1154. xmljDispatchError (ctx, loc, env, target, sax->error, msg, args);
  1155. va_end (args);
  1156. }
  1157. void
  1158. xmljSAXFatalError (void *vctx,
  1159. const char *msg,
  1160. ...)
  1161. {
  1162. va_list args;
  1163. xmlParserCtxtPtr ctx;
  1164. SAXParseContext *sax;
  1165. xmlSAXLocatorPtr loc;
  1166. JNIEnv *env;
  1167. jobject target;
  1168. ctx = (xmlParserCtxtPtr) vctx;
  1169. sax = (SAXParseContext *) ctx->_private;
  1170. loc = (xmlSAXLocatorPtr) sax->loc;
  1171. env = sax->env;
  1172. target = sax->obj;
  1173. if ((*env)->ExceptionOccurred (env))
  1174. {
  1175. return;
  1176. }
  1177. if (sax->fatalError == NULL)
  1178. {
  1179. sax->fatalError =
  1180. xmljGetMethodID (env,
  1181. target,
  1182. "fatalError",
  1183. "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
  1184. if (sax->fatalError == NULL)
  1185. {
  1186. return;
  1187. }
  1188. }
  1189. va_start (args, msg);
  1190. /* xmlParserError (vctx, msg, args); */
  1191. xmljDispatchError (ctx, loc, env, target, sax->fatalError, msg, args);
  1192. va_end (args);
  1193. }
  1194. void
  1195. xmljCheckWellFormed (xmlParserCtxtPtr ctx)
  1196. {
  1197. if (!ctx->wellFormed)
  1198. {
  1199. xmljSAXFatalError (ctx, "document is not well-formed");
  1200. }
  1201. if (ctx->validate && !ctx->valid)
  1202. {
  1203. xmljSAXFatalError (ctx, "document is not valid");
  1204. }
  1205. }
  1206. /*
  1207. * Convert a libxml2 attribute type to a string.
  1208. */
  1209. jstring
  1210. xmljAttributeTypeName (JNIEnv * env, int type)
  1211. {
  1212. const char *text;
  1213. switch (type)
  1214. {
  1215. case XML_ATTRIBUTE_CDATA:
  1216. text = "CDATA";
  1217. break;
  1218. case XML_ATTRIBUTE_ID:
  1219. text = "ID";
  1220. break;
  1221. case XML_ATTRIBUTE_IDREF:
  1222. text = "IDREF";
  1223. break;
  1224. case XML_ATTRIBUTE_IDREFS:
  1225. text = "IDREFS";
  1226. break;
  1227. case XML_ATTRIBUTE_NMTOKEN:
  1228. text = "NMTOKEN";
  1229. break;
  1230. case XML_ATTRIBUTE_NMTOKENS:
  1231. text = "NMTOKENS";
  1232. break;
  1233. case XML_ATTRIBUTE_ENTITY:
  1234. text = "ID";
  1235. break;
  1236. case XML_ATTRIBUTE_ENTITIES:
  1237. text = "ID";
  1238. break;
  1239. default:
  1240. return NULL;
  1241. }
  1242. return (*env)->NewStringUTF (env, text);
  1243. }
  1244. /*
  1245. * Convert a libxml2 attribute default value type to a string.
  1246. */
  1247. jstring
  1248. xmljAttributeModeName (JNIEnv * env, int type)
  1249. {
  1250. const char *text;
  1251. switch (type)
  1252. {
  1253. case XML_ATTRIBUTE_IMPLIED:
  1254. text = "#IMPLIED";
  1255. break;
  1256. case XML_ATTRIBUTE_REQUIRED:
  1257. text = "#REQUIRED";
  1258. break;
  1259. case XML_ATTRIBUTE_FIXED:
  1260. text = "#FIXED";
  1261. break;
  1262. default:
  1263. return NULL;
  1264. }
  1265. return (*env)->NewStringUTF (env, text);
  1266. }