View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.pdf;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Date;
24  import java.util.List;
25  
26  import org.apache.commons.io.input.XmlStreamReader;
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.StringUtils;
39  
40  /**
41   * Construct a DocumentModel from a MavenProject and related information.
42   *
43   * @author ltheussl
44   */
45  public class DocumentModelBuilder {
46      /** A MavenProject to extract the information. */
47      private final MavenProject project;
48  
49      /** A DecorationModel to extract additional information. */
50      private final DecorationModel decorationModel;
51  
52      /**
53       * Constructor. Initialize a MavenProject to extract information from.
54       *
55       * @param project a MavenProject. May be null.
56       */
57      public DocumentModelBuilder(MavenProject project) {
58          this(project, null);
59      }
60  
61      /**
62       * Constructor. Initialize a MavenProject and a DecorationModel to extract information from.
63       *
64       * @param project a MavenProject. May be null.
65       * @param decorationModel a DecorationModel. May be null.
66       */
67      public DocumentModelBuilder(MavenProject project, DecorationModel decorationModel) {
68          this.project = project;
69          this.decorationModel = decorationModel;
70      }
71  
72      /**
73       * Get a DocumentModel.
74       *
75       * @return a DocumentModel. Always non-null.
76       */
77      public DocumentModel getDocumentModel() {
78          return getDocumentModel(project, decorationModel, null);
79      }
80  
81      /**
82       * Get a DocumentModel.
83       *
84       * @param date overrides the default date in meta- and cover information.
85       * @return a DocumentModel. Always non-null.
86       */
87      public DocumentModel getDocumentModel(Date date) {
88          return getDocumentModel(project, decorationModel, date);
89      }
90  
91      /**
92       * Extract a DocumentModel from a MavenProject.
93       *
94       * @param project a MavenProject. May be null.
95       * @param decorationModel a DecorationModel. May be null.
96       * @param date the date of the TOC. May be null in which case the build date will be used.
97       *
98       * @return a DocumentModel. Always non-null.
99       */
100     private static DocumentModel getDocumentModel(MavenProject project, DecorationModel decorationModel, Date date) {
101         final Date now = date == null ? new Date() : date;
102 
103         final DocumentModel docModel = new DocumentModel();
104 
105         docModel.setModelEncoding(getProjectModelEncoding(project));
106         docModel.setOutputName(
107                 project == null || project.getArtifactId() == null ? "unnamed" : project.getArtifactId());
108         docModel.setMeta(getDocumentMeta(project, now));
109         docModel.setCover(getDocumentCover(project, now));
110         docModel.setToc(getDocumentTOC(decorationModel));
111 
112         return docModel;
113     }
114 
115     /**
116      * Extract a DocumentTOC from a DecorationModel.
117      *
118      * @param decorationModel a DecorationModel. May be null.
119      * @return a DocumentTOC, always non-null.
120      */
121     private static DocumentTOC getDocumentTOC(DecorationModel decorationModel) {
122         final DocumentTOC toc = new DocumentTOC();
123 
124         if (decorationModel != null && decorationModel.getMenus() != null) {
125             for (final Menu menu : decorationModel.getMenus()) {
126                 for (final MenuItem item : menu.getItems()) {
127                     final DocumentTOCItem documentTOCItem = new DocumentTOCItem();
128                     documentTOCItem.setName(item.getName());
129                     documentTOCItem.setRef(item.getHref());
130                     toc.addItem(documentTOCItem);
131                 }
132             }
133         }
134 
135         return toc;
136     }
137 
138     /**
139      * Extract meta information from a MavenProject.
140      *
141      * @param project a MavenProject. May be null.
142      * @param date the date to use in meta. May be null.
143      *
144      * @return a DocumentMeta object. Always non-null.
145      */
146     private static DocumentMeta getDocumentMeta(MavenProject project, Date date) {
147         final DocumentMeta meta = new DocumentMeta();
148 
149         meta.setAuthors(getAuthors(project));
150         meta.setCreationDate(date);
151         meta.setCreator(System.getProperty("user.name"));
152         meta.setDate(date);
153         meta.setDescription(project == null ? null : project.getDescription());
154         // meta.setGenerator( generator );
155         meta.setInitialCreator(System.getProperty("user.name"));
156         // meta.setLanguage( locale == null ? null : locale.getLanguage() );
157         // meta.setPageSize( pageSize );
158         meta.setSubject(getProjectName(project));
159         meta.setTitle(getProjectName(project));
160 
161         return meta;
162     }
163 
164     /**
165      * Extract information for a DocumentCover from a MavenProject.
166      *
167      * @param project a MavenProject. May be null.
168      * @param date the cover date. May be null.
169      *
170      * @return a DocumentCover object. Always non-null.
171      */
172     private static DocumentCover getDocumentCover(MavenProject project, Date date) {
173         final DocumentCover cover = new DocumentCover();
174 
175         cover.setAuthors(getAuthors(project));
176         // cover.setCompanyLogo( companyLogo );
177         cover.setCompanyName(getProjectOrganizationName(project));
178         cover.setCoverDate(date);
179         cover.setCoverSubTitle(project == null ? null : "v. " + project.getVersion());
180         cover.setCoverTitle(getProjectName(project));
181         // cover.setCoverType( type );
182         cover.setCoverVersion(project == null ? null : project.getVersion());
183         // cover.setProjectLogo( projectLogo );
184         cover.setProjectName(getProjectName(project));
185 
186         return cover;
187     }
188 
189     /**
190      * Wrap the list of project {@link Developer} to a list of {@link DocumentAuthor}.
191      *
192      * @param project the MavenProject to extract the authors from.
193      * @return a list of DocumentAuthors from the project developers.
194      * Returns null if project is null or contains no developers.
195      */
196     private static List<DocumentAuthor> getAuthors(MavenProject project) {
197         if (project == null || project.getDevelopers() == null) {
198             return null;
199         }
200 
201         final List<DocumentAuthor> ret = new ArrayList<>(4);
202 
203         for (Developer developer : project.getDevelopers()) {
204             final DocumentAuthor author = new DocumentAuthor();
205             author.setName(developer.getName());
206             author.setEmail(developer.getEmail());
207             author.setCompanyName(developer.getOrganization());
208             StringBuilder roles = null;
209 
210             for (final String role : developer.getRoles()) {
211                 if (roles == null) {
212                     roles = new StringBuilder(32);
213                 } else {
214                     roles.append(',').append(' ');
215                 }
216                 roles.append(role);
217             }
218             if (roles != null) {
219                 author.setPosition(roles.toString());
220             }
221 
222             ret.add(author);
223         }
224 
225         return ret;
226     }
227 
228     /**
229      * @param project the MavenProject to extract the project organization name from.
230      * @return the project organization name if not empty, or the current System user name otherwise.
231      */
232     private static String getProjectOrganizationName(MavenProject project) {
233         if (project != null
234                 && project.getOrganization() != null
235                 && StringUtils.isNotEmpty(project.getOrganization().getName())) {
236             return project.getOrganization().getName();
237         }
238 
239         return System.getProperty("user.name");
240     }
241 
242     /**
243      * Extract the name of the project.
244      *
245      * @param project the MavenProject to extract the project name from.
246      * @return the project name, or the project groupId and artifactId if
247      * the project name is empty, or null if project is null.
248      */
249     private static String getProjectName(MavenProject project) {
250         if (project == null) {
251             return null;
252         }
253 
254         if (StringUtils.isEmpty(project.getName())) {
255             return project.getGroupId() + ":" + project.getArtifactId();
256         }
257 
258         return project.getName();
259     }
260 
261     /**
262      * Extract the encoding.
263      *
264      * @param project the MavenProject to extract the encoding name from.
265      * @return the project encoding if defined, or UTF-8 otherwise, or null if project is null.
266      */
267     private static String getProjectModelEncoding(MavenProject project) {
268         if (project == null) {
269             return null;
270         }
271 
272         String encoding = project.getModel().getModelEncoding();
273 
274         // Workaround for MNG-4289
275         try (XmlStreamReader reader = new XmlStreamReader(project.getFile())) {
276             encoding = reader.getEncoding();
277         } catch (IOException e) {
278             // nop
279         }
280 
281         if (encoding == null || encoding.isEmpty()) {
282             return "UTF-8";
283         }
284 
285         return encoding;
286     }
287 }