aboutsummaryrefslogtreecommitdiffstats
path: root/src/documentation/content/xdocs/embedding.xml
blob: 47a94129a48453c962de4e21d0f0422d91350e87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<?xml version="1.0" standalone="no"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "document-v11.dtd">


<!-- Embedding FOP -->
<document>
    <header>
        <title>Embedding FOP</title>
        <subtitle>Notes about embedding FOP in your Java application</subtitle>
    </header>

    <body>
<section>
  <title>Embedding FOP</title>
  <section>
    <title>Overview</title>
  <p>Instantiate org.apache.fop.apps.Driver. Once this class is
     instantiated, methods are called to set the
     Renderer to use
     and the OutputStream to use to output the results of the
     rendering (where applicable). In the case of the Renderer and
     ElementMapping(s), the Driver may be supplied either with the
     object itself, or the name of the class, in which case Driver will
     instantiate the class itself. The advantage of the latter is it
     enables runtime determination of Renderer and ElementMapping(s).
  </p>
  </section>
  <section>
    <title>Examples</title>
  <p>The simplest way to use Driver is to instantiate it with the
     InputSource and OutputStream, then set the renderer desired and
     call the run method.
  </p>
  <p>Here is an example use of Driver which outputs PDF:
  </p>
    <source><![CDATA[
   Driver driver = new Driver(new InputSource (args[0]),
                              new FileOutputStream(args[1]));
   driver.setRenderer(Driver.RENDER_PDF);
   driver.run();]]></source>

  <p>You also need to set up logging. Global logging for all FOP
    processes is managed by MessageHandler. Per-instance logging
    is handled by Driver. You want to set both using an implementation
    of org.apache.avalon.framework.logger.Logger. See
    <link href="http://jakarta.apache.org/avalon/framework/">Jakarta
    Avalon Framework</link> for more information.
  </p>
    <source><![CDATA[
    Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
    MessageHandler.setScreenLogger(logger);
    driver.setLogger(logger);]]></source>

  <p>To setup the user config file you can do the following
  </p>
    <source><![CDATA[
   userConfigFile = new File(userConfig);
   options = new Options(userConfigFile);]]></source>
    <note>
        This is all you need to do, it sets up a static configuration class.
    </note>

  <p>Once the Driver is set up, the render method
     is called. Depending on whether DOM or SAX is being used, the
     invocation of the method is either render(Document) or
     render(Parser, InputSource) respectively.
  </p>
  <p>
     <strong>Another possibility may be used to build the FO Tree. You can
     call getContentHandler() and fire the SAX events yourself.
     </strong>
  </p>
  <p>Once the FO Tree is built, the format() and render() methods may be
     called in that order.
  </p>
  <p>Here is an example use of Driver:</p>
  <source><![CDATA[
  Driver driver = new Driver();
  driver.setRenderer(Driver.RENDER_PDF);
  driver.setInputSource(new FileInputSource(args[0]));
  driver.setOutputStream(new FileOutputStream(args[1]));
  driver.run();]]></source>
  <p>You can also specify an xml and xsl file for the input.
  </p>
  <p>Here is an example use of Driver with the XSLTInputHandler:</p>
  <source><![CDATA[
  Driver driver = new Driver();
  driver.setRenderer(Driver.RENDER_PDF);
  InputHandler inputHandler = new XSLTInputHandler(xmlFile, xslFile);
  XMLReader parser = inputHandler.getParser();
  driver.setOutputStream(new FileOutputStream(outFile));
  driver.render(parser, inputHandler.getInputSource());]]></source>
  <p>Have a look at the classes CommandLineStarter or FopServlet for complete examples.</p>

<note>If your FO files contain SVG then batik will be used. When batik is
initialised it uses certain classes in <code>java.awt</code> that
intialises the java AWT classes. This means that a daemon thread
is created by the jvm and on unix it will need to connect to a
DISPLAY.
The thread means that the java application will not automatically quit
when finished, you will need to call <code>System.exit</code>. These
issues should be fixed in the upcoming JDK1.4</note>

  </section>
  <section>
    <title>Controlling logging</title>
    <p>FOP uses Jakarta Avalon's
      <link href="http://jakarta.apache.org/avalon/api/org/apache/avalon/framework/logger/Logger.html">Logger</link>
       interface to do logging. See the <link href="http://jakarta.apache.org/avalon/">Jakarta Avalon project</link> for more information.</p>
    <p>Per default FOP uses the ConsoleLogger which logs to System.out. If you want to do logging using a
    logging framework (such as LogKit, Log4J or JDK 1.4 Logging) you can set a
    different Logger implementation on the Driver object. Here's an example how you would use LogKit:</p>
    <source><![CDATA[
    Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
    PatternFormatter formatter = new PatternFormatter(
       "[%{priority}]: %{message}\n%{throwable}" );

    LogTarget target = null;
    target = new StreamTarget(System.out, formatter);

    hierarchy.setDefaultLogTarget(target);
    log = hierarchy.getLoggerFor("fop");
    log.setPriority(Priority.INFO);

    driver.setLogger(new org.apache.avalon.framework.logger.LogKitLogger(log));]]></source>
  <p>The LogKitLogger class implements the Logger interface so all logging calls are being redirected to LogKit.
  More information on Jakarta LogKit can be found <link href="http://jakarta.apache.org/avalon/logkit/index.html">here</link>.</p>
  <p>Similar implementations exist for Log4J (org.apache.avalon.framework.logger.Log4JLogger) and
  JDK 1.4 logging (org.apache.avalon.framework.logger.Jdk14Logger).</p>
  <p>If you want FOP to be totally silent you can also set an org.apache.avalon.framework.logger.NullLogger instance.</p>
  <p>If you want to use yet another logging facility you simply have to create a class that implements org.apache.avalon.framework.logging.Logger
  and set it on the Driver object. See the existing implementations in Avalon Framework for examples.</p>

  </section>
  <section>
    <title>Hints</title>
    <section>
     <title>XML/XSL/DOM Inputs</title>
     <p>
You may want to supply you input to FOP from different data sources.
For example you may have a DOM and XSL stylesheet or you may want to
set variables in the stylesheet. The page here:
<link href="http://xml.apache.org/xalan-j/usagepatterns.html">
http://xml.apache.org/xalan-j/usagepatterns.html</link> describes
how you can do these things.
     </p>
     <p>
You can use the content handler from the driver to create a SAXResult.
The transformer then can fire SAX events on the content handler which
will in turn create the rendered output.
     </p>
    </section>
    <section>
      <title>Object reuse</title>
     <p>
If FOP is going to be used multiple times within your application
it may be useful to reuse certain objects to save time.
     </p>
     <p>
The renderers and the driver can both be reused. A renderer is reusable
once the previous render has been completed. The driver is reuseable
after the rendering is complete and the reset method is called.
You will need to setup the driver again with a new OutputStream,
IntputStream and renderer.
     </p>
    </section>
    <section>
      <title>Getting information on the rendering process</title>
      <p>
      To get the number of pages that were rendered by FOP you can call Driver.getResults(). This returns a
      FormattingResults object where you can lookup the number of pages produced. It also gives you the
      page-sequences that were produced along with their id attribute and their number of pages. This is particularly useful if you
      render multiple documents (each enclosed by a page-sequence) and have to know the number of pages
      of each document.
      </p>
    </section>
  </section>
  <section>
    <title>Using Fop in a servlet</title>
     <p>
In the directory xml-fop/docs/examples/embedding you can find a working
example how to use Fop in a servlet. You can drop the fop.war into the
webapps directory of Tomcat, then go to a URL like this:
     </p>
     <p>http://localhost:8080/fop/fop?fo=/home/path/to/fofile.fo</p>
     <p>http://localhost:8080/fop/fop?xml=/home/path/to/xmlfile.xml&amp;xsl=/home/path/to/xslfile.xsl</p>
     <p>You can also find the source code there in the file FopServlet.java</p>
     <p>
        To compile this code you will need servlet_2_2.jar (or compatible), fop.jar and the sax api in your classpath.
     </p>
     <note>
         Some browsers have problems handling the PDF result sent back to
         the browser. IE is particularly bad and different versions behave
         differently. Having a ".pdf" on the end of the url may help.
     </note>
  </section>
</section>
    </body>
</document>