View Javadoc

1   package org.apache.maven.doxia.book.services.renderer;
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.FileNotFoundException;
24  import java.io.IOException;
25  import java.io.Reader;
26  import java.io.Writer;
27  
28  import org.apache.maven.doxia.Doxia;
29  import org.apache.maven.doxia.book.BookDoxiaException;
30  import org.apache.maven.doxia.book.context.BookContext;
31  import org.apache.maven.doxia.book.model.BookModel;
32  import org.apache.maven.doxia.book.model.Chapter;
33  import org.apache.maven.doxia.book.model.Section;
34  import org.apache.maven.doxia.book.services.renderer.docbook.DocBookBookSink;
35  import org.apache.maven.doxia.parser.ParseException;
36  import org.apache.maven.doxia.parser.manager.ParserNotFoundException;
37  import org.apache.maven.doxia.sink.Sink;
38  import org.codehaus.plexus.logging.AbstractLogEnabled;
39  import org.codehaus.plexus.util.IOUtil;
40  import org.codehaus.plexus.util.ReaderFactory;
41  import org.codehaus.plexus.util.StringUtils;
42  import org.codehaus.plexus.util.WriterFactory;
43  
44  /**
45   * An implementation of <code>BookRenderer</code> for docbook
46   *
47   * @plexus.component role-hint="doc-book"
48   * @author Eric Redmond
49   * @version $Id: DocbookBookRenderer.java 1090706 2011-04-09 23:15:28Z hboutemy $
50   */
51  public class DocbookBookRenderer
52      extends AbstractLogEnabled
53      implements BookRenderer
54  {
55      /**
56       * @plexus.requirement
57       */
58      private Doxia doxia;
59  
60      // ----------------------------------------------------------------------
61      // BookRenderer Implementation
62      // ----------------------------------------------------------------------
63  
64      /** {@inheritDoc} */
65      public void renderBook( BookContext context )
66          throws BookDoxiaException
67      {
68          BookModel book = context.getBook();
69  
70          if ( !context.getOutputDirectory().exists() )
71          {
72              if ( !context.getOutputDirectory().mkdirs() )
73              {
74                  throw new BookDoxiaException( "Could not make directory: "
75                          + context.getOutputDirectory().getAbsolutePath() + "." );
76              }
77          }
78  
79          File bookFile = new File( context.getOutputDirectory(), book.getId() + ".xml" );
80  
81          Writer fileWriter;
82          try
83          {
84              fileWriter = WriterFactory.newXmlWriter( bookFile );
85          }
86          catch ( IOException e )
87          {
88              throw new BookDoxiaException( "Error while opening file.", e );
89          }
90  
91          // ----------------------------------------------------------------------
92          // Create the Dockbook File
93          // ----------------------------------------------------------------------
94  
95          // TODO: Write out TOC?
96  
97          DocBookBookSink sink = new DocBookBookSink( fileWriter );
98  
99          try
100         {
101             sink.book();
102 
103             // TODO: symmetrize bookHead?
104 
105             if ( StringUtils.isNotEmpty( book.getTitle() ) )
106             {
107                 sink.bookTitle();
108                 sink.text( book.getTitle() );
109                 sink.bookTitle_();
110             }
111 
112             if ( StringUtils.isNotEmpty( book.getDate() ) )
113             {
114                 sink.bookDate();
115                 sink.text( book.getDate() );
116                 sink.bookDate_();
117             }
118 
119             if ( StringUtils.isNotEmpty( book.getAuthor() ) )
120             {
121                 sink.bookAuthor();
122                 sink.text( book.getAuthor() );
123                 sink.bookAuthor_();
124             }
125 
126             sink.bookHead_();
127 
128             for ( Chapter chapter : book.getChapters() )
129             {
130                 sink.chapter();
131 
132                 if ( StringUtils.isNotEmpty( chapter.getTitle() ) )
133                 {
134                     sink.chapterTitle();
135                     sink.text( chapter.getTitle() );
136                     sink.chapterTitle_();
137                 }
138 
139                 renderChapter( chapter, context, sink );
140 
141                 sink.chapter_();
142             }
143 
144             sink.book_();
145         }
146         finally
147         {
148             sink.flush();
149 
150             sink.close();
151 
152             IOUtil.close( fileWriter );
153         }
154     }
155 
156     /**
157      * Write a chapter.
158      *
159      * @param writer the writer.
160      * @param chapter the Chapter.
161      * @param context the BookContext.
162      * @param sink a Sink.
163      * @throws BookDoxiaException if the chapter cannot be written.
164      */
165     private void renderChapter( Chapter chapter, BookContext context, Sink sink )
166         throws BookDoxiaException
167     {
168         for ( Section section : chapter.getSections() )
169         {
170             renderSection( section, context, sink );
171         }
172     }
173 
174     /**
175      * Write a section.
176      *
177      * @param writer the writer.
178      * @param section the Section.
179      * @param context the BookContext.
180      * @param sink a Sink.
181      * @throws BookDoxiaException if the section cannot be written.
182      */
183     private void renderSection( Section section, BookContext context, Sink sink )
184         throws BookDoxiaException
185     {
186         BookContext.BookFile bookFile = (BookContext.BookFile) context.getFiles().get( section.getId() );
187 
188         if ( bookFile == null )
189         {
190             throw new BookDoxiaException( "No document that matches section with id=" + section.getId() + "." );
191         }
192 
193         Reader reader = null;
194         try
195         {
196             reader = ReaderFactory.newReader( bookFile.getFile(), context.getInputEncoding() );
197             doxia.parse( reader, bookFile.getParserId(), sink );
198         }
199         catch ( ParserNotFoundException e )
200         {
201             throw new BookDoxiaException( "Parser not found: " + bookFile.getParserId() + ".", e );
202         }
203         catch ( ParseException e )
204         {
205             throw new BookDoxiaException(
206                                           "Error while parsing document: " + bookFile.getFile().getAbsolutePath() + ".",
207                                           e );
208         }
209         catch ( FileNotFoundException e )
210         {
211             throw new BookDoxiaException( "Could not find document: " + bookFile.getFile().getAbsolutePath() + ".", e );
212         }
213         catch ( IOException e )
214         {
215             throw new BookDoxiaException( "Error while rendering book: "
216                       + bookFile.getFile().getAbsolutePath() + ".", e );
217         }
218         finally
219         {
220             IOUtil.close( reader );
221         }
222     }
223 }