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.IOException;
24  import java.io.StringWriter;
25  import java.io.Writer;
26  
27  import javax.xml.transform.TransformerException;
28  
29  import org.apache.maven.doxia.document.DocumentCover;
30  import org.apache.maven.doxia.document.DocumentModel;
31  import org.apache.maven.doxia.markup.Markup;
32  import org.codehaus.plexus.util.WriterFactory;
33  import org.custommonkey.xmlunit.Diff;
34  import org.custommonkey.xmlunit.XMLUnit;
35  import org.xml.sax.SAXParseException;
36  
37  import junit.framework.TestCase;
38  
39  /**
40   * Test FoAggregateSink.
41   *
42   * @author ltheussl
43   * @version $Id: FoAggregateSinkTest.java 1563713 2014-02-02 20:55:04Z rfscholte $
44   */
45  public class FoAggregateSinkTest
46      extends TestCase
47  {
48      private FoAggregateSink sink;
49  
50      private Writer writer;
51  
52      @Override
53      protected void setUp()
54          throws Exception
55      {
56          super.setUp();
57          writer = new StringWriter();
58      }
59      
60      protected String wrapXml( String xmlFragment )
61      {
62          return "<fo:fo xmlns:fo=\"" + FoMarkup.FO_NAMESPACE+ "\">" + xmlFragment + "</fo:fo>";
63      }
64  
65  
66      /**
67       * Test of body method, of class FoAggregateSink.
68       */
69      public void testBody()
70      {
71          try
72          {
73              sink = new FoAggregateSink( writer );
74  
75              sink.setDocumentName( "folder/documentName.apt" );
76              sink.setDocumentTitle( "documentTitle" );
77              sink.body();
78              sink.body_();
79          }
80          finally
81          {
82              sink.close();
83          }
84  
85          assertTrue( writer.toString().indexOf( "<fo:block id=\"./folder/documentName\">" ) != -1 );
86      }
87  
88      /**
89       * Test of setDocumentName method, of class FoAggregateSink.
90       */
91      public void testSetDocumentName()
92      {
93          try
94          {
95              sink = new FoAggregateSink( writer );
96  
97              sink.setDocumentName( "folder\\documentName.boo" );
98              sink.body();
99          }
100         finally
101         {
102             sink.close();
103         }
104 
105         assertTrue( writer.toString().indexOf( "<fo:block id=\"./folder/documentName\">" ) != -1 );
106     }
107     
108     /**
109      * Test the FO PDF generation with some special characters in company name.
110      */
111     public void testSpecialCharacters()
112         throws IOException, TransformerException
113     {
114         DocumentModel model = new DocumentModel();
115         DocumentCover cover = new DocumentCover();
116 
117         cover.setCompanyName( "Partner & Friends" );
118         cover.setCoverTitle( "A Masterpice in Encoding Theory <>&" );
119         cover.setCoverSubTitle( "Some nice Encodings & <METHODS>" );
120         cover.setProjectName( "A Masterpice in Encoding Theory <>&" );
121         cover.setAuthor( "Partner & Friends" );
122         model.setCover( cover );
123 
124         File foFile = File.createTempFile( "fo-test", ".fo" );
125         File pdfFile = File.createTempFile( "fo-test", ".pdf" );
126         try
127         {
128 
129             sink = new FoAggregateSink( WriterFactory.newXmlWriter( foFile ) );
130 
131             sink.setDocumentModel( model );
132             sink.setDocumentTitle( "A Masterpice in Encoding Theory <>&" );
133             sink.beginDocument();
134             sink.coverPage();
135             // sink.toc();
136             sink.endDocument();
137         }
138         finally
139         {
140             sink.close();
141         }
142 
143         try
144         {
145             FoUtils.convertFO2PDF( foFile, pdfFile, null, model );
146         }
147         catch ( TransformerException e )
148         {
149             if ( ( e.getCause() != null ) && ( e.getCause() instanceof SAXParseException ) )
150             {
151                 SAXParseException sax = (SAXParseException) e.getCause();
152 
153                 StringBuffer sb = new StringBuffer();
154                 sb.append( "Error creating PDF from " ).append( foFile.getAbsolutePath() ).append( ":" ).append( sax.getLineNumber() ).append( ":" ).append( sax.getColumnNumber() ).append( "\n" );
155                 sb.append( e.getMessage() );
156 
157                 throw new RuntimeException( sb.toString() );
158             }
159 
160             throw new TransformerException( "Error creating PDF from " + foFile + ": " + e.getMessage() );
161         }
162     }
163 
164     /**
165      * Test of figureGraphics method, of class FoAggregateSink.
166      */
167     public void testFigureGraphics() throws Exception
168     {
169         try
170         {
171             sink = new FoAggregateSink( writer );
172             sink.setDocumentName( "./folder\\docName.xml" );
173             sink.figureGraphics( "./../images/fig.png", null );
174         }
175         finally
176         {
177             sink.close();
178         }
179 
180         String expected = "<fo:external-graphic src=\"./images/fig.png\" "
181                         + "content-width=\"scale-down-to-fit\" "
182                         + "content-height=\"scale-down-to-fit\" "
183                         + "height=\"100%\" "
184                         + "width=\"100%\"/>" + Markup.EOL;
185         String actual = writer.toString();
186 
187         Diff diff = XMLUnit.compareXML( wrapXml( expected ), wrapXml( actual ) );
188         assertTrue( "Wrong figure!", diff.identical() );
189     }
190 
191     /**
192      * Test of anchor method, of class FoAggregateSink.
193      */
194     public void testAnchor()
195     {
196         try
197         {
198             sink = new FoAggregateSink( writer );
199             sink.anchor( "invalid Anchor" );
200             sink.setDocumentName( "./folder\\docName.xml" );
201             sink.anchor( "validAnchor" );
202         }
203         finally
204         {
205             sink.close();
206         }
207 
208         assertTrue( writer.toString().indexOf( "<fo:inline id=\"#invalid_Anchor\">" ) != -1 );
209         assertTrue( writer.toString().indexOf( "<fo:inline id=\"./folder/docName#validAnchor\">" ) != -1 );
210     }
211 
212     /**
213      * Test of link method, of class FoAggregateSink.
214      */
215     public void testLink()
216     {
217         try
218         {
219             sink = new FoAggregateSink( writer );
220             sink.link( "http://www.example.com/" );
221             sink.text( "http://www.example.com/" );
222             sink.link_();
223             sink.setDocumentName( "./folder\\docName.xml" );
224             sink.link( "#anchor" );
225             sink.text( "#anchor" );
226             sink.link_();
227             sink.link( "./././index.html" );
228             sink.text( "./././index.html" );
229             sink.link_();
230             sink.link( "./../download.html" );
231             sink.text( "./../download.html" );
232             sink.link_();
233             sink.link( ".///test.html" );
234             sink.text( "./test.html" );
235             sink.link_();
236             sink.link( "./whatsnew-1.1.html" );
237             sink.text( "./whatsnew-1.1.html" );
238             sink.link_();
239             sink.setDocumentName( ".///whatsnew-1.1.html" );
240             sink.body();
241             sink.body_();
242         }
243         finally
244         {
245             sink.close();
246         }
247 
248         String result = writer.toString();
249 
250         assertTrue( result.indexOf( "<fo:basic-link external-destination=\"http://www.example.com/\">" ) != -1 );
251         assertTrue( result.indexOf( "<fo:basic-link internal-destination=\"./folder/docName#anchor\">" ) != -1 );
252         assertTrue( result.indexOf( "<fo:basic-link internal-destination=\"./folder/index\">" ) != -1 );
253         assertTrue( result.indexOf( "<fo:basic-link internal-destination=\"./download\">" ) != -1 );
254         assertTrue( result.indexOf( "<fo:basic-link internal-destination=\"./folder/test\">" ) != -1 );
255         assertTrue( result.indexOf( "<fo:basic-link internal-destination=\"./folder/whatsnew-1.1\">" ) != -1 );
256         assertTrue( result.indexOf( "<fo:block id=\"./whatsnew-1.1\">" ) != -1 );
257 
258         writer = new StringWriter();
259         try
260         {
261             sink = new FoAggregateSink( writer );
262             sink.setDocumentName( "./subdir/dir/index.html" );
263             sink.link( "../../root.html" );
264             sink.text( "../../root.html" );
265             sink.link_();
266             sink.link( "../../../outside.html" );
267             sink.text( "../../../outside.html" );
268             sink.link_();
269             sink.body();
270             sink.body_();
271         }
272         finally
273         {
274             sink.close();
275         }
276 
277         result = writer.toString();
278 
279         assertTrue( result.indexOf( "<fo:basic-link internal-destination=\"./root\">" ) != -1 );
280         assertTrue( result.indexOf( "<fo:basic-link internal-destination=\"./outside\">" ) != -1 );
281     }
282 }