View Javadoc

1   package org.apache.maven.doxia.module.fo;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.StringReader;
24  import java.io.Writer;
25  
26  import org.apache.maven.doxia.document.DocumentMeta;
27  import org.apache.maven.doxia.document.DocumentModel;
28  import org.apache.maven.doxia.document.DocumentTOC;
29  import org.apache.maven.doxia.document.DocumentTOCItem;
30  
31  import org.apache.maven.doxia.parser.XhtmlBaseParser;
32  import org.apache.maven.doxia.sink.Sink;
33  import org.apache.maven.doxia.sink.AbstractSinkTest;
34  import org.apache.maven.doxia.sink.SinkTestDocument;
35  import org.codehaus.plexus.util.StringUtils;
36  
37  /**
38   * <code>FO Sink</code> Test case.
39   *
40   * @version $Id: FoSinkTest.java 1467294 2013-04-12 14:51:42Z rfscholte $
41   */
42  public class FoSinkTest
43      extends AbstractSinkTest
44  {
45      private FoConfiguration config;
46  
47      // ----------------------------------------------------------------------
48      // Specific test methods
49      // ----------------------------------------------------------------------
50  
51      /**
52       * Uses fop to generate a pdf from a test document.
53       * @throws Exception If the conversion fails.
54       */
55      public void testConvertFO2PDF()
56          throws Exception
57      {
58          String fileName = "test";
59          // first create fo
60          FoSink fosink = new FoSink( getTestWriter( fileName ) );
61          fosink.beginDocument();
62          SinkTestDocument.generate( fosink );
63          fosink.endDocument();
64          fosink.close();
65  
66          // then generate PDF
67          fo2pdf( fileName );
68      }
69  
70      /**
71       * Uses fop to generate an aggregated pdf from two test documents.
72       * @throws Exception If the conversion fails.
73       */
74      public void testAggregateMode()
75          throws Exception
76      {
77          FoAggregateSink fosink = new FoAggregateSink( getTestWriter( "aggregate" ) );
78  
79          fosink.setDocumentModel( getModel() );
80  
81          fosink.beginDocument();
82  
83          fosink.coverPage();
84  
85          fosink.toc();
86  
87          fosink.setDocumentName( "doc1" );
88          fosink.setDocumentTitle( "Document 1" );
89          SinkTestDocument.generate( fosink );
90  
91          // re-use the same source
92          fosink.setDocumentName( "doc2" );
93          fosink.setDocumentTitle( "Document 2" );
94          SinkTestDocument.generate( fosink );
95  
96          fosink.endDocument();
97  
98          // then generate PDF
99          fo2pdf( "aggregate" );
100     }
101 
102     private DocumentModel getModel()
103     {
104         DocumentModel model = new DocumentModel();
105         model.setToc( getToc() );
106         model.setMeta( getMeta() );
107         return model;
108     }
109 
110     private DocumentMeta getMeta()
111     {
112         DocumentMeta meta = new DocumentMeta();
113         meta.setAuthor( "The Apache Maven Project" );
114         meta.setTitle( "Doxia FO Sink" );
115         return meta;
116     }
117 
118     private DocumentTOC getToc()
119     {
120         DocumentTOCItem item1 = new DocumentTOCItem();
121         item1.setName( "First document" );
122         item1.setRef( "doc1.apt" );
123 
124         DocumentTOCItem item2 = new DocumentTOCItem();
125         item2.setName( "Second document" );
126         item2.setRef( "doc2.xml" );
127 
128         DocumentTOC toc = new DocumentTOC();
129         toc.setName( "What's in here" );
130         toc.addItem( item1 );
131         toc.addItem( item2 );
132 
133         return toc;
134     }
135 
136     // ----------------------------------------------------------------------
137     // Abstract methods the individual SinkTests must provide
138     // ----------------------------------------------------------------------
139 
140     /** {@inheritDoc} */
141     protected String outputExtension()
142     {
143         return "fo";
144     }
145 
146     /** {@inheritDoc} */
147     protected Sink createSink( Writer writer )
148     {
149         return new FoSink( writer );
150     }
151 
152     /** {@inheritDoc} */
153     protected boolean isXmlSink()
154     {
155         return true;
156     }
157 
158     /** {@inheritDoc} */
159     protected String getTitleBlock( String title )
160     {
161         String attribs = getConfig().getAttributeString( "doc.header.title" );
162         return EOL + "<fo:block" + attribs + ">" + title + "</fo:block>" + EOL;
163     }
164 
165     /** {@inheritDoc} */
166     protected String getAuthorBlock( String author )
167     {
168         String attribs = getConfig().getAttributeString( "doc.header.author" );
169         return EOL + "<fo:block" + attribs + ">" + author + "</fo:block>" + EOL;
170     }
171 
172     /** {@inheritDoc} */
173     protected String getDateBlock( String date )
174     {
175         String attribs = getConfig().getAttributeString( "doc.header.date" );
176         return EOL + "<fo:block" + attribs + ">" + date + "</fo:block>" + EOL;
177     }
178 
179     // TODO
180     protected String getHeadBlock()
181     {
182         return "";
183     }
184 
185     // TODO: remove
186     public void testHead()
187     {
188         String expected = "";
189         assertEquals( "Wrong head!", expected, getHeadBlock() );
190     }
191 
192     /** {@inheritDoc} */
193     protected String getBodyBlock()
194     {
195         return EOL + "</fo:flow>" + EOL + "</fo:page-sequence>" + EOL + "</fo:root>" + EOL;
196     }
197 
198     /** {@inheritDoc} */
199     protected String getSectionTitleBlock( String title )
200     {
201         return title;
202     }
203 
204     /** {@inheritDoc} */
205     protected String getSection1Block( String title )
206     {
207         String attribs = getConfig().getAttributeString( "body.text" );
208         String attrib2 = getConfig().getAttributeString( "body.h1" );
209         return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">1   " + title
210             + "</fo:block>" + EOL + "</fo:block>" + EOL;
211     }
212 
213     /** {@inheritDoc} */
214     protected String getSection2Block( String title )
215     {
216         String attribs = getConfig().getAttributeString( "body.text" );
217         String attrib2 = getConfig().getAttributeString( "body.h2" );
218         return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">0.1   " + title
219             + "</fo:block>" + EOL + "</fo:block>" + EOL;
220     }
221 
222     /** {@inheritDoc} */
223     protected String getSection3Block( String title )
224     {
225         String attribs = getConfig().getAttributeString( "body.text" );
226         String attrib2 = getConfig().getAttributeString( "body.h3" );
227         return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">0.0.1   " + title
228             + "</fo:block>" + EOL + "</fo:block>" + EOL;
229     }
230 
231     /** {@inheritDoc} */
232     protected String getSection4Block( String title )
233     {
234         String attribs = getConfig().getAttributeString( "body.text" );
235         String attrib2 = getConfig().getAttributeString( "body.h4" );
236         return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">" + title
237             + "</fo:block>" + EOL + "</fo:block>" + EOL;
238     }
239 
240     /** {@inheritDoc} */
241     protected String getSection5Block( String title )
242     {
243         String attribs = getConfig().getAttributeString( "body.text" );
244         String attrib2 = getConfig().getAttributeString( "body.h5" );
245         return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">" + title
246             + "</fo:block>" + EOL + "</fo:block>" + EOL;
247     }
248 
249     /** {@inheritDoc} */
250     protected String getListBlock( String item )
251     {
252         String attribs = getConfig().getAttributeString( "list" );
253         String itemAttribs = getConfig().getAttributeString( "list.item" );
254         return EOL + EOL + "<fo:list-block" + attribs + ">" + EOL + "<fo:list-item" + itemAttribs
255             + "><fo:list-item-label><fo:block>&#8226;</fo:block></fo:list-item-label>" + EOL + EOL
256             + "<fo:list-item-body" + itemAttribs + ">" + EOL + "<fo:block>" + item + "</fo:block>" + EOL
257             + "</fo:list-item-body>" + EOL + "</fo:list-item>" + EOL + "</fo:list-block>" + EOL;
258     }
259 
260     /** {@inheritDoc} */
261     protected String getNumberedListBlock( String item )
262     {
263         String attribs = getConfig().getAttributeString( "list" );
264         String itemAttribs = getConfig().getAttributeString( "list.item" );
265         return EOL + EOL + "<fo:list-block" + attribs + ">" + EOL + "<fo:list-item" + itemAttribs + ">" + EOL
266             + "<fo:list-item-label>" + EOL + "<fo:block>i.</fo:block>" + EOL + "</fo:list-item-label>" + EOL + EOL
267             + "<fo:list-item-body" + itemAttribs + ">" + EOL + "<fo:block>" + item + "</fo:block>" + EOL
268             + "</fo:list-item-body>" + EOL + "</fo:list-item>" + EOL + "</fo:list-block>" + EOL;
269     }
270 
271     /** {@inheritDoc} */
272     protected String getDefinitionListBlock( String definum, String definition )
273     {
274         String dlAtts = getConfig().getAttributeString( "dl" );
275         String dtAtts = getConfig().getAttributeString( "dt" );
276         String ddAtts = getConfig().getAttributeString( "dd" );
277         return EOL + EOL + "<fo:block" + dlAtts + ">" + EOL + "<fo:block" + dtAtts + ">" + definum + "</fo:block>"
278             + EOL + EOL + EOL + "<fo:block" + ddAtts + ">" + definition + "</fo:block>" + EOL + "</fo:block>"
279             + EOL;
280     }
281 
282     /** {@inheritDoc} */
283     protected String getFigureBlock( String source, String caption )
284     {
285         String dlAtts = getConfig().getAttributeString( "figure.display" );
286         String dtAtts = getConfig().getAttributeString( "figure.graphics" );
287         String ddAtts = getConfig().getAttributeString( "figure.caption" );
288 
289         String figureBlock = EOL + EOL + "<fo:block" + dlAtts + "><fo:external-graphic" + " src=\"" + source + "\"" + dtAtts
290             + "/>" + EOL;
291         if ( caption != null )
292         {
293             figureBlock += EOL + "<fo:block" + ddAtts + ">" + caption + "</fo:block>" + EOL;
294         }
295         figureBlock +=  "</fo:block>" + EOL;
296         
297         
298         return figureBlock;
299     }
300 
301     /** {@inheritDoc} */
302     protected String getTableBlock( String cell, String caption )
303     {
304         String dlAtts = getConfig().getAttributeString( "table.padding" );
305         String dtAtts = getConfig().getAttributeString( "table.layout" );
306         String ddAtts = getConfig().getAttributeString( "table.body.row" );
307         // String deAtts = getConfig().getAttributeString( "table.body.cell" );
308 
309         return EOL + EOL + "<fo:block" + dlAtts + ">" + EOL + "<fo:table" + dtAtts + ">" + EOL
310             + "<fo:table-column column-width=\"proportional-column-width(1)\"/>" + EOL + EOL + "<fo:table-body>"
311             + EOL + "<fo:table-row" + ddAtts
312             + "><fo:table-cell column-number=\"1\" padding-after=\"1.5pt\" padding-end=\"5pt\" "
313             + "keep-together.within-column=\"always\" padding-start=\"2.5pt\" "
314             + "background-color=\"#eeeeee\" padding-before=\"4pt\">" + EOL + "<fo:block line-height=\"1.2em\" "
315             + "text-align=\"center\" font-family=\"Helvetica,sans-serif\" font-size=\"9pt\">" + EOL + cell
316             + "</fo:block>" + EOL + "</fo:table-cell>" + EOL + "</fo:table-row>" + EOL + "</fo:table-body>" + EOL
317             + "</fo:table>" + EOL + "</fo:block>" + EOL + EOL
318             + "<fo:block white-space-collapse=\"true\" space-after=\"6pt\" space-before=\"3pt\" "
319             + "font-family=\"Garamond,serif\" line-height=\"12pt\" text-align=\"center\" font-size=\"11pt\">"
320             + "Table_caption</fo:block>" + EOL;
321     }
322 
323     /** {@inheritDoc} */
324     protected String getParagraphBlock( String text )
325     {
326         String attribs = getConfig().getAttributeString( "normal.paragraph" );
327         return EOL + "<fo:block" + attribs + ">" + text + "</fo:block>" + EOL;
328     }
329 
330     /** {@inheritDoc} */
331     protected String getVerbatimBlock( String text )
332     {
333         String attribs = getConfig().getAttributeString( "body.source" );
334         return EOL + "<fo:block" + attribs + ">" + text + "</fo:block>" + EOL;
335     }
336 
337     /** {@inheritDoc} */
338     protected String getHorizontalRuleBlock()
339     {
340         String attribs = getConfig().getAttributeString( "body.rule" );
341         return EOL + EOL + "<fo:block>" + EOL + "<fo:leader" + attribs + " /></fo:block>" + EOL;
342     }
343 
344     /** {@inheritDoc} */
345     protected String getPageBreakBlock()
346     {
347         return EOL + "<fo:block break-before=\"page\" />" + EOL;
348     }
349 
350     /** {@inheritDoc} */
351     protected String getAnchorBlock( String anchor )
352     {
353         // all anchors get '#' pre-pended
354         return EOL + "<fo:inline id=\"#" + anchor + "\">" + anchor + "</fo:inline>";
355     }
356 
357     /** {@inheritDoc} */
358     protected String getLinkBlock( String link, String text )
359     {
360         String attribs = getConfig().getAttributeString( "href.internal" );
361         return EOL + "<fo:basic-link internal-destination=\"" + link + "\">" + EOL + "<fo:inline" + attribs + ">"
362             + text + "</fo:inline></fo:basic-link>";
363     }
364 
365     /** {@inheritDoc} */
366     protected String getItalicBlock( String text )
367     {
368         String attribs = getConfig().getAttributeString( "italic" );
369         return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>";
370     }
371 
372     /** {@inheritDoc} */
373     protected String getBoldBlock( String text )
374     {
375         String attribs = getConfig().getAttributeString( "bold" );
376         return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>";
377     }
378 
379     /** {@inheritDoc} */
380     protected String getMonospacedBlock( String text )
381     {
382         String attribs = getConfig().getAttributeString( "monospace" );
383         return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>";
384     }
385 
386     /** {@inheritDoc} */
387     protected String getLineBreakBlock()
388     {
389         return EOL + EOL + "<fo:block />";
390     }
391 
392     /** {@inheritDoc} */
393     protected String getNonBreakingSpaceBlock()
394     {
395         return "&#160;";
396     }
397 
398     /** {@inheritDoc} */
399     protected String getTextBlock( String text )
400     {
401         return FoSink.escaped( text, false );
402     }
403 
404     /** {@inheritDoc} */
405     protected String getRawTextBlock( String text )
406     {
407         return text;
408     }
409 
410     // ----------------------------------------------------------------------
411     // Auxiliary methods
412     // ----------------------------------------------------------------------
413 
414     private void fo2pdf( String baseName )
415         throws Exception
416     {
417         // File outputDirectory = new File( getBasedirFile(), getOutputDir() );
418         File outputDirectory = new File( getBasedir(), outputBaseDir() + getOutputDir() );
419         File resourceDirectory = new File( getBasedirFile(), "target/test-classes" );
420         File foFile = new File( outputDirectory, baseName + "." + outputExtension() );
421         File pdfFile = new File( outputDirectory, baseName + ".pdf" );
422         FoUtils.convertFO2PDF( foFile, pdfFile, resourceDirectory.getCanonicalPath() );
423     }
424 
425     private FoConfiguration getConfig()
426     {
427         if ( config == null )
428         {
429             config = ( (FoSink) getSink() ).getFoConfiguration();
430         }
431 
432         return config;
433     }
434 
435     /** {@inheritDoc} */
436     protected String getCommentBlock( String text )
437     {
438         return "<!-- Simple comment with - - - - -->";
439     }
440 
441     /**
442      * DOXIA-357
443      *
444      * @throws Exception if any
445      */
446     public void testTableCaption()
447         throws Exception
448     {
449         StringBuilder html = new StringBuilder();
450         html.append( "<table>" ).append( EOL );
451         html.append( "<caption>caption table</caption>" ).append( EOL );
452         html.append( "<tr>" ).append( EOL );
453         html.append( "<td>foo</td>" ).append( EOL );
454         html.append( "</tr>" ).append( EOL );
455         html.append( "<tr>" ).append( EOL );
456         html.append( "<td>bar</td>" ).append( EOL );
457         html.append( "</tr>" ).append( EOL );
458         html.append( "</table>" ).append( EOL );
459 
460         String fileName = "testTableCaption";
461 
462         // first create fo
463         FoSink fosink = new FoSink( getTestWriter( fileName ) );
464         fosink.beginDocument();
465         SinkTestDocument.generateHead( fosink );
466 
467         fosink.body();
468         XhtmlBaseParser parser = new XhtmlBaseParser();
469         parser.parse( new StringReader( html.toString() ), fosink );
470         fosink.body_();
471 
472         fosink.endDocument();
473         fosink.close();
474 
475         // then generate PDF
476         fo2pdf( fileName );
477     }
478 
479     /**
480      * @throws Exception if any
481      */
482     public void testNestedTables()
483         throws Exception
484     {
485         StringBuilder html = new StringBuilder();
486         html.append( "<table>" ).append( EOL );
487         html.append( "<caption>first caption</caption>" ).append( EOL );
488         html.append( "<tr>" ).append( EOL );
489         html.append( "<td>foo</td>" ).append( EOL );
490         html.append( "</tr>" ).append( EOL );
491         html.append( "<tr>" ).append( EOL );
492         html.append( "<td>" ).append( EOL );
493 
494         html.append( "<table>" ).append( EOL );
495         html.append( "<caption>second caption</caption>" ).append( EOL );
496         html.append( "<tr>" ).append( EOL );
497         html.append( "<td>foo</td>" ).append( EOL );
498         html.append( "<td>bar</td>" ).append( EOL );
499         html.append( "</tr>" ).append( EOL );
500         html.append( "<tr>" ).append( EOL );
501         html.append( "<td>foo1</td>" ).append( EOL );
502         html.append( "<td>" ).append( EOL );
503 
504         html.append( "<table>" ).append( EOL );
505         html.append( "<caption>third caption</caption>" ).append( EOL );
506         html.append( "<tr>" ).append( EOL );
507         html.append( "<td>foo1</td>" ).append( EOL );
508         html.append( "<td>bar1</td>" ).append( EOL );
509         html.append( "</tr>" ).append( EOL );
510         html.append( "</table>" ).append( EOL );
511         html.append( "</td>" ).append( EOL );
512 
513         html.append( "</tr>" ).append( EOL );
514         html.append( "</table>" ).append( EOL );
515 
516         html.append( "</td>" ).append( EOL );
517         html.append( "</tr>" ).append( EOL );
518         html.append( "</table>" ).append( EOL );
519 
520         String fileName = "testNestedTables";
521 
522         // first create fo
523         FoSink fosink = new FoSink( getTestWriter( fileName ) );
524         fosink.beginDocument();
525         SinkTestDocument.generateHead( fosink );
526 
527         fosink.body();
528         XhtmlBaseParser parser = new XhtmlBaseParser();
529         parser.parse( new StringReader( html.toString() ), fosink );
530         fosink.body_();
531 
532         fosink.endDocument();
533         fosink.close();
534 
535         // then generate PDF
536         fo2pdf( fileName );
537     }
538 }