View Javadoc
1   package org.apache.maven.plugins.pdf;
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.IOException;
23  import java.util.ArrayList;
24  import java.util.Date;
25  import java.util.List;
26  
27  import org.apache.maven.doxia.document.DocumentAuthor;
28  import org.apache.maven.doxia.document.DocumentCover;
29  import org.apache.maven.doxia.document.DocumentMeta;
30  import org.apache.maven.doxia.document.DocumentModel;
31  import org.apache.maven.doxia.document.DocumentTOC;
32  import org.apache.maven.doxia.document.DocumentTOCItem;
33  import org.apache.maven.doxia.site.decoration.DecorationModel;
34  import org.apache.maven.doxia.site.decoration.Menu;
35  import org.apache.maven.doxia.site.decoration.MenuItem;
36  import org.apache.maven.model.Developer;
37  import org.apache.maven.project.MavenProject;
38  import org.codehaus.plexus.util.IOUtil;
39  import org.codehaus.plexus.util.StringUtils;
40  import org.apache.commons.io.input.XmlStreamReader;
41  
42  /**
43   * Construct a DocumentModel from a MavenProject and related information.
44   *
45   * @author ltheussl
46   * @version $Id$
47   */
48  public class DocumentModelBuilder
49  {
50      /** A MavenProject to extract the information. */
51      private final MavenProject project;
52  
53      /** A DecorationModel to extract additional information. */
54      private final DecorationModel decorationModel;
55  
56      /**
57       * Constructor. Initialize a MavenProject to extract information from.
58       *
59       * @param project a MavenProject. May be null.
60       */
61      public DocumentModelBuilder( MavenProject project )
62      {
63          this( project, null );
64      }
65  
66      /**
67       * Constructor. Initialize a MavenProject and a DecorationModel to extract information from.
68       *
69       * @param project a MavenProject. May be null.
70       * @param decorationModel a DecorationModel. May be null.
71       */
72      public DocumentModelBuilder( MavenProject project, DecorationModel decorationModel )
73      {
74          this.project = project;
75          this.decorationModel = decorationModel;
76      }
77  
78      /**
79       * Get a DocumentModel.
80       *
81       * @return a DocumentModel. Always non-null.
82       */
83      public DocumentModel getDocumentModel()
84      {
85          return getDocumentModel( project, decorationModel, null );
86      }
87  
88      /**
89       * Get a DocumentModel.
90       *
91       * @param date overrides the default date in meta- and cover information.
92       * @return a DocumentModel. Always non-null.
93       */
94      public DocumentModel getDocumentModel( Date date )
95      {
96          return getDocumentModel( project, decorationModel, date );
97      }
98  
99      // ----------------------------------------------------------------------
100     // Private methods
101     // ----------------------------------------------------------------------
102 
103     /**
104      * Extract a DocumentModel from a MavenProject.
105      *
106      * @param project a MavenProject. May be null.
107      * @param decorationModel a DecorationModel. May be null.
108      * @param date the date of the TOC. May be null in which case the build date will be used.
109      *
110      * @return a DocumentModel. Always non-null.
111      */
112     private static DocumentModel getDocumentModel( MavenProject project,
113             DecorationModel decorationModel, Date date )
114     {
115         final Date now = ( date == null ? new Date() : date );
116 
117         final DocumentModel docModel = new DocumentModel();
118 
119         docModel.setModelEncoding( getProjectModelEncoding( project ) );
120         docModel.setOutputName( project == null || project.getArtifactId() == null
121                 ? "unnamed" : project.getArtifactId() );
122         docModel.setMeta( getDocumentMeta( project, now ) );
123         docModel.setCover( getDocumentCover( project, now ) );
124         docModel.setToc( getDocumentTOC( decorationModel ) );
125 
126         return docModel;
127     }
128 
129     /**
130      * Extract a DocumentTOC from a DecorationModel.
131      *
132      * @param decorationModel a DecorationModel. May be null.
133      * @return a DocumentTOC, always non-null.
134      */
135     private static DocumentTOC getDocumentTOC( DecorationModel decorationModel )
136     {
137         final DocumentTOC toc = new DocumentTOC();
138 
139         if ( decorationModel != null && decorationModel.getMenus() != null )
140         {
141             for ( final Menu menu  : decorationModel.getMenus() )
142             {
143                 for ( final MenuItem item : menu.getItems() )
144                 {
145                     final DocumentTOCItem documentTOCItem = new DocumentTOCItem();
146                     documentTOCItem.setName( item.getName() );
147                     documentTOCItem.setRef( item.getHref() );
148                     toc.addItem( documentTOCItem );
149                 }
150             }
151         }
152 
153         return toc;
154     }
155 
156     /**
157      * Extract meta information from a MavenProject.
158      *
159      * @param project a MavenProject. May be null.
160      * @param date the date to use in meta. May be null.
161      *
162      * @return a DocumentMeta object. Always non-null.
163      */
164     private static DocumentMeta getDocumentMeta( MavenProject project, Date date )
165     {
166         final DocumentMeta meta = new DocumentMeta();
167 
168         meta.setAuthors( getAuthors( project ) );
169         meta.setCreationDate( date );
170         meta.setCreator( System.getProperty( "user.name" ) );
171         meta.setDate( date );
172         meta.setDescription( project == null ? null : project.getDescription() );
173         //meta.setGenerator( generator );
174         meta.setInitialCreator( System.getProperty( "user.name" ) );
175         //meta.setLanguage( locale == null ? null : locale.getLanguage() );
176         //meta.setPageSize( pageSize );
177         meta.setSubject( getProjectName( project ) );
178         meta.setTitle( getProjectName( project ) );
179 
180         return meta;
181     }
182 
183     /**
184      * Extract information for a DocumentCover from a MavenProject.
185      *
186      * @param project a MavenProject. May be null.
187      * @param date the cover date. May be null.
188      *
189      * @return a DocumentCover object. Always non-null.
190      */
191     private static DocumentCover getDocumentCover( MavenProject project, Date date )
192     {
193         final DocumentCover cover = new DocumentCover();
194 
195         cover.setAuthors( getAuthors( project ) );
196         //cover.setCompanyLogo( companyLogo );
197         cover.setCompanyName( getProjectOrganizationName( project ) );
198         cover.setCoverDate( date );
199         cover.setCoverSubTitle( project == null ? null : "v. " + project.getVersion() );
200         cover.setCoverTitle( getProjectName( project ) );
201         //cover.setCoverType( type );
202         cover.setCoverVersion( project == null ? null : project.getVersion() );
203         //cover.setProjectLogo( projectLogo );
204         cover.setProjectName( getProjectName( project ) );
205 
206         return cover;
207     }
208 
209     /**
210      * Wrap the list of project {@link Developer} to a list of {@link DocumentAuthor}.
211      *
212      * @param project the MavenProject to extract the authors from.
213      * @return a list of DocumentAuthors from the project developers.
214      * Returns null if project is null or contains no developers.
215      */
216     private static List<DocumentAuthor> getAuthors( MavenProject project )
217     {
218         if ( project == null || project.getDevelopers() == null )
219         {
220             return null;
221         }
222 
223         final List<DocumentAuthor> ret = new ArrayList<DocumentAuthor>( 4 );
224 
225         for ( Object o : project.getDevelopers() )
226         {
227             final Developer developer = (Developer) o;
228 
229             final DocumentAuthor author = new DocumentAuthor();
230             author.setName( developer.getName() );
231             author.setEmail( developer.getEmail() );
232             author.setCompanyName( developer.getOrganization() );
233             StringBuilder roles = null;
234 
235             for ( final String role : developer.getRoles() )
236             {
237                 if ( roles == null )
238                 {
239                     roles = new StringBuilder( 32 );
240                 }
241                 else
242                 {
243                     roles.append( ',' ).append( ' ' );
244                 }
245                 roles.append( role );
246             }
247             if ( roles != null )
248             {
249                 author.setPosition( roles.toString() );
250             }
251 
252             ret.add( author );
253         }
254 
255         return ret;
256     }
257 
258     /**
259      * @param project the MavenProject to extract the project organization name from.
260      * @return the project organization name if not empty, or the current System user name otherwise.
261      */
262     private static String getProjectOrganizationName( MavenProject project )
263     {
264         if ( project != null && project.getOrganization() != null
265                 && StringUtils.isNotEmpty( project.getOrganization().getName() ) )
266         {
267             return project.getOrganization().getName();
268         }
269 
270         return System.getProperty( "user.name" );
271     }
272 
273     /**
274      * Extract the name of the project.
275      *
276      * @param project the MavenProject to extract the project name from.
277      * @return the project name, or the project groupId and artifactId if
278      * the project name is empty, or null if project is null.
279      */
280     private static String getProjectName( MavenProject project )
281     {
282         if ( project == null )
283         {
284             return null;
285         }
286 
287         if ( StringUtils.isEmpty( project.getName() ) )
288         {
289             return project.getGroupId() + ":" + project.getArtifactId();
290         }
291 
292         return project.getName();
293     }
294 
295     /**
296      * Extract the encoding.
297      *
298      * @param project the MavenProject to extract the encoding name from.
299      * @return the project encoding if defined, or UTF-8 otherwise, or null if project is null.
300      */
301     private static String getProjectModelEncoding( MavenProject project )
302     {
303         if ( project == null )
304         {
305             return null;
306         }
307 
308         String encoding = project.getModel().getModelEncoding();
309         // Workaround for MNG-4289
310         XmlStreamReader reader = null;
311         try
312         {
313             reader = new XmlStreamReader( project.getFile() );
314             encoding = reader.getEncoding();
315         }
316         catch ( IOException e )
317         {
318             // nop
319         }
320         finally
321         {
322             IOUtil.close( reader );
323         }
324 
325         if ( StringUtils.isEmpty( encoding ) )
326         {
327             return "UTF-8";
328         }
329 
330         return encoding;
331     }
332 }