1 package org.apache.maven.doxia.book.services.renderer;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 import java.util.Iterator;
28 import java.util.Locale;
29
30 import org.apache.maven.doxia.Doxia;
31 import org.apache.maven.doxia.book.BookDoxiaException;
32 import org.apache.maven.doxia.book.context.BookContext;
33 import org.apache.maven.doxia.book.model.BookModel;
34 import org.apache.maven.doxia.book.model.Chapter;
35 import org.apache.maven.doxia.book.model.Section;
36 import org.apache.maven.doxia.book.services.renderer.xdoc.ChapterXdocBookSink;
37 import org.apache.maven.doxia.book.services.renderer.xdoc.IndexXdocBookSink;
38 import org.apache.maven.doxia.book.services.renderer.xdoc.SectionXdocBookSink;
39 import org.apache.maven.doxia.index.IndexEntry;
40 import org.apache.maven.doxia.module.xdoc.XdocSink;
41 import org.apache.maven.doxia.parser.ParseException;
42 import org.apache.maven.doxia.parser.manager.ParserNotFoundException;
43 import org.apache.maven.doxia.util.HtmlTools;
44 import org.codehaus.plexus.i18n.I18N;
45 import org.codehaus.plexus.logging.AbstractLogEnabled;
46 import org.codehaus.plexus.util.IOUtil;
47 import org.codehaus.plexus.util.ReaderFactory;
48 import org.codehaus.plexus.util.StringUtils;
49 import org.codehaus.plexus.util.WriterFactory;
50
51
52
53
54
55
56
57
58
59 public class XdocBookRenderer
60 extends AbstractLogEnabled
61 implements BookRenderer
62 {
63
64
65
66 private Doxia doxia;
67
68
69
70
71 private I18N i18n;
72
73
74
75
76
77
78 public void renderBook( BookContext context )
79 throws BookDoxiaException
80 {
81 BookModel book = context.getBook();
82
83 if ( !context.getOutputDirectory().exists() )
84 {
85 if ( !context.getOutputDirectory().mkdirs() )
86 {
87 throw new BookDoxiaException( "Could not make directory: "
88 + context.getOutputDirectory().getAbsolutePath() + "." );
89 }
90 }
91
92 renderBook( book, context );
93 }
94
95
96
97
98
99
100
101
102
103
104
105
106 protected String getString( Locale locale, String key )
107 {
108 if ( StringUtils.isEmpty( key ) )
109 {
110 throw new IllegalArgumentException( "The key cannot be empty" );
111 }
112
113 return i18n.getString( "book-renderer", locale, key ).trim();
114 }
115
116
117
118
119
120
121
122
123
124
125
126
127 private void renderBook( BookModel book, BookContext context )
128 throws BookDoxiaException
129 {
130
131
132
133
134 File index = new File( context.getOutputDirectory(), "index.xml" );
135
136 try
137 {
138 writeBookIndex( index, book, context );
139 }
140 catch ( IOException e )
141 {
142 throw new BookDoxiaException( "Error while rendering index page to: '"
143 + index.getAbsolutePath() + "'.", e );
144 }
145
146
147
148
149
150 Iterator<IndexEntry> ii = context.getIndex().getChildEntries().iterator();
151
152 for ( Chapter chapter : book.getChapters() )
153 {
154 renderChapter( chapter, context, ii.next() );
155 }
156 }
157
158
159
160
161
162
163
164
165
166 private void writeBookIndex( File index, BookModel book, BookContext context )
167 throws IOException
168 {
169 Writer writer = WriterFactory.newXmlWriter( index );
170
171 XdocSink sink = new IndexXdocBookSink( writer, context.getIndex().getFirstEntry(), i18n, context.getLocale() );
172
173 try
174 {
175
176
177
178
179 sink.head();
180
181 sink.title();
182 sink.text( book.getTitle() + " - " + getString( context.getLocale(), "toc" ) );
183 sink.title_();
184
185 sink.head_();
186
187
188
189
190
191 sink.body();
192
193 sink.section1();
194 sink.sectionTitle1();
195 sink.text( book.getTitle() + " - " + getString( context.getLocale(), "toc" ) );
196 sink.sectionTitle1_();
197
198 sink.list();
199 for ( IndexEntry entry : context.getIndex().getChildEntries() )
200 {
201 writeChapterIndexForBookIndex( sink, entry );
202 }
203 sink.list_();
204
205 sink.section1_();
206
207 sink.body_();
208 }
209 finally
210 {
211 sink.flush();
212
213 sink.close();
214
215 IOUtil.close( writer );
216 }
217 }
218
219
220
221
222
223
224
225 private void writeChapterIndexForBookIndex( XdocSink sink, IndexEntry chapterEntry )
226 {
227 sink.listItem();
228 sink.link( chapterEntry.getId() + ".html" );
229 sink.text( chapterEntry.getTitle() );
230 sink.link_();
231
232 sink.list();
233 for ( IndexEntry sectionIndex : chapterEntry.getChildEntries() )
234 {
235 writeSectionIndexForBookIndex( sink, sectionIndex );
236 }
237 sink.list_();
238
239 sink.listItem_();
240 }
241
242
243
244
245
246
247
248 private void writeSectionIndexForBookIndex( XdocSink sink, IndexEntry sectionIndex )
249 {
250 sink.listItem();
251 sink.link( sectionIndex.getId() + ".html" );
252 sink.text( sectionIndex.getTitle() );
253 sink.link_();
254
255 sink.list();
256 for ( IndexEntry subsectionIndex : sectionIndex.getChildEntries() )
257 {
258 writeSubsectionIndexForBookIndex( sink, sectionIndex, subsectionIndex );
259 }
260 sink.list_();
261
262 sink.listItem_();
263 }
264
265
266
267
268
269
270
271
272 private void writeSubsectionIndexForBookIndex( XdocSink sink, IndexEntry sectionIndex, IndexEntry subsectionIndex )
273 {
274 sink.listItem();
275 sink.link( sectionIndex.getId() + ".html#" + HtmlTools.encodeId( subsectionIndex.getId() ) );
276 sink.text( subsectionIndex.getTitle() );
277 sink.link_();
278 sink.listItem_();
279 }
280
281
282
283
284
285
286
287
288
289
290
291
292
293 private void renderChapter( Chapter chapter, BookContext context, IndexEntry chapterIndex )
294 throws BookDoxiaException
295 {
296
297
298
299
300 File index = new File( context.getOutputDirectory(), chapter.getId() + ".xml" );
301
302 try
303 {
304 writeChapterIndex( index, chapter, chapterIndex, context );
305 }
306 catch ( IOException e )
307 {
308 throw new BookDoxiaException( "Error while rendering index page to: '"
309 + index.getAbsolutePath() + "'.", e );
310 }
311
312
313
314
315
316 Iterator<IndexEntry> ii = chapterIndex.getChildEntries().iterator();
317
318 for ( Section section : chapter.getSections() )
319 {
320 renderSection( context, section, ii.next() );
321 }
322 }
323
324
325
326
327
328
329
330
331
332
333 private void writeChapterIndex( File index, Chapter chapter, IndexEntry chapterIndex, BookContext context )
334 throws IOException
335 {
336 Writer writer = WriterFactory.newXmlWriter( index );
337
338 ChapterXdocBookSink sink = new ChapterXdocBookSink( writer, chapterIndex, i18n, context.getLocale() );
339
340 try
341 {
342
343
344
345
346 sink.head();
347
348 sink.title();
349 sink.text( chapter.getTitle() );
350 sink.title_();
351
352 sink.head_();
353
354
355
356
357
358 sink.body();
359
360 sink.section1();
361 sink.sectionTitle1();
362 sink.text( chapter.getTitle() );
363 sink.sectionTitle1_();
364
365 sink.list();
366 for ( IndexEntry sectionIndex : chapterIndex.getChildEntries() )
367 {
368 writeSectionIndexForBookIndex( sink, sectionIndex );
369 }
370 sink.list_();
371
372 sink.section1_();
373
374 sink.body_();
375 }
376 finally
377 {
378 sink.flush();
379
380 sink.close();
381
382 IOUtil.close( writer );
383 }
384 }
385
386
387
388
389
390
391
392
393
394 private void renderSection( BookContext context, Section section, IndexEntry sectionIndex )
395 throws BookDoxiaException
396 {
397 try
398 {
399 Writer writer = WriterFactory.newXmlWriter( new File( context.getOutputDirectory()
400 + "/" + section.getId() + ".xml" ) );
401
402 SectionXdocBookSink sink = new SectionXdocBookSink( writer, sectionIndex, i18n, context.getLocale() );
403
404 BookContext.BookFile bookFile = (BookContext.BookFile) context.getFiles().get( section.getId() );
405
406 if ( bookFile == null )
407 {
408 throw new BookDoxiaException( "No document that matches section with id=" + section.getId() + "." );
409 }
410
411 Reader reader = null;
412 try
413 {
414 reader = ReaderFactory.newReader( bookFile.getFile(), context.getInputEncoding() );
415 doxia.parse( reader, bookFile.getParserId(), sink );
416 }
417 catch ( ParserNotFoundException e )
418 {
419 throw new BookDoxiaException( "Parser not found: " + bookFile.getParserId() + ".", e );
420 }
421 catch ( ParseException e )
422 {
423 throw new BookDoxiaException( "Error while parsing document: " + bookFile.getFile().getAbsolutePath()
424 + ".", e );
425 }
426 catch ( FileNotFoundException e )
427 {
428 throw new BookDoxiaException( "Could not find document: " + bookFile.getFile().getAbsolutePath() + ".",
429 e );
430 }
431 finally
432 {
433 sink.flush();
434 sink.close();
435
436 IOUtil.close( reader );
437 IOUtil.close( writer );
438 }
439 }
440 catch ( IOException e )
441 {
442 throw new BookDoxiaException( "Error while rendering book.", e );
443 }
444 }
445 }