View Javadoc

1   package org.codehaus.mojo.rat;
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.FileOutputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.PrintWriter;
27  import java.io.StringReader;
28  import java.io.StringWriter;
29  import java.net.URL;
30  
31  import javax.xml.parsers.DocumentBuilderFactory;
32  import javax.xml.parsers.ParserConfigurationException;
33  import javax.xml.transform.Transformer;
34  import javax.xml.transform.TransformerException;
35  import javax.xml.transform.TransformerFactory;
36  import javax.xml.transform.dom.DOMSource;
37  import javax.xml.transform.stream.StreamResult;
38  import javax.xml.transform.stream.StreamSource;
39  
40  import org.apache.maven.plugin.MojoExecutionException;
41  import org.apache.maven.plugin.MojoFailureException;
42  import org.w3c.dom.Document;
43  import org.w3c.dom.Element;
44  import org.w3c.dom.Node;
45  import org.xml.sax.InputSource;
46  import org.xml.sax.SAXException;
47  
48  import rat.Defaults;
49  
50  /**
51   * Run RAT to perform a violation check.
52   * 
53   * @goal check
54   * @phase verify
55   */
56  public class RatCheckMojo extends AbstractRatMojo
57  {
58      /**
59       * Where to store the report.
60       * 
61       * @parameter expression="${rat.outputFile}" default-value="${project.build.directory}/rat.txt"
62       */
63      private File reportFile;
64  
65      /**
66       * Maximum number of files with unapproved licenses.
67       * @parameter expression="${rat.numUnapprovedLicenses}" default-value="0"
68       */
69      private int numUnapprovedLicenses;
70      
71      private URL getStylesheetURL()
72      {
73          URL url = Thread.currentThread().getContextClassLoader().getResource( "org/codehaus/mojo/rat/identity.xsl" );
74          if ( url == null )
75          {
76              throw new IllegalStateException( "Failed to locate stylesheet" );
77          }
78          return url;
79      }
80  
81      private Document getRawReport()
82          throws MojoExecutionException, MojoFailureException
83      {
84          URL url = getStylesheetURL();
85          InputStream style = null;
86          try
87          {
88              style = url.openStream();
89              final StringWriter sw = new StringWriter();
90              createReport( new PrintWriter( sw ), style );
91              style.close();
92              style = null;
93              DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
94              dbf.setNamespaceAware( true );
95              dbf.setValidating( false );
96              return dbf.newDocumentBuilder().parse( new InputSource( new StringReader( sw.toString() ) ) );
97          }
98          catch ( IOException e )
99          {
100             throw new MojoExecutionException( e.getMessage(), e );
101         }
102         catch ( SAXException e )
103         {
104             throw new MojoExecutionException( e.getMessage(), e );
105         }
106         catch ( ParserConfigurationException e )
107         {
108             throw new MojoExecutionException( e.getMessage(), e );
109         }
110         finally
111         {
112             if ( style != null )
113             {
114                 try
115                 {
116                     style.close();
117                 }
118                 catch ( Throwable t )
119                 {
120                     /* Ignore me */
121                 }
122             }
123         }
124     }
125 
126     /**
127      * Invoked by Maven to execute the Mojo.
128      * 
129      * @throws MojoFailureException
130      *             An error in the plugin configuration was detected.
131      * @throws MojoExecutionException
132      *             Another error occurred while executing the plugin.
133      */
134     public void execute() throws MojoExecutionException, MojoFailureException
135     {
136         File parent = reportFile.getParentFile();
137         parent.mkdirs();
138 
139         final Document report = getRawReport();
140         FileOutputStream fos = null;
141         try
142         {
143             fos = new FileOutputStream( reportFile );
144             Transformer t = TransformerFactory.newInstance().newTransformer( new StreamSource( Defaults.getDefaultStyleSheet() ) );
145             t.transform( new DOMSource( report ), new StreamResult( fos ) );
146             fos.close();
147             fos = null;
148         }
149         catch ( TransformerException e )
150         {
151             throw new MojoExecutionException( "Failed to create file " + reportFile + ": " + e.getMessage(), e );
152         }
153         catch ( IOException e )
154         {
155             throw new MojoExecutionException( "Failed to create file " + reportFile + ": " + e.getMessage(), e );
156         }
157         finally
158         {
159             if ( fos != null )
160             {
161                 try
162                 {
163                     fos.close();
164                 }
165                 catch ( Throwable t )
166                 {
167                     // Ignore me
168                 }
169             }
170         }
171 
172         check( report );
173     }
174 
175     
176     private void count( RatStatistics pStatistics, Node node )
177     {
178         for ( Node child = node.getFirstChild();  child != null;  child = child.getNextSibling() )
179         {
180             switch ( child.getNodeType() )
181             {
182                 case Node.ELEMENT_NODE:
183                     final Element e = (Element) child;
184                     final String uri = e.getNamespaceURI();
185                     if ( uri == null  ||  uri.length() == 0 )
186                     {
187                         final String localName = e.getLocalName();
188                         if ( "license-approval".equals( localName ) )
189                         {
190                             if ( Boolean.valueOf( e.getAttribute( "name" ) ).booleanValue() )
191                             {
192                                 pStatistics.setNumApprovedLicenses( pStatistics.getNumApprovedLicenses() + 1 );
193                             }
194                             else
195                             {
196                                 pStatistics.setNumUnapprovedLicenses( pStatistics.getNumUnapprovedLicenses() + 1 );
197                             }
198                         }
199                     }
200                     count( pStatistics, child );
201                     break;
202                 case Node.DOCUMENT_FRAGMENT_NODE:
203                     count( pStatistics, child );
204                     break;
205                 default:
206                     break;
207             }
208         }
209     }
210 
211     protected void check( Document document )
212         throws MojoFailureException
213     {
214         RatStatistics statistics = new RatStatistics();
215         count( statistics, document );
216         check( statistics );
217     }
218 
219     protected void check( RatStatistics statistics )
220         throws MojoFailureException
221     {
222         if ( numUnapprovedLicenses < statistics.getNumUnapprovedLicenses() )
223         {
224             throw new RatCheckException( "Too many unapproved licenses: " + statistics.getNumApprovedLicenses() );
225         }
226     }
227 }