You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

XSLTProcess.java 25 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if
  20. * any, must include the following acknowlegement:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowlegement may appear in the software itself,
  24. * if and wherever such third-party acknowlegements normally appear.
  25. *
  26. * 4. The names "The Jakarta Project", "Ant", and "Apache Software
  27. * Foundation" must not be used to endorse or promote products derived
  28. * from this software without prior written permission. For written
  29. * permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache"
  32. * nor may "Apache" appear in their names without prior written
  33. * permission of the Apache Group.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation. For more
  51. * information on the Apache Software Foundation, please see
  52. * <http://www.apache.org/>.
  53. */
  54. package org.apache.tools.ant.taskdefs;
  55. import java.lang.reflect.Method;
  56. import java.io.File;
  57. import java.util.Enumeration;
  58. import java.util.Vector;
  59. import org.apache.tools.ant.BuildException;
  60. import org.apache.tools.ant.DirectoryScanner;
  61. import org.apache.tools.ant.Project;
  62. import org.apache.tools.ant.AntClassLoader;
  63. import org.apache.tools.ant.taskdefs.optional.TraXLiaison;
  64. import org.apache.tools.ant.types.Path;
  65. import org.apache.tools.ant.types.Reference;
  66. import org.apache.tools.ant.util.FileUtils;
  67. import org.apache.tools.ant.types.XMLCatalog;
  68. import org.xml.sax.EntityResolver;
  69. /**
  70. * Processes a set of XML documents via XSLT. This is
  71. * useful for building views of XML based documentation.
  72. *
  73. * @version $Revision$
  74. *
  75. * @author <a href="mailto:kvisco@exoffice.com">Keith Visco</a>
  76. * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a>
  77. * @author <a href="mailto:russgold@acm.org">Russell Gold</a>
  78. * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
  79. *
  80. * @since Ant 1.1
  81. *
  82. * @ant.task name="xslt" category="xml"
  83. */
  84. public class XSLTProcess extends MatchingTask implements XSLTLogger {
  85. /** destination directory */
  86. private File destDir = null;
  87. /** where to find the source XML file, default is the project's basedir */
  88. private File baseDir = null;
  89. /** XSL stylesheet */
  90. private String xslFile = null;
  91. /** extension of the files produced by XSL processing */
  92. private String targetExtension = ".html";
  93. /** additional parameters to be passed to the stylesheets */
  94. private Vector params = new Vector();
  95. /** Input XML document to be used */
  96. private File inFile = null;
  97. /** Output file */
  98. private File outFile = null;
  99. /** The name of the XSL processor to use */
  100. private String processor;
  101. /** Classpath to use when trying to load the XSL processor */
  102. private Path classpath = null;
  103. /** The Liason implementation to use to communicate with the XSL
  104. * processor */
  105. private XSLTLiaison liaison;
  106. /** Flag which indicates if the stylesheet has been loaded into
  107. * the processor */
  108. private boolean stylesheetLoaded = false;
  109. /** force output of target files even if they already exist */
  110. private boolean force = false;
  111. /** Utilities used for file operations */
  112. private FileUtils fileUtils;
  113. /** XSL output method to be used */
  114. private Vector outputProperties = new Vector();
  115. /** for resolving entities such as dtds */
  116. private XMLCatalog xmlCatalog = new XMLCatalog();
  117. /** Name of the TRAX Liason class */
  118. private static final String TRAX_LIAISON_CLASS =
  119. "org.apache.tools.ant.taskdefs.optional.TraXLiaison";
  120. /** Name of the now-deprecated XSLP Liason class */
  121. private static final String XSLP_LIAISON_CLASS =
  122. "org.apache.tools.ant.taskdefs.optional.XslpLiaison";
  123. /** Name of the Xalan liason class */
  124. private static final String XALAN_LIAISON_CLASS =
  125. "org.apache.tools.ant.taskdefs.optional.XalanLiaison";
  126. /**
  127. * Whether to style all files in the included directories as well.
  128. *
  129. * @since Ant 1.5
  130. */
  131. private boolean performDirectoryScan = true;
  132. /**
  133. * Creates a new XSLTProcess Task.
  134. */
  135. public XSLTProcess() {
  136. fileUtils = FileUtils.newFileUtils();
  137. } //-- XSLTProcess
  138. /**
  139. * Whether to style all files in the included directories as well;
  140. * optional, default is true.
  141. *
  142. * @param b true if files in included directories are processed.
  143. * @since Ant 1.5
  144. */
  145. public void setScanIncludedDirectories(boolean b) {
  146. performDirectoryScan = b;
  147. }
  148. /**
  149. * Executes the task.
  150. *
  151. * @exception BuildException if there is an execution problem.
  152. * @todo validate that if either in or our is defined, then both are
  153. */
  154. public void execute() throws BuildException {
  155. File savedBaseDir = baseDir;
  156. DirectoryScanner scanner;
  157. String[] list;
  158. String[] dirs;
  159. if (xslFile == null) {
  160. throw new BuildException("no stylesheet specified", location);
  161. }
  162. try {
  163. if (baseDir == null) {
  164. baseDir = project.resolveFile(".");
  165. }
  166. liaison = getLiaison();
  167. // check if liaison wants to log errors using us as logger
  168. if (liaison instanceof XSLTLoggerAware) {
  169. ((XSLTLoggerAware) liaison).setLogger(this);
  170. }
  171. log("Using " + liaison.getClass().toString(), Project.MSG_VERBOSE);
  172. File stylesheet = project.resolveFile(xslFile);
  173. if (!stylesheet.exists()) {
  174. stylesheet = fileUtils.resolveFile(baseDir, xslFile);
  175. /*
  176. * shouldn't throw out deprecation warnings before we know,
  177. * the wrong version has been used.
  178. */
  179. if (stylesheet.exists()) {
  180. log("DEPRECATED - the style attribute should be relative "
  181. + "to the project\'s");
  182. log(" basedir, not the tasks\'s basedir.");
  183. }
  184. }
  185. // if we have an in file and out then process them
  186. if (inFile != null && outFile != null) {
  187. process(inFile, outFile, stylesheet);
  188. return;
  189. }
  190. /*
  191. * if we get here, in and out have not been specified, we are
  192. * in batch processing mode.
  193. */
  194. //-- make sure Source directory exists...
  195. if (destDir == null) {
  196. String msg = "destdir attributes must be set!";
  197. throw new BuildException(msg);
  198. }
  199. scanner = getDirectoryScanner(baseDir);
  200. log("Transforming into " + destDir, Project.MSG_INFO);
  201. // Process all the files marked for styling
  202. list = scanner.getIncludedFiles();
  203. for (int i = 0; i < list.length; ++i) {
  204. process(baseDir, list[i], destDir, stylesheet);
  205. }
  206. if (performDirectoryScan) {
  207. // Process all the directories marked for styling
  208. dirs = scanner.getIncludedDirectories();
  209. for (int j = 0; j < dirs.length; ++j){
  210. list = new File(baseDir, dirs[j]).list();
  211. for (int i = 0; i < list.length; ++i) {
  212. process(baseDir, list[i], destDir, stylesheet);
  213. }
  214. }
  215. }
  216. } finally {
  217. liaison = null;
  218. stylesheetLoaded = false;
  219. baseDir = savedBaseDir;
  220. }
  221. }
  222. /**
  223. * Set whether to check dependencies, or always generate;
  224. * optional, default is false.
  225. *
  226. * @param force true if always generate.
  227. */
  228. public void setForce(boolean force) {
  229. this.force = force;
  230. }
  231. /**
  232. * Set the base directory;
  233. * optional, default is the project's basedir.
  234. *
  235. * @param dir the base directory
  236. **/
  237. public void setBasedir(File dir) {
  238. baseDir = dir;
  239. }
  240. /**
  241. * Set the destination directory into which the XSL result
  242. * files should be copied to;
  243. * required, unless <tt>in</tt> and <tt>out</tt> are
  244. * specified.
  245. * @param dir the name of the destination directory
  246. **/
  247. public void setDestdir(File dir) {
  248. destDir = dir;
  249. }
  250. /**
  251. * Set the desired file extension to be used for the target;
  252. * optional, default is html.
  253. * @param name the extension to use
  254. **/
  255. public void setExtension(String name) {
  256. targetExtension = name;
  257. }
  258. /**
  259. * Name of the stylesheet to use - given either relative
  260. * to the project's basedir or as an absolute path; required.
  261. */
  262. public void setStyle(String xslFile) {
  263. this.xslFile = xslFile;
  264. }
  265. /**
  266. * Set the optional classpath to the XSL processor
  267. *
  268. * @param classpath the classpath to use when loading the XSL processor
  269. */
  270. public void setClasspath(Path classpath) {
  271. createClasspath().append(classpath);
  272. }
  273. /**
  274. * Set the optional classpath to the XSL processor
  275. *
  276. * @return a path instance to be configured by the Ant core.
  277. */
  278. public Path createClasspath() {
  279. if (classpath == null) {
  280. classpath = new Path(project);
  281. }
  282. return classpath.createPath();
  283. }
  284. /**
  285. * Set the reference to an optional classpath to the XSL processor
  286. *
  287. * @param r the id of the Ant path instance to act as the classpath
  288. * for loading the XSL processor
  289. */
  290. public void setClasspathRef(Reference r) {
  291. createClasspath().setRefid(r);
  292. }
  293. /**
  294. * Set the name of the XSL processor to use; optional, default trax.
  295. * Other values are "xalan" for Xalan1 and "xslp" for XSL:P, though the
  296. * later is strongly deprecated.
  297. *
  298. * @param processor the name of the XSL processor
  299. */
  300. public void setProcessor(String processor) {
  301. this.processor = processor;
  302. }
  303. /**
  304. * Add the catalog to our internal catalog
  305. *
  306. * @param xmlCatalog the XMLCatalog instance to use to look up DTDs
  307. */
  308. public void addConfiguredXMLCatalog(XMLCatalog xmlCatalog) {
  309. this.xmlCatalog.addConfiguredXMLCatalog(xmlCatalog);
  310. }
  311. /**
  312. * Load processor here instead of in setProcessor - this will be
  313. * called from within execute, so we have access to the latest
  314. * classpath.
  315. *
  316. * @param proc the name of the processor to load.
  317. * @exception Exception if the processor cannot be loaded.
  318. */
  319. private void resolveProcessor(String proc) throws Exception {
  320. if (proc.equals("trax")) {
  321. final Class clazz = loadClass(TRAX_LIAISON_CLASS);
  322. liaison = (XSLTLiaison) clazz.newInstance();
  323. } else if (proc.equals("xslp")) {
  324. log("DEPRECATED - xslp processor is deprecated. Use trax or "
  325. + "xalan instead.");
  326. final Class clazz = loadClass(XSLP_LIAISON_CLASS);
  327. liaison = (XSLTLiaison) clazz.newInstance();
  328. } else if (proc.equals("xalan")) {
  329. final Class clazz = loadClass(XALAN_LIAISON_CLASS);
  330. liaison = (XSLTLiaison) clazz.newInstance();
  331. } else {
  332. liaison = (XSLTLiaison) loadClass(proc).newInstance();
  333. }
  334. }
  335. /**
  336. * Load named class either via the system classloader or a given
  337. * custom classloader.
  338. *
  339. * @param classname the name of the class to load.
  340. * @return the requested class.
  341. * @exception Exception if the class could not be loaded.
  342. */
  343. private Class loadClass(String classname) throws Exception {
  344. if (classpath == null) {
  345. return Class.forName(classname);
  346. } else {
  347. AntClassLoader al = new AntClassLoader(project, classpath);
  348. Class c = al.loadClass(classname);
  349. AntClassLoader.initializeClass(c);
  350. return c;
  351. }
  352. }
  353. /**
  354. * Specifies the output name for the styled result from the
  355. * <tt>in</tt> attribute; required if <tt>in</tt> is set
  356. *
  357. * @param outFile the output File instance.
  358. */
  359. public void setOut(File outFile){
  360. this.outFile = outFile;
  361. }
  362. /**
  363. * specifies a single XML document to be styled. Should be used
  364. * with the <tt>out</tt> attribute; ; required if <tt>out</tt> is set
  365. *
  366. * @param inFile the input file
  367. */
  368. public void setIn(File inFile){
  369. this.inFile = inFile;
  370. }
  371. /**
  372. * Processes the given input XML file and stores the result
  373. * in the given resultFile.
  374. *
  375. * @param baseDir the base directory for resolving files.
  376. * @param xmlFile the input file
  377. * @param destDir the destination directory
  378. * @param stylesheet the stylesheet to use.
  379. * @exception BuildException if the processing fails.
  380. */
  381. private void process(File baseDir, String xmlFile, File destDir,
  382. File stylesheet)
  383. throws BuildException {
  384. String fileExt = targetExtension;
  385. File outFile = null;
  386. File inFile = null;
  387. try {
  388. long styleSheetLastModified = stylesheet.lastModified();
  389. inFile = new File(baseDir, xmlFile);
  390. if (inFile.isDirectory()) {
  391. log("Skipping " + inFile + " it is a directory.",
  392. Project.MSG_VERBOSE);
  393. return;
  394. }
  395. int dotPos = xmlFile.lastIndexOf('.');
  396. if (dotPos > 0) {
  397. outFile = new File(destDir,
  398. xmlFile.substring(0, xmlFile.lastIndexOf('.')) + fileExt);
  399. } else {
  400. outFile = new File(destDir, xmlFile + fileExt);
  401. }
  402. if (force ||
  403. inFile.lastModified() > outFile.lastModified() ||
  404. styleSheetLastModified > outFile.lastModified()) {
  405. ensureDirectoryFor(outFile);
  406. log("Processing " + inFile + " to " + outFile);
  407. configureLiaison(stylesheet);
  408. liaison.transform(inFile, outFile);
  409. }
  410. } catch (Exception ex) {
  411. // If failed to process document, must delete target document,
  412. // or it will not attempt to process it the second time
  413. log("Failed to process " + inFile, Project.MSG_INFO);
  414. if (outFile != null) {
  415. outFile.delete();
  416. }
  417. throw new BuildException(ex);
  418. }
  419. } //-- processXML
  420. /**
  421. * Process the input file to the output file with the given stylesheet.
  422. *
  423. * @param inFile the input file to process.
  424. * @param outFile the detination file.
  425. * @param stylesheet the stylesheet to use.
  426. * @exception BuildException if the processing fails.
  427. */
  428. private void process(File inFile, File outFile, File stylesheet)
  429. throws BuildException {
  430. try {
  431. long styleSheetLastModified = stylesheet.lastModified();
  432. log("In file " + inFile + " time: " + inFile.lastModified(),
  433. Project.MSG_DEBUG);
  434. log("Out file " + outFile + " time: " + outFile.lastModified(),
  435. Project.MSG_DEBUG);
  436. log("Style file " + xslFile + " time: " + styleSheetLastModified,
  437. Project.MSG_DEBUG);
  438. if (force ||
  439. inFile.lastModified() > outFile.lastModified() ||
  440. styleSheetLastModified > outFile.lastModified()) {
  441. ensureDirectoryFor(outFile);
  442. log("Processing " + inFile + " to " + outFile,
  443. Project.MSG_INFO);
  444. configureLiaison(stylesheet);
  445. liaison.transform(inFile, outFile);
  446. }
  447. } catch (Exception ex) {
  448. log("Failed to process " + inFile, Project.MSG_INFO);
  449. if (outFile != null) {
  450. outFile.delete();
  451. }
  452. throw new BuildException(ex);
  453. }
  454. }
  455. /**
  456. * Ensure the directory exists for a given file
  457. *
  458. * @param targetFile the file for which the directories are required.
  459. * @exception BuildException if the directories cannot be created.
  460. */
  461. private void ensureDirectoryFor(File targetFile)
  462. throws BuildException {
  463. File directory = fileUtils.getParentFile(targetFile);
  464. if (!directory.exists()) {
  465. if (!directory.mkdirs()) {
  466. throw new BuildException("Unable to create directory: "
  467. + directory.getAbsolutePath());
  468. }
  469. }
  470. }
  471. /**
  472. * Get the Liason implementation to use in processing.
  473. *
  474. * @return an instance of the XSLTLiason interface.
  475. */
  476. protected XSLTLiaison getLiaison() {
  477. // if processor wasn't specified, see if TraX is available. If not,
  478. // default it to xslp or xalan, depending on which is in the classpath
  479. if (liaison == null) {
  480. if (processor != null) {
  481. try {
  482. resolveProcessor(processor);
  483. } catch (Exception e) {
  484. throw new BuildException(e);
  485. }
  486. } else {
  487. try {
  488. resolveProcessor("trax");
  489. } catch (Throwable e1) {
  490. try {
  491. resolveProcessor("xalan");
  492. } catch (Throwable e2) {
  493. try {
  494. resolveProcessor("xslp");
  495. } catch (Throwable e3) {
  496. e3.printStackTrace();
  497. e2.printStackTrace();
  498. throw new BuildException(e1);
  499. }
  500. }
  501. }
  502. }
  503. }
  504. return liaison;
  505. }
  506. /**
  507. * Create an instance of an XSL parameter for configuration by Ant.
  508. *
  509. * @return an instance of the Param class to be configured.
  510. */
  511. public Param createParam() {
  512. Param p = new Param();
  513. params.addElement(p);
  514. return p;
  515. }
  516. /**
  517. * The Param inner class used to store XSL parameters
  518. */
  519. public class Param {
  520. /** The parameter name */
  521. private String name = null;
  522. /** The parameter's XSL expression */
  523. private String expression = null;
  524. /**
  525. * Set the parameter name.
  526. *
  527. * @param name the name of the parameter.
  528. */
  529. public void setName(String name){
  530. this.name = name;
  531. }
  532. /**
  533. * The XSL expression for the parameter value
  534. *
  535. * @param expression the XSL expression representing the
  536. * parameter's value.
  537. */
  538. public void setExpression(String expression){
  539. this.expression = expression;
  540. }
  541. /**
  542. * Get the parameter name
  543. *
  544. * @return the parameter name
  545. * @exception BuildException if the name is not set.
  546. */
  547. public String getName() throws BuildException{
  548. if (name == null) {
  549. throw new BuildException("Name attribute is missing.");
  550. }
  551. return name;
  552. }
  553. /**
  554. * Get the parameter expression
  555. *
  556. * @return the parameter expression
  557. * @exception BuildException if the expression is not set.
  558. */
  559. public String getExpression() throws BuildException{
  560. if (expression == null) {
  561. throw new BuildException("Expression attribute is missing.");
  562. }
  563. return expression;
  564. }
  565. } // Param
  566. /**
  567. * Create an instance of an output property to be configured.
  568. * @return the newly created output property.
  569. * @since Ant 1.5
  570. */
  571. public OutputProperty createOutputProperty() {
  572. OutputProperty p = new OutputProperty();
  573. outputProperties.addElement(p);
  574. return p;
  575. }
  576. /**
  577. * Specify how the result tree should be output as specified
  578. * in the <a href="http://www.w3.org/TR/xslt#output">
  579. * specification</a>.
  580. * @since Ant 1.5
  581. */
  582. public static class OutputProperty {
  583. /** output property name */
  584. private String name;
  585. /** output property value */
  586. private String value;
  587. /**
  588. * @return the output property name.
  589. */
  590. public String getName() {
  591. return name;
  592. }
  593. /**
  594. * set the name for this property
  595. * @param name A non-null String that specifies an
  596. * output property name, which may be namespace qualified.
  597. */
  598. public void setName(String name) {
  599. this.name = name;
  600. }
  601. /**
  602. * @return the output property value.
  603. */
  604. public String getValue() {
  605. return value;
  606. }
  607. /**
  608. * set the value for this property
  609. * @param value The non-null string value of the output property.
  610. */
  611. public void setValue(String value) {
  612. this.value = value;
  613. }
  614. }
  615. /**
  616. * Initialize internal instance of XMLCatalog
  617. */
  618. public void init() throws BuildException {
  619. super.init();
  620. xmlCatalog.setProject(project);
  621. }
  622. /**
  623. * Loads the stylesheet and set xsl:param parameters.
  624. *
  625. * @param stylesheet the file form which to load the stylesheet.
  626. * @exception BuildException if the stylesheet cannot be loaded.
  627. */
  628. protected void configureLiaison(File stylesheet) throws BuildException {
  629. if (stylesheetLoaded) {
  630. return;
  631. }
  632. stylesheetLoaded = true;
  633. try {
  634. log("Loading stylesheet " + stylesheet, Project.MSG_INFO);
  635. liaison.setStylesheet(stylesheet);
  636. for (Enumeration e = params.elements(); e.hasMoreElements();) {
  637. Param p = (Param) e.nextElement();
  638. liaison.addParam(p.getName(), p.getExpression());
  639. }
  640. if (liaison instanceof TraXLiaison) {
  641. configureTraXLiaison((TraXLiaison)liaison);
  642. }
  643. } catch (Exception ex) {
  644. log("Failed to transform using stylesheet " + stylesheet, Project.MSG_INFO);
  645. throw new BuildException(ex);
  646. }
  647. }
  648. /**
  649. * Specific configuration for the TRaX liaison... support for
  650. * all other has been dropped so this liaison will soon look
  651. * like the exact copy of JAXP interface..
  652. * @param liaison the TRaXLiaison to configure.
  653. */
  654. protected void configureTraXLiaison(TraXLiaison liaison){
  655. // use XMLCatalog as the entity resolver and URI resolver
  656. if (xmlCatalog != null) {
  657. liaison.setEntityResolver(xmlCatalog);
  658. liaison.setURIResolver(xmlCatalog);
  659. }
  660. // configure output properties
  661. for (Enumeration props = outputProperties.elements();
  662. props.hasMoreElements();) {
  663. OutputProperty prop = (OutputProperty)props.nextElement();
  664. liaison.setOutputProperty(prop.getName(), prop.getValue());
  665. }
  666. }
  667. } //-- XSLTProcess