View Javadoc

1   package org.apache.maven.plugins.help;
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.File;
23  import java.io.IOException;
24  import java.io.StringReader;
25  import java.io.StringWriter;
26  import java.io.Writer;
27  import java.text.DateFormat;
28  import java.text.SimpleDateFormat;
29  import java.util.ArrayList;
30  import java.util.Collections;
31  import java.util.Date;
32  import java.util.Iterator;
33  import java.util.LinkedHashSet;
34  import java.util.List;
35  import java.util.Properties;
36  import java.util.Set;
37  
38  import org.codehaus.plexus.util.IOUtil;
39  import org.codehaus.plexus.util.StringUtils;
40  import org.codehaus.plexus.util.WriterFactory;
41  import org.codehaus.plexus.util.xml.XMLWriter;
42  import org.codehaus.plexus.util.xml.XmlWriterUtil;
43  import org.jdom.Document;
44  import org.jdom.Element;
45  import org.jdom.JDOMException;
46  import org.jdom.Namespace;
47  import org.jdom.filter.ElementFilter;
48  import org.jdom.input.SAXBuilder;
49  import org.jdom.output.Format;
50  import org.jdom.output.XMLOutputter;
51  
52  /**
53   * Base class with common utilities to write effective Pom/settings.
54   * 
55   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
56   * @version $Id: AbstractEffectiveMojo.java 1446786 2013-02-15 21:54:28Z rfscholte $
57   * @since 2.1
58   */
59  public abstract class AbstractEffectiveMojo
60      extends AbstractHelpMojo
61  {
62      /** The POM XSD URL */
63      private static final String POM_XSD_URL = "http://maven.apache.org/maven-v4_0_0.xsd";
64  
65      /** The Settings XSD URL */
66      private static final String SETTINGS_XSD_URL = "http://maven.apache.org/xsd/settings-1.0.0.xsd";
67  
68      /**
69       * Utility method to write an XML content in a given file.
70       * 
71       * @param output is the wanted output file.
72       * @param content contains the XML content to be written to the file.
73       * @param encoding is the wanted encoding to use when writing file.
74       * @throws IOException if any
75       * @see AbstractHelpMojo#writeFile(File, String) if encoding is null.
76       */
77      protected static void writeXmlFile( File output, String content, String encoding )
78          throws IOException
79      {
80          if ( output == null )
81          {
82              return;
83          }
84  
85          if ( StringUtils.isEmpty( encoding ) )
86          {
87              writeFile( output, content );
88              return;
89          }
90  
91          Writer out = null;
92          try
93          {
94              output.getParentFile().mkdirs();
95  
96              out = WriterFactory.newXmlWriter( output );
97  
98              out.write( content );
99  
100             out.flush();
101         }
102         finally
103         {
104             IOUtil.close( out );
105         }
106     }
107 
108     /**
109      * Write comments in the Effective POM/settings header.
110      * 
111      * @param writer not null
112      */
113     protected static void writeHeader( XMLWriter writer )
114     {
115         XmlWriterUtil.writeCommentLineBreak( writer );
116         XmlWriterUtil.writeComment( writer, " " );
117         // Use ISO8601-format for date and time
118         DateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd'T'hh:mm:ss" );
119         XmlWriterUtil.writeComment( writer,
120                                     "Generated by Maven Help Plugin on "
121                                         + dateFormat.format( new Date( System.currentTimeMillis() ) ) );
122         XmlWriterUtil.writeComment( writer, "See: http://maven.apache.org/plugins/maven-help-plugin/" );
123         XmlWriterUtil.writeComment( writer, " " );
124         XmlWriterUtil.writeCommentLineBreak( writer );
125 
126         XmlWriterUtil.writeLineBreak( writer );
127     }
128 
129     /**
130      * Write comments in a normalize way.
131      * 
132      * @param writer not null
133      * @param comment not null
134      */
135     protected static void writeComment( XMLWriter writer, String comment )
136     {
137         XmlWriterUtil.writeCommentLineBreak( writer );
138         XmlWriterUtil.writeComment( writer, " " );
139         XmlWriterUtil.writeComment( writer, comment );
140         XmlWriterUtil.writeComment( writer, " " );
141         XmlWriterUtil.writeCommentLineBreak( writer );
142 
143         XmlWriterUtil.writeLineBreak( writer );
144     }
145 
146     /**
147      * Add a Pom/Settings namespaces to the effective XML content.
148      * 
149      * @param effectiveXml not null the effective POM or Settings
150      * @param isPom if <code>true</code> add the Pom xsd url, otherwise add the settings xsd url.
151      * @return the content of the root element, i.e. &lt;project/&gt; or &lt;settings/&gt; with the Maven namespace or
152      *         the original <code>effective</code> if an error occurred.
153      * @see #POM_XSD_URL
154      * @see #SETTINGS_XSD_URL
155      */
156     protected static String addMavenNamespace( String effectiveXml, boolean isPom )
157     {
158         SAXBuilder builder = new SAXBuilder();
159 
160         try
161         {
162             Document document = builder.build( new StringReader( effectiveXml ) );
163             Element rootElement = document.getRootElement();
164 
165             // added namespaces
166             Namespace pomNamespace = Namespace.getNamespace( "", "http://maven.apache.org/POM/4.0.0" );
167             rootElement.setNamespace( pomNamespace );
168 
169             Namespace xsiNamespace = Namespace.getNamespace( "xsi", "http://www.w3.org/2001/XMLSchema-instance" );
170             rootElement.addNamespaceDeclaration( xsiNamespace );
171             if ( rootElement.getAttribute( "schemaLocation", xsiNamespace ) == null )
172             {
173                 rootElement.setAttribute( "schemaLocation", "http://maven.apache.org/POM/4.0.0 "
174                     + ( isPom ? POM_XSD_URL : SETTINGS_XSD_URL ), xsiNamespace );
175             }
176 
177             ElementFilter elementFilter = new ElementFilter( Namespace.getNamespace( "" ) );
178             for ( Iterator<?> i = rootElement.getDescendants( elementFilter ); i.hasNext(); )
179             {
180                 Element e = (Element) i.next();
181                 e.setNamespace( pomNamespace );
182             }
183 
184             StringWriter w = new StringWriter();
185             Format format = Format.getPrettyFormat();
186             XMLOutputter out = new XMLOutputter( format );
187             out.output( document.getRootElement(), w );
188 
189             return w.toString();
190         }
191         catch ( JDOMException e )
192         {
193             return effectiveXml;
194         }
195         catch ( IOException e )
196         {
197             return effectiveXml;
198         }
199     }
200 
201     /**
202      * Properties which provides a sorted keySet().
203      */
204     protected static class SortedProperties
205         extends Properties
206     {
207         /** serialVersionUID */
208         static final long serialVersionUID = -8985316072702233744L;
209 
210         /** {@inheritDoc} */
211         @SuppressWarnings( { "rawtypes", "unchecked" } )
212         public Set<Object> keySet()
213         {
214             Set<Object> keynames = super.keySet();
215             List list = new ArrayList( keynames );
216             Collections.sort( list );
217 
218             return new LinkedHashSet<Object>( list );
219         }
220     }
221 }