1 package org.apache.maven.doxia.plugin;
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 org.apache.maven.doxia.book.BookDoxia;
23 import org.apache.maven.doxia.book.BookDoxiaException;
24 import org.apache.maven.doxia.book.InvalidBookDescriptorException;
25 import org.apache.maven.doxia.book.model.BookModel;
26 import org.apache.maven.doxia.book.services.validation.ValidationResult;
27 import org.apache.maven.doxia.tools.SiteTool;
28 import org.apache.maven.plugin.AbstractMojo;
29 import org.apache.maven.plugin.MojoExecutionException;
30 import org.apache.maven.plugin.MojoFailureException;
31 import org.codehaus.plexus.util.FileUtils;
32 import org.codehaus.plexus.util.ReaderFactory;
33 import org.codehaus.plexus.util.StringUtils;
34
35 import java.io.File;
36 import java.io.IOException;
37 import java.util.List;
38 import java.util.Locale;
39
40 /**
41 * A Mojo to create books in different output formats.
42 *
43 * @goal render-books
44 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
45 * @version $Id: DoxiaRenderBooksMojo.java 1090706 2011-04-09 23:15:28Z hboutemy $
46 * @since 1.0
47 */
48 public class DoxiaRenderBooksMojo
49 extends AbstractMojo
50 {
51 /** System EOL. */
52 private static final String LINE_SEPARATOR = System.getProperty( "line.separator" );
53
54 // ----------------------------------------------------------------------
55 // Mojo components
56 // ----------------------------------------------------------------------
57
58 /**
59 * BookDoxia component
60 *
61 * @component
62 */
63 private BookDoxia bookDoxia;
64
65 /**
66 * SiteTool.
67 *
68 * @component
69 */
70 protected SiteTool siteTool;
71
72 // ----------------------------------------------------------------------
73 // Mojo parameters
74 // ----------------------------------------------------------------------
75
76 /**
77 * A list of books.
78 *
79 * @parameter
80 * @required
81 */
82 private List<Book> books;
83
84 /**
85 * Base directory of the project.
86 *
87 * @parameter default-value="${basedir}"
88 */
89 private File basedir;
90
91 /**
92 * Directory containing the generated project docs.
93 *
94 * @parameter default-value="${project.build.directory}/generated-site"
95 */
96 private File generatedDocs;
97
98 /**
99 * A comma separated list of locales supported by Maven. The first valid token will be the default Locale
100 * for this instance of the Java Virtual Machine.
101 *
102 * @parameter default-value="${locales}"
103 */
104 protected String locales;
105
106 /**
107 * Specifies the input encoding.
108 *
109 * @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}"
110 */
111 private String inputEncoding;
112
113 /**
114 * Specifies the output encoding.
115 *
116 * @parameter expression="${outputEncoding}" default-value="${project.reporting.outputEncoding}"
117 */
118 private String outputEncoding;
119
120 // ----------------------------------------------------------------------
121 //
122 // ----------------------------------------------------------------------
123
124 /**
125 * {@inheritDoc}
126 *
127 * Executes the Mojo.
128 */
129 public void execute()
130 throws MojoExecutionException, MojoFailureException
131 {
132 for ( Book book : books )
133 {
134 // ----------------------------------------------------------------------
135 // Validate
136 // ----------------------------------------------------------------------
137
138 if ( StringUtils.isEmpty( book.getDescriptor() ) )
139 {
140 throw new MojoFailureException( "Invalid configuration: "
141 + "The book is required to have a descriptor set." );
142 }
143
144 if ( StringUtils.isEmpty( book.getDirectory() ) )
145 {
146 throw new MojoFailureException( "Invalid configuration: "
147 + "The book is required to have a directory set." );
148 }
149
150 if ( book.getFormats() == null || book.getFormats().size() == 0 )
151 {
152 throw new MojoFailureException( "Invalid configuration: "
153 + "The book is required to have at least one format set." );
154 }
155
156 // ----------------------------------------------------------------------
157 //
158 // ----------------------------------------------------------------------
159
160 File descriptor = new File( basedir, book.getDescriptor() );
161
162 String includes;
163 if ( book.getIncludes() != null )
164 {
165 includes = StringUtils.join( book.getIncludes().iterator(), "," );
166 }
167 else
168 {
169 includes = "**/*";
170 }
171
172 String excludes = "";
173
174 if ( book.getExcludes() != null )
175 {
176 excludes = StringUtils.join( book.getExcludes().iterator(), "," );
177 }
178
179 // ----------------------------------------------------------------------
180 // Find all the files to pass to the renderer.
181 // ----------------------------------------------------------------------
182
183 if ( getLog().isDebugEnabled() )
184 {
185 getLog().debug( "Locating files to include in the book:" );
186 getLog().debug( "Basedir: " + basedir );
187 getLog().debug( "Includes: " + includes );
188 getLog().debug( "Excludes: " + excludes );
189 }
190
191 List<File> files;
192
193 try
194 {
195 files = FileUtils.getFiles( new File( basedir, book.getDirectory() ), includes, excludes );
196 }
197 catch ( IOException e )
198 {
199 throw new MojoExecutionException( "Error while looking for input files. " + "Basedir="
200 + basedir.getAbsolutePath() + ", " + "includes=" + includes + ", " + "excludes=" + excludes, e );
201 }
202
203 // -----------------------------------------------------------------------
204 // Load the model
205 // -----------------------------------------------------------------------
206
207 BookModel bookModel;
208
209 try
210 {
211 bookModel = bookDoxia.loadBook( descriptor );
212 }
213 catch ( InvalidBookDescriptorException e )
214 {
215 throw new MojoFailureException( "Invalid book descriptor: " + LINE_SEPARATOR
216 + formatResult( e.getValidationResult() ) );
217 }
218 catch ( BookDoxiaException e )
219 {
220 throw new MojoExecutionException( "Error while loading the book descriptor", e );
221 }
222
223 // -----------------------------------------------------------------------
224 // Render the book in all the formats
225 // -----------------------------------------------------------------------
226
227 List<Locale> localesList = siteTool.getAvailableLocales( locales );
228
229 // Default is first in the list
230 Locale defaultLocale = localesList.get( 0 );
231 Locale.setDefault( defaultLocale );
232
233 for ( Locale locale : localesList )
234 {
235 for ( Format format : book.getFormats() )
236 {
237 File outputDirectory = new File( generatedDocs, format.getId() );
238 File directory = new File( outputDirectory + "/" + locale.toString(), bookModel.getId() );
239
240 if ( locale.equals( defaultLocale ) )
241 {
242 directory = new File( outputDirectory, bookModel.getId() );
243 }
244
245 try
246 {
247 bookDoxia.renderBook( bookModel, format.getId(), files, directory, locale,
248 getInputEncoding(), getOutputEncoding() );
249 }
250 catch ( BookDoxiaException e )
251 {
252 throw new MojoExecutionException( "Error while generating book in format '"
253 + format.getId() + "'.", e );
254 }
255 }
256 }
257 }
258 }
259
260 /**
261 * Gets the input files encoding.
262 *
263 * @return The input files encoding, never <code>null</code>.
264 * @since 1.1
265 */
266 protected String getInputEncoding()
267 {
268 return ( inputEncoding == null ) ? ReaderFactory.ISO_8859_1 : inputEncoding;
269 }
270
271 /**
272 * Gets the effective reporting output files encoding.
273 *
274 * @return The effective reporting output file encoding, never <code>null</code>.
275 * @since 1.1
276 */
277 protected String getOutputEncoding()
278 {
279 return ( outputEncoding == null ) ? ReaderFactory.UTF_8 : outputEncoding;
280 }
281
282 /**
283 * Returns a formatted message of a ValidationResult.
284 *
285 * @param result the ValidationResult to format.
286 * @return the formatted result.
287 */
288 private String formatResult( ValidationResult result )
289 {
290 StringBuffer buffer = new StringBuffer();
291
292 if ( result.getErrors().size() > 0 )
293 {
294 buffer.append( "Validation errors:" );
295
296 for ( String error : result.getErrors() )
297 {
298 buffer.append( LINE_SEPARATOR ).append( " " ).append( error );
299 }
300 }
301
302 if ( result.getWarnings().size() > 0 )
303 {
304 buffer.append( "Validation warnings:" );
305
306 for ( String error : result.getWarnings() )
307 {
308 buffer.append( LINE_SEPARATOR ).append( " " ).append( error );
309 }
310 }
311
312 return buffer.toString();
313 }
314 }