xmlj_transform.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. /* xmlj_transform.c -
  2. Copyright (C) 2003, 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 "gnu_xml_libxmlj_transform_GnomeTransformerFactory.h"
  32. #include "gnu_xml_libxmlj_transform_GnomeTransformer.h"
  33. #include "xmlj_dom.h"
  34. #include "xmlj_io.h"
  35. #include "xmlj_error.h"
  36. #include "xmlj_node.h"
  37. #include "xmlj_sax.h"
  38. #include "xmlj_util.h"
  39. #include <math.h>
  40. #include <stdarg.h>
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <libxml/xmlmemory.h>
  44. #include <libxml/debugXML.h>
  45. #include <libxml/xmlIO.h>
  46. #include <libxml/xinclude.h>
  47. #include <libxml/parser.h>
  48. #include <libxml/catalog.h>
  49. #include <libxslt/keys.h>
  50. #include <libxslt/xslt.h>
  51. #include <libxslt/xsltInternals.h>
  52. #include <libxslt/transform.h>
  53. #include <libxslt/xsltutils.h>
  54. #include <libxslt/functions.h>
  55. #include <libxslt/extensions.h>
  56. #include <libxslt/documents.h>
  57. /* Local function prototypes */
  58. void
  59. xmljDocumentFunction (xmlXPathParserContextPtr ctxt, int nargs);
  60. xsltStylesheetPtr
  61. xmljGetStylesheetID (JNIEnv * env, jobject transformer);
  62. jobject
  63. xmljGetTransformerProperties (JNIEnv *env, jobject transformer);
  64. const xmlChar *
  65. xmljBooleanToString (int value);
  66. void
  67. xmljSetOutputProperties (JNIEnv *env, jobject transformer,
  68. xsltStylesheetPtr stylesheet);
  69. jobjectArray
  70. xmljGetParameterArray (JNIEnv *env, jobject transformer);
  71. const char **
  72. xmljGetParameters (JNIEnv *env, jobjectArray pa);
  73. void
  74. xmljFreeParameters (JNIEnv *env, jobjectArray pa, const char **parameters);
  75. xmlDocPtr
  76. xmljTransform (JNIEnv *env, jobject transformer, xmlDocPtr source);
  77. void
  78. xmljTransformToSAX (JNIEnv *env, jobject transformer, xmlDocPtr source,
  79. jobject callback);
  80. xmlDocPtr
  81. xmljDocLoader (const xmlChar *uri, xmlDictPtr dict, int options,
  82. void *ctxt, xsltLoadType type);
  83. /* HACK: store stylesheet URL as context for resolving URIs in xmljDocLoader */
  84. static jstring stylesheetURL = NULL;
  85. /*
  86. * --------------------------------------------------------------------------
  87. *
  88. * Native implementation for class
  89. * gnu.xml.libxmlj.transform.GnomeTransformer follows.
  90. */
  91. static void
  92. xmljSetProperty (JNIEnv * env, jobject outputProperties,
  93. jmethodID setPropertyMethodID, const char *name,
  94. const xmlChar * value)
  95. {
  96. if (NULL != value)
  97. {
  98. jstring nameString = (*env)->NewStringUTF (env, name);
  99. jstring valueString = (*env)->NewStringUTF (env, (const char *) value);
  100. jobject prevValue = (*env)->CallObjectMethod (env, outputProperties,
  101. setPropertyMethodID,
  102. nameString, valueString);
  103. if (NULL != prevValue)
  104. {
  105. (*env)->DeleteLocalRef (env, prevValue);
  106. }
  107. (*env)->DeleteLocalRef (env, nameString);
  108. (*env)->DeleteLocalRef (env, valueString);
  109. }
  110. }
  111. typedef struct CdataSectionScannerInfo_
  112. {
  113. JNIEnv *env;
  114. jobject stringBuffer;
  115. jmethodID appendMethodID;
  116. int isFirst;
  117. } CdataSectionScannerInfo;
  118. static void
  119. cdataSectionScanner (void *payload, void *data, xmlChar * name)
  120. {
  121. CdataSectionScannerInfo *info = (CdataSectionScannerInfo *) data;
  122. JNIEnv *env = info->env;
  123. jstring nameString = (*env)->NewStringUTF (env, (const char *) name);
  124. jstring blankString = (*env)->NewStringUTF (env, " ");
  125. jobject stringBuffer;
  126. if (!info->isFirst)
  127. {
  128. stringBuffer
  129. = (*env)->CallObjectMethod (env,
  130. info->stringBuffer,
  131. info->appendMethodID, blankString);
  132. (*env)->DeleteLocalRef (env, stringBuffer);
  133. }
  134. info->isFirst = 0;
  135. stringBuffer
  136. = (*env)->CallObjectMethod (env,
  137. info->stringBuffer,
  138. info->appendMethodID, nameString);
  139. (*env)->DeleteLocalRef (env, stringBuffer);
  140. (*env)->DeleteLocalRef (env, blankString);
  141. (*env)->DeleteLocalRef (env, nameString);
  142. }
  143. void
  144. xmljDocumentFunction (xmlXPathParserContextPtr ctxt, int nargs)
  145. {
  146. xmlXPathObjectPtr obj, obj2 = NULL;
  147. if ((nargs < 1) || (nargs > 2))
  148. {
  149. xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
  150. "document() : invalid number of args %d\n", nargs);
  151. ctxt->error = XPATH_INVALID_ARITY;
  152. return;
  153. }
  154. if (ctxt->value == NULL)
  155. {
  156. xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
  157. "document() : invalid arg value\n");
  158. ctxt->error = XPATH_INVALID_TYPE;
  159. return;
  160. }
  161. if (nargs == 2)
  162. {
  163. if (ctxt->value->type != XPATH_NODESET)
  164. {
  165. xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
  166. "document() : invalid arg expecting a nodeset\n");
  167. ctxt->error = XPATH_INVALID_TYPE;
  168. return;
  169. }
  170. obj2 = valuePop (ctxt);
  171. }
  172. if (ctxt->value->type == XPATH_NODESET)
  173. {
  174. int i;
  175. xmlXPathObjectPtr newobj, ret;
  176. obj = valuePop (ctxt);
  177. ret = xmlXPathNewNodeSet (NULL);
  178. if (obj->nodesetval)
  179. {
  180. for (i = 0; i < obj->nodesetval->nodeNr; i++)
  181. {
  182. valuePush (ctxt,
  183. xmlXPathNewNodeSet (obj->nodesetval->nodeTab[i]));
  184. xmlXPathStringFunction (ctxt, 1);
  185. if (nargs == 2)
  186. {
  187. valuePush (ctxt, xmlXPathObjectCopy (obj2));
  188. }
  189. else
  190. {
  191. valuePush (ctxt,
  192. xmlXPathNewNodeSet (obj->nodesetval->
  193. nodeTab[i]));
  194. }
  195. xsltDocumentFunction (ctxt, 2);
  196. newobj = valuePop (ctxt);
  197. ret->nodesetval = xmlXPathNodeSetMerge (ret->nodesetval,
  198. newobj->nodesetval);
  199. xmlXPathFreeObject (newobj);
  200. }
  201. }
  202. xmlXPathFreeObject (obj);
  203. if (obj2 != NULL)
  204. {
  205. xmlXPathFreeObject (obj2);
  206. }
  207. valuePush (ctxt, ret);
  208. return;
  209. }
  210. /*
  211. * Make sure it's converted to a string
  212. */
  213. xmlXPathStringFunction (ctxt, 1);
  214. if (ctxt->value->type != XPATH_STRING)
  215. {
  216. xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
  217. "document() : invalid arg expecting a string\n");
  218. ctxt->error = XPATH_INVALID_TYPE;
  219. if (obj2 != NULL)
  220. xmlXPathFreeObject (obj2);
  221. return;
  222. }
  223. obj = valuePop (ctxt);
  224. if (obj->stringval == NULL)
  225. {
  226. valuePush (ctxt, xmlXPathNewNodeSet (NULL));
  227. }
  228. else
  229. {
  230. xsltTransformContextPtr tctxt;
  231. tctxt = xsltXPathGetTransformContext (ctxt);
  232. {
  233. SAXParseContext *saxContext =
  234. (SAXParseContext *) tctxt->style->_private;
  235. xmlDocPtr tree = xmljResolveURIAndOpen (saxContext,
  236. (const char*)obj->stringval,
  237. NULL);
  238. xsltNewDocument (tctxt, tree); /* FIXME - free at a later point */
  239. valuePush (ctxt, xmlXPathNewNodeSet ((xmlNodePtr) tree));
  240. }
  241. }
  242. xmlXPathFreeObject (obj);
  243. if (obj2 != NULL) {
  244. xmlXPathFreeObject (obj2);
  245. }
  246. }
  247. /*
  248. * Returns the stylesheet pointer for the given GnomeTransformer.
  249. */
  250. xsltStylesheetPtr
  251. xmljGetStylesheetID (JNIEnv * env, jobject transformer)
  252. {
  253. jclass cls;
  254. jfieldID field;
  255. jobject id;
  256. xsltStylesheetPtr stylesheet;
  257. if (transformer == NULL)
  258. {
  259. xmljThrowException (env, "javax/xml/transform/TransformerException",
  260. "Transformer is null");
  261. return NULL;
  262. }
  263. cls = (*env)->GetObjectClass (env, transformer);
  264. if (cls == NULL)
  265. {
  266. return NULL;
  267. }
  268. field = (*env)->GetFieldID (env, cls, "stylesheet", "Ljava/lang/Object;");
  269. if (field == NULL)
  270. {
  271. return NULL;
  272. }
  273. id = (*env)->GetObjectField (env, transformer, field);
  274. stylesheet = (xsltStylesheetPtr) xmljAsPointer (env, id);
  275. if (stylesheet == NULL)
  276. {
  277. xmljThrowException (env, "javax/xml/transform/TransformerException",
  278. "Stylesheet is null");
  279. return NULL;
  280. }
  281. return stylesheet;
  282. }
  283. jobject
  284. xmljGetTransformerProperties (JNIEnv *env, jobject transformer)
  285. {
  286. jclass cls;
  287. jfieldID field;
  288. cls = (*env)->GetObjectClass (env, transformer);
  289. if (cls == NULL)
  290. {
  291. return NULL;
  292. }
  293. field = (*env)->GetFieldID (env, cls, "outputProperties",
  294. "Ljava/util/Properties;");
  295. if (field == NULL)
  296. {
  297. return NULL;
  298. }
  299. return (*env)->GetObjectField (env, transformer, field);
  300. }
  301. const xmlChar *
  302. xmljBooleanToString (int value)
  303. {
  304. return value ? BAD_CAST "yes" : BAD_CAST "no";
  305. }
  306. /*
  307. * Sets the output properties for the given transformer,
  308. * based on its stylesheet.
  309. */
  310. void
  311. xmljSetOutputProperties (JNIEnv *env, jobject transformer,
  312. xsltStylesheetPtr stylesheet)
  313. {
  314. jobject outputProperties;
  315. jclass propertiesClass;
  316. jmethodID setPropertyMethod;
  317. outputProperties = xmljGetTransformerProperties (env, transformer);
  318. if (outputProperties == NULL)
  319. {
  320. return;
  321. }
  322. propertiesClass = (*env)->FindClass (env, "java/util/Properties");
  323. if (propertiesClass == NULL)
  324. {
  325. return;
  326. }
  327. setPropertyMethod =
  328. (*env)->GetMethodID (env, propertiesClass, "setProperty",
  329. "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
  330. if (setPropertyMethod == NULL)
  331. {
  332. return;
  333. }
  334. xmljSetProperty (env, outputProperties, setPropertyMethod,
  335. "encoding", stylesheet->encoding);
  336. xmljSetProperty (env, outputProperties, setPropertyMethod,
  337. "media-type", stylesheet->mediaType);
  338. xmljSetProperty (env, outputProperties, setPropertyMethod,
  339. "doctype-public", stylesheet->doctypePublic);
  340. xmljSetProperty (env, outputProperties, setPropertyMethod,
  341. "doctype-system", stylesheet->doctypeSystem);
  342. xmljSetProperty (env, outputProperties, setPropertyMethod,
  343. "indent", xmljBooleanToString (stylesheet->indent));
  344. xmljSetProperty (env, outputProperties, setPropertyMethod,
  345. "method", stylesheet->method);
  346. xmljSetProperty (env, outputProperties, setPropertyMethod,
  347. "standalone", xmljBooleanToString (stylesheet->standalone));
  348. xmljSetProperty (env, outputProperties, setPropertyMethod,
  349. "version", stylesheet->version);
  350. xmljSetProperty (env, outputProperties, setPropertyMethod,
  351. "omit-xml-declaration",
  352. xmljBooleanToString (stylesheet->omitXmlDeclaration));
  353. {
  354. CdataSectionScannerInfo info;
  355. jclass stringBufferClass
  356. =
  357. (*env)->FindClass (env,
  358. "java/lang/StringBuffer");
  359. jmethodID stringBufferConstructorID =
  360. (*env)->GetMethodID (env, stringBufferClass,
  361. "<init>", "()V");
  362. jmethodID toStringMethodID =
  363. (*env)->GetMethodID (env, stringBufferClass,
  364. "toString",
  365. "()Ljava/lang/String;");
  366. info.env = env;
  367. info.isFirst = 1;
  368. info.stringBuffer
  369. = (*env)->AllocObject (env, stringBufferClass);
  370. (*env)->CallVoidMethod (env, info.stringBuffer,
  371. stringBufferConstructorID);
  372. info.appendMethodID =
  373. (*env)->GetMethodID (env, stringBufferClass,
  374. "append",
  375. "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
  376. xmlHashScan (stylesheet->cdataSection,
  377. cdataSectionScanner, &info);
  378. {
  379. jstring result = (jstring)
  380. (*env)->CallObjectMethod (env,
  381. info.stringBuffer,
  382. toStringMethodID);
  383. jstring nameString =
  384. (*env)->NewStringUTF (env,
  385. "cdata-section-elements");
  386. jobject prevValue
  387. =
  388. (*env)->CallObjectMethod (env,
  389. outputProperties,
  390. setPropertyMethod,
  391. nameString, result);
  392. if (NULL != prevValue)
  393. {
  394. (*env)->DeleteLocalRef (env, prevValue);
  395. }
  396. (*env)->DeleteLocalRef (env, nameString);
  397. }
  398. (*env)->DeleteLocalRef (env, info.stringBuffer);
  399. }
  400. }
  401. /*
  402. * Returns the parameter array for the given GnomeTransformer.
  403. */
  404. jobjectArray
  405. xmljGetParameterArray (JNIEnv *env, jobject transformer)
  406. {
  407. jclass cls;
  408. jmethodID method;
  409. cls = (*env)->GetObjectClass (env, transformer);
  410. if (cls == NULL)
  411. {
  412. return NULL;
  413. }
  414. method = (*env)->GetMethodID (env, cls, "getParameterArray",
  415. "()[Ljava/lang/String;");
  416. if (method == NULL)
  417. {
  418. return NULL;
  419. }
  420. return (jobjectArray) (*env)->CallObjectMethod (env, transformer, method);
  421. }
  422. /* Convert parameter array to xmlChar ** */
  423. const char **
  424. xmljGetParameters (JNIEnv *env, jobjectArray pa)
  425. {
  426. int i, len;
  427. const char **parameters;
  428. len = (*env)->GetArrayLength (env, pa);
  429. parameters = (const char **) malloc ((len + 2) * sizeof (const char *));
  430. if (parameters == NULL)
  431. {
  432. return NULL;
  433. }
  434. for (i = 0; i < len; i++)
  435. {
  436. jstring string = (jstring) (*env)->GetObjectArrayElement (env, pa, i);
  437. if (string != NULL)
  438. {
  439. parameters[i] = (*env)->GetStringUTFChars (env, string, NULL);
  440. }
  441. else
  442. {
  443. parameters[i] = NULL;
  444. }
  445. }
  446. parameters[len] = 0;
  447. parameters[len + 1] = 0;
  448. return parameters;
  449. }
  450. /* Release parameter strings */
  451. void
  452. xmljFreeParameters (JNIEnv *env, jobjectArray pa, const char **parameters)
  453. {
  454. int i, len;
  455. len = (*env)->GetArrayLength (env, pa);
  456. for (i = 0; i < len; i++)
  457. {
  458. jstring string = (jstring) (*env)->GetObjectArrayElement (env, pa, i);
  459. if (string != NULL)
  460. {
  461. (*env)->ReleaseStringUTFChars (env, string, parameters[i]);
  462. }
  463. }
  464. free (parameters);
  465. }
  466. xmlDocPtr
  467. xmljTransform (JNIEnv *env, jobject transformer, xmlDocPtr source)
  468. {
  469. xsltStylesheetPtr stylesheet;
  470. xmlDocPtr result;
  471. jobjectArray pa;
  472. const char **parameters;
  473. stylesheet = xmljGetStylesheetID (env, transformer);
  474. pa = xmljGetParameterArray (env, transformer);
  475. parameters = xmljGetParameters (env, pa);
  476. if (parameters == NULL)
  477. {
  478. xmljThrowException (env, "javax/xml/transform/TransformerException",
  479. "Couldn't allocate memory for parameters");
  480. return NULL;
  481. }
  482. result = xsltApplyStylesheet (stylesheet, source, parameters);
  483. xmljFreeParameters (env, pa, parameters);
  484. if (result == NULL)
  485. {
  486. xmljThrowException (env, "javax/xml/transform/TransformerException",
  487. "XSLT transformation failed");
  488. }
  489. return result;
  490. }
  491. void
  492. xmljTransformToSAX (JNIEnv *env, jobject transformer, xmlDocPtr source,
  493. jobject callback)
  494. {
  495. xsltStylesheetPtr stylesheet;
  496. int ret;
  497. jobjectArray pa;
  498. const char **parameters;
  499. xmlSAXHandlerPtr sax;
  500. stylesheet = xmljGetStylesheetID (env, transformer);
  501. pa = xmljGetParameterArray (env, transformer);
  502. parameters = xmljGetParameters (env, pa);
  503. if (parameters == NULL)
  504. {
  505. xmljThrowException (env, "javax/xml/transform/TransformerException",
  506. "Couldn't allocate memory for parameters");
  507. return;
  508. }
  509. sax = NULL; /* TODO link up sax and callback */
  510. ret = xsltRunStylesheet (stylesheet, source, parameters, NULL, sax, NULL);
  511. xmljFreeParameters (env, pa, parameters);
  512. if (ret == -1)
  513. {
  514. xmljThrowException (env, "javax/xml/transform/TransformerException",
  515. "XSLT transformation failed");
  516. }
  517. }
  518. xmlDocPtr
  519. xmljDocLoader (const xmlChar *uri, xmlDictPtr dict, int options,
  520. void *ctxt, xsltLoadType type)
  521. {
  522. JNIEnv *env;
  523. jclass xmljClass;
  524. jclass inputStreamClass;
  525. jmethodID getInputStream;
  526. jmethodID getDetectBuffer;
  527. jstring systemId;
  528. jobject inputStream;
  529. jbyteArray detectBuffer;
  530. fflush(stdout);
  531. env = xmljGetJNIEnv ();
  532. if (!env)
  533. {
  534. return NULL;
  535. }
  536. xmljClass = (*env)->FindClass (env, "gnu/xml/libxmlj/util/XMLJ");
  537. if (!xmljClass)
  538. {
  539. return NULL;
  540. }
  541. getInputStream =
  542. (*env)->GetStaticMethodID (env, xmljClass, "xmljGetInputStream",
  543. "(Ljava/lang/String;Ljava/lang/String;)Lgnu/xml/libxmlj/util/NamedInputStream;");
  544. if (!getInputStream)
  545. {
  546. return NULL;
  547. }
  548. systemId = xmljNewString (env, uri);
  549. inputStream = (*env)->CallStaticObjectMethod (env, xmljClass, getInputStream,
  550. stylesheetURL, systemId);
  551. if (!inputStream)
  552. {
  553. return NULL;
  554. }
  555. inputStreamClass = (*env)->GetObjectClass (env, inputStream);
  556. if (!inputStreamClass)
  557. {
  558. return NULL;
  559. }
  560. getDetectBuffer = (*env)->GetMethodID (env, inputStreamClass,
  561. "getDetectBuffer", "()[B");
  562. if (!getDetectBuffer)
  563. {
  564. return NULL;
  565. }
  566. detectBuffer = (*env)->CallObjectMethod (env, inputStream, getDetectBuffer);
  567. if (!detectBuffer)
  568. {
  569. return NULL;
  570. }
  571. return xmljParseDocument (env, NULL, inputStream, detectBuffer,
  572. NULL, systemId, stylesheetURL,
  573. 0, 0, 0, 0, 0, 0, 0, 0, 0, 2);
  574. }
  575. /* GnomeTransformer.newStylesheet */
  576. JNIEXPORT jobject JNICALL
  577. Java_gnu_xml_libxmlj_transform_GnomeTransformer_newStylesheet (JNIEnv *env,
  578. jobject self)
  579. {
  580. xsltStylesheetPtr stylesheet;
  581. jobject ret;
  582. stylesheetURL = NULL;
  583. xsltSetLoaderFunc (xmljDocLoader);
  584. stylesheet = xsltNewStylesheet ();
  585. xmljSetOutputProperties (env, self, stylesheet);
  586. ret = xmljAsField (env, stylesheet);
  587. if (ret == NULL)
  588. {
  589. xmljThrowException (env,
  590. "javax/xml/transform/TransformerConfigurationException",
  591. "Can't create Java object for stylesheet");
  592. }
  593. return ret;
  594. }
  595. /* GnomeTransformer.newStylesheetFromStream */
  596. JNIEXPORT jobject JNICALL
  597. Java_gnu_xml_libxmlj_transform_GnomeTransformer_newStylesheetFromStream
  598. (JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
  599. jstring publicId, jstring systemId, jstring base,
  600. jboolean entityResolver, jboolean errorHandler)
  601. {
  602. xmlDocPtr doc;
  603. xsltStylesheetPtr stylesheet;
  604. jobject ret;
  605. doc = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
  606. base, 0, 0, 0, 0, 0,
  607. entityResolver, errorHandler, 0, 0, 2);
  608. if (doc == NULL)
  609. {
  610. return NULL;
  611. }
  612. stylesheetURL = systemId;
  613. xsltSetLoaderFunc (xmljDocLoader);
  614. stylesheet = xsltParseStylesheetDoc (doc);
  615. if (stylesheet == NULL)
  616. {
  617. xmljThrowException (env,
  618. "javax/xml/transform/TransformerConfigurationException",
  619. "Error parsing XSLT stylesheet");
  620. return NULL;
  621. }
  622. xmljSetOutputProperties (env, self, stylesheet);
  623. ret = xmljAsField (env, stylesheet);
  624. if (ret == NULL)
  625. {
  626. xmljThrowException (env,
  627. "javax/xml/transform/TransformerConfigurationException",
  628. "Can't create Java object for stylesheet");
  629. }
  630. return ret;
  631. }
  632. /* GnomeTransformer.newStylesheetFromDoc */
  633. JNIEXPORT jobject JNICALL
  634. Java_gnu_xml_libxmlj_transform_GnomeTransformer_newStylesheetFromDoc
  635. (JNIEnv *env, jobject self, jobject in)
  636. {
  637. xmlDocPtr doc;
  638. xsltStylesheetPtr stylesheet;
  639. jobject ret;
  640. doc = (xmlDocPtr) xmljGetNodeID (env, in);
  641. if (doc == NULL)
  642. {
  643. return NULL;
  644. }
  645. stylesheetURL = xmljNewString (env, doc->URL);
  646. xsltSetLoaderFunc (xmljDocLoader);
  647. stylesheet = xsltParseStylesheetDoc (doc);
  648. if (stylesheet == NULL)
  649. {
  650. xmljThrowException (env,
  651. "javax/xml/transform/TransformerConfigurationException",
  652. "Error parsing XSLT stylesheet");
  653. }
  654. xmljSetOutputProperties (env, self, stylesheet);
  655. ret = xmljAsField (env, stylesheet);
  656. if (ret == NULL)
  657. {
  658. xmljThrowException (env,
  659. "javax/xml/transform/TransformerConfigurationException",
  660. "Can't create Java object for stylesheet");
  661. }
  662. return ret;
  663. }
  664. /* GnomeTransformer.transformStreamToStream */
  665. JNIEXPORT void JNICALL
  666. Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformStreamToStream
  667. (JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
  668. jstring publicId, jstring systemId, jstring base,
  669. jboolean entityResolver, jboolean errorHandler, jobject out)
  670. {
  671. xmlDocPtr source;
  672. xmlDocPtr result;
  673. source = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
  674. base, 0, 0, 0, 0, 0,
  675. entityResolver, errorHandler, 0, 0, 2);
  676. result = xmljTransform (env, self, source);
  677. xmljSaveFileToJavaOutputStream (env, out, result,
  678. (const char*) result->encoding);
  679. xmlFreeDoc (result);
  680. }
  681. /* GnomeTransformer.transformStreamToDoc */
  682. JNIEXPORT jobject JNICALL
  683. Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformStreamToDoc
  684. (JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
  685. jstring publicId, jstring systemId, jstring base,
  686. jboolean entityResolver, jboolean errorHandler)
  687. {
  688. xmlDocPtr source;
  689. xmlDocPtr result;
  690. source = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
  691. base, 0, 0, 0, 0, 0,
  692. entityResolver, errorHandler, 0, 0, 2);
  693. result = xmljTransform (env, self, source);
  694. return xmljGetNodeInstance (env, (xmlNodePtr) result);
  695. }
  696. /* GnomeTransformer.transformStreamToSAX */
  697. JNIEXPORT void JNICALL
  698. Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformStreamToSAX
  699. (JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
  700. jstring publicId, jstring systemId, jstring base,
  701. jboolean entityResolver, jboolean errorHandler, jobject callback)
  702. {
  703. xmlDocPtr source;
  704. source = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
  705. base, 0, 0, 0, 0, 0,
  706. entityResolver, errorHandler, 0, 0, 2);
  707. xmljTransformToSAX (env, self, source, callback);
  708. }
  709. /* GnomeTransformer.transformDocToStream */
  710. JNIEXPORT void JNICALL
  711. Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformDocToStream
  712. (JNIEnv *env, jobject self, jobject doc, jobject out)
  713. {
  714. xmlDocPtr source;
  715. xmlDocPtr result;
  716. source = (xmlDocPtr) xmljGetNodeID (env, doc);
  717. result = xmljTransform (env, self, source);
  718. xmljSaveFileToJavaOutputStream (env, out, result,
  719. (const char*) result->encoding);
  720. xmlFreeDoc (result);
  721. }
  722. /* GnomeTransformer.transformDocToDoc */
  723. JNIEXPORT jobject JNICALL
  724. Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformDocToDoc
  725. (JNIEnv *env, jobject self, jobject doc)
  726. {
  727. xmlDocPtr source;
  728. xmlDocPtr result;
  729. source = (xmlDocPtr) xmljGetNodeID (env, doc);
  730. result = xmljTransform (env, self, source);
  731. return xmljGetNodeInstance (env, (xmlNodePtr) result);
  732. }
  733. /* GnomeTransformer.transformDocToSAX */
  734. JNIEXPORT void JNICALL
  735. Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformDocToSAX
  736. (JNIEnv *env, jobject self, jobject doc, jobject callback)
  737. {
  738. xmlDocPtr source;
  739. source = (xmlDocPtr) xmljGetNodeID (env, doc);
  740. xmljTransformToSAX (env, self, source, callback);
  741. }
  742. /* GnomeTransformer.free */
  743. JNIEXPORT void JNICALL
  744. Java_gnu_xml_libxmlj_transform_GnomeTransformer_free (JNIEnv *env,
  745. jobject self)
  746. {
  747. xsltStylesheetPtr stylesheet;
  748. stylesheet = xmljGetStylesheetID (env, self);
  749. xsltFreeStylesheet (stylesheet);
  750. }
  751. /*
  752. * --------------------------------------------------------------------------
  753. * Native implementation for class
  754. * gnu.xml.libxmlj.transform.GnomeTransformerFactory follows.
  755. */
  756. /* GnomeTransformerFactory.freeLibxsltGlobal */
  757. JNIEXPORT void JNICALL
  758. Java_gnu_xml_libxmlj_transform_GnomeTransformerFactory_freeLibxsltGlobal (
  759. JNIEnv *env __attribute__((__unused__)),
  760. jclass clazz __attribute__((__unused__)))
  761. {
  762. xsltCleanupGlobals ();
  763. xmlCleanupParser ();
  764. }