View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.rat.anttasks;
18  
19  import org.apache.commons.io.IOUtils;
20  import org.apache.tools.ant.BuildException;
21  import org.junit.Assert;
22  
23  import java.io.BufferedReader;
24  import java.io.File;
25  import java.io.FileInputStream;
26  import java.io.IOException;
27  import java.io.InputStreamReader;
28  import java.lang.reflect.Field;
29  import java.nio.charset.Charset;
30  import javax.xml.parsers.DocumentBuilder;
31  import javax.xml.parsers.DocumentBuilderFactory;
32  import org.apache.rat.document.impl.guesser.BinaryGuesser;
33  import org.w3c.dom.Document;
34  
35  public class ReportTest extends AbstractRatAntTaskTest {
36      private static final File antFile = new File("src/test/resources/antunit/report-junit.xml").getAbsoluteFile();
37  
38      @Override
39      protected File getAntFile() {
40          return antFile;
41      }
42  
43      public void testWithReportSentToAnt() throws Exception {
44          executeTarget("testWithReportSentToAnt");
45          assertLogMatches("AL +\\Q" + getAntFileName() + "\\E");
46      }
47  
48      public void testWithReportSentToFile() throws Exception {
49          final File reportFile = new File(getTempDir(), "selftest.report");
50          if (!getTempDir().mkdirs() && !getTempDir().isDirectory()) {
51              throw new IOException("Could not create temporary directory " + getTempDir());
52          }
53          final String alLine = "AL +\\Q" + getAntFileName() + "\\E";
54          if (reportFile.isFile() && !reportFile.delete()) {
55              throw new IOException("Unable to remove report file " + reportFile);
56          }
57          executeTarget("testWithReportSentToFile");
58          assertLogDoesNotMatch(alLine);
59          Assert.assertTrue("Expected report file " + reportFile, reportFile.isFile());
60          assertFileMatches(reportFile, alLine);
61      }
62  
63      public void testWithALUnknown() throws Exception {
64          executeTarget("testWithALUnknown");
65          assertLogDoesNotMatch("AL +\\Q" + getAntFileName() + "\\E");
66          assertLogMatches("\\!\\?\\?\\?\\?\\? +\\Q" + getAntFileName() + "\\E");
67      }
68  
69      public void testCustomMatcher() throws Exception {
70          executeTarget("testCustomMatcher");
71          assertLogDoesNotMatch("AL +\\Q" + getAntFileName() + "\\E");
72          assertLogMatches("EXMPL +\\Q" + getAntFileName() + "\\E");
73      }
74  
75      public void testNoResources() throws Exception {
76          try {
77              executeTarget("testNoResources");
78              fail("Expected Exception");
79          } catch (BuildException e) {
80              final String expect = "You must specify at least one file";
81              assertTrue("Expected " + expect + ", got " + e.getMessage(),
82                      e.getMessage().contains(expect));
83          }
84      }
85  
86      public void testNoLicenseMatchers() throws Exception {
87          try {
88              executeTarget("testNoLicenseMatchers");
89              fail("Expected Exception");
90          } catch (BuildException e) {
91              final String expect = "at least one license";
92              assertTrue("Expected " + expect + ", got " + e.getMessage(),
93                      e.getMessage().contains(expect));
94          }
95      }
96  
97      private String getAntFileName() {
98          return getAntFile().getPath().replace('\\', '/');
99      }
100 
101     private String getFirstLine(File pFile) throws IOException {
102         FileInputStream fis = null;
103         InputStreamReader reader = null;
104         BufferedReader breader = null;
105         try {
106             fis = new FileInputStream(pFile);
107             reader = new InputStreamReader(fis, "UTF8");
108             breader = new BufferedReader(reader);
109             final String result = breader.readLine();
110             breader.close();
111             return result;
112         } finally {
113             IOUtils.closeQuietly(fis);
114             IOUtils.closeQuietly(reader);
115             IOUtils.closeQuietly(breader);
116         }
117     }
118 
119     public void testAddLicenseHeaders() throws Exception {
120         executeTarget("testAddLicenseHeaders");
121 
122         final File origFile = new File("target/anttasks/it-sources/index.apt");
123         final String origFirstLine = getFirstLine(origFile);
124         assertTrue(origFirstLine.contains("--"));
125         assertFalse(origFirstLine.contains("~~"));
126         final File modifiedFile = new File("target/anttasks/it-sources/index.apt.new");
127         final String modifiedFirstLine = getFirstLine(modifiedFile);
128         assertFalse(modifiedFirstLine.contains("--"));
129         assertTrue(modifiedFirstLine.contains("~~"));
130     }
131 
132     /**
133      * Test correct generation of string result if non-UTF8 file.encoding is set.
134      */
135     public void testISO88591() throws Exception {
136         String origEncoding = overrideFileEncoding("ISO-8859-1");
137         executeTarget("testISO88591");
138         overrideFileEncoding(origEncoding);
139         assertTrue("Log should contain the test umlauts", getLog().contains("\u00E4\u00F6\u00FC\u00C4\u00D6\u00DC\u00DF"));
140     }
141 
142     /**
143      * Test correct generation of XML file if non-UTF8 file.encoding is set.
144      */
145     public void testISO88591WithFile() throws Exception {
146         Charset.defaultCharset();
147         String outputDir = System.getProperty("output.dir", "target/anttasks");
148         String selftestOutput = System.getProperty("report.file", outputDir + "/selftest.report");
149         String origEncoding = overrideFileEncoding("ISO-8859-1");
150         executeTarget("testISO88591WithReportFile");
151         overrideFileEncoding(origEncoding);
152         DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
153         FileInputStream fis = new FileInputStream(selftestOutput);
154         boolean documentParsed = false;
155         try {
156             Document doc = db.parse(fis);
157             boolean byteSequencePresent = doc.getElementsByTagName("header-sample")
158                     .item(0)
159                     .getTextContent()
160                     .contains("\u00E4\u00F6\u00FC\u00C4\u00D6\u00DC\u00DF");
161             assertTrue("Report should contain test umlauts", byteSequencePresent);
162             documentParsed = true;
163         } catch (Exception ex) {
164             documentParsed = false;
165         } finally {
166             fis.close();
167         }
168         assertTrue("Report file could not be parsed as XML", documentParsed);
169     }
170 
171     private String overrideFileEncoding(String newEncoding) {
172         String current = System.getProperty("file.encoding");
173         System.setProperty("file.encoding", newEncoding);
174         setBinaryGuesserCharset(newEncoding);
175         clearDefaultCharset();
176         return current;
177     }
178 
179     private void clearDefaultCharset() {
180         try {
181             Field f = Charset.class.getDeclaredField("defaultCharset");
182             f.setAccessible(true);
183             f.set(null, null);
184         } catch (Exception ex) {
185             // This is for unittesting - there is no good reason not to rethrow
186             // it. This could be happening in JDK 9, where the unittests need
187             // run with the java.base module opened
188             throw new RuntimeException(ex);
189         }
190     }
191 
192     private void setBinaryGuesserCharset(String charset) {
193         try {
194             Field f = BinaryGuesser.class.getDeclaredField("CHARSET_FROM_FILE_ENCODING_OR_UTF8");
195             f.setAccessible(true);
196             f.set(null, Charset.forName(charset));
197         } catch (Exception ex) {
198             // This is for unittesting - there is no good reason not to rethrow
199             // it. This could be happening in JDK 9, where the unittests need
200             // run with the java.base module opened
201             throw new RuntimeException(ex);
202         }
203     }
204 }