View Javadoc

1   /*
2    * Copyright 2006-2012 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.maven.plugin.buildmetadata.io;
17  
18  import java.io.BufferedOutputStream;
19  import java.io.File;
20  import java.io.FileNotFoundException;
21  import java.io.FileOutputStream;
22  import java.io.IOException;
23  import java.io.OutputStream;
24  import java.util.List;
25  import java.util.Properties;
26  
27  import javax.xml.parsers.DocumentBuilder;
28  import javax.xml.parsers.DocumentBuilderFactory;
29  import javax.xml.parsers.ParserConfigurationException;
30  import javax.xml.transform.TransformerException;
31  
32  import org.apache.commons.io.IOUtils;
33  import org.apache.maven.plugin.MojoExecutionException;
34  import org.apache.maven.plugin.logging.Log;
35  import org.w3c.dom.Document;
36  
37  import de.smartics.maven.io.MojoIoUtils;
38  import de.smartics.maven.plugin.buildmetadata.common.MojoUtils;
39  import de.smartics.maven.plugin.buildmetadata.common.Property;
40  
41  /**
42   * Helper to handle the build meta data properties file.
43   *
44   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
45   * @version $Revision:591 $
46   */
47  public final class BuildXmlFileHelper
48  {
49    // ********************************* Fields *********************************
50  
51    // --- constants ------------------------------------------------------------
52  
53    // --- members --------------------------------------------------------------
54  
55    /**
56     * The logger to use.
57     */
58    private final Log log;
59  
60    /**
61     * The file to write to.
62     */
63    private final File xmlOutputFile;
64  
65    /**
66     * The list of a system properties or environment variables to be selected by
67     * the user to include into the build meta data properties.
68     * <p>
69     * The name is the name of the property, the section is relevant for placing
70     * the property in one of the following sections:
71     * </p>
72     * <ul>
73     * <li><code>build.scm</code></li>
74     * <li><code>build.dateAndVersion</code></li>
75     * <li><code>build.runtime</code></li>
76     * <li><code>build.java</code></li>
77     * <li><code>build.maven</code></li>
78     * <li><code>build.misc</code></li>
79     * </ul>
80     * <p>
81     * If no valid section is given, the property is silently rendered in the
82     * <code>build.misc</code> section.
83     * </p>
84     */
85    private final List<Property> selectedProperties;
86  
87    // ****************************** Initializer *******************************
88  
89    // ****************************** Constructors ******************************
90  
91    /**
92     * Default constructor.
93     *
94     * @param log the logger to use.
95     * @param xmlOutputFile the file to write to.
96     * @param selectedProperties the list of a system properties or environment
97     *          variables to be selected by the user to include into the build
98     *          meta data properties.
99     */
100   public BuildXmlFileHelper(final Log log, final File xmlOutputFile,
101       final List<Property> selectedProperties)
102   {
103     this.log = log;
104     this.xmlOutputFile = xmlOutputFile;
105     this.selectedProperties = selectedProperties;
106   }
107 
108   // ****************************** Inner Classes *****************************
109 
110   // ********************************* Methods ********************************
111 
112   // --- init -----------------------------------------------------------------
113 
114   // --- get&set --------------------------------------------------------------
115 
116   // --- business -------------------------------------------------------------
117 
118   /**
119    * Writes the build meta data XML file to the target file.
120    *
121    * @param buildMetaDataProperties the properties to write.
122    * @return the reference to the written file.
123    * @throws MojoExecutionException on any problem encountered while writing the
124    *           XML file.
125    */
126   public File writeXmlFile(final Properties buildMetaDataProperties)
127     throws MojoExecutionException
128   {
129     final File buildMetaDataFile = createBuildMetaDataFile(xmlOutputFile);
130     if (log.isInfoEnabled())
131     {
132       log.info("Writing XML report '" + buildMetaDataFile.getAbsolutePath()
133                + "'...");
134     }
135 
136     writeContent(buildMetaDataProperties, buildMetaDataFile);
137 
138     return buildMetaDataFile;
139   }
140 
141   private void writeContent(final Properties buildMetaDataProperties,
142       final File buildMetaDataFile) throws MojoExecutionException
143   {
144     OutputStream out = null;
145     try
146     {
147       out = new BufferedOutputStream(new FileOutputStream(buildMetaDataFile));
148       serializeDocument(buildMetaDataProperties, out);
149     }
150     catch (final FileNotFoundException e)
151     {
152       final String message =
153           "Cannot find file '" + buildMetaDataFile
154               + "' to write XML report to.";
155       throw MojoUtils.createException(log, e, message);
156     }
157     catch (final IOException e)
158     {
159       final String message =
160           "Cannot write XML report to file '" + buildMetaDataFile + "'.";
161       throw MojoUtils.createException(log, e, message);
162     }
163     catch (final ParserConfigurationException e)
164     {
165       final String message =
166           "Cannot create XML report to write to file '" + buildMetaDataFile
167               + "'.";
168       throw MojoUtils.createException(log, e, message);
169     }
170     catch (final TransformerException e)
171     {
172       final String message =
173           "Cannot transform build meta data to XML to write to file '"
174               + buildMetaDataFile + "'.";
175       throw MojoUtils.createException(log, e, message);
176     }
177     finally
178     {
179       IOUtils.closeQuietly(out);
180     }
181   }
182 
183   private void serializeDocument(final Properties buildMetaDataProperties,
184       final OutputStream out) throws ParserConfigurationException, IOException,
185     TransformerException
186   {
187     final Document document = createDocument();
188     final SdocBuilder builder =
189         new SdocBuilder(document, buildMetaDataProperties, selectedProperties);
190     builder.writeDocumentContent();
191     MojoIoUtils.serialize(document, out);
192   }
193 
194   /**
195    * Creates the properties file for the build meta data. If the directory to
196    * place it in is not present, it will be created.
197    *
198    * @return the file to write the build properties to.
199    * @throws MojoExecutionException if the output directory is not present and
200    *           cannot be created.
201    */
202   private File createBuildMetaDataFile(final File propertiesOutputFile)
203     throws MojoExecutionException
204   {
205     final File outputDirectory = propertiesOutputFile.getParentFile();
206     if (!outputDirectory.exists())
207     {
208       final boolean created = outputDirectory.mkdirs();
209       if (!created)
210       {
211         throw new MojoExecutionException("Cannot create output directory '"
212                                          + outputDirectory + "'.");
213       }
214     }
215     return propertiesOutputFile;
216   }
217 
218   private Document createDocument() throws ParserConfigurationException
219   {
220     final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
221     final DocumentBuilder builder = factory.newDocumentBuilder();
222     final Document document = builder.newDocument();
223     return document;
224   }
225 
226   // --- object basics --------------------------------------------------------
227 
228 }