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