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  
20  package org.apache.rat.walker;
21  
22  import java.io.BufferedInputStream;
23  import java.io.ByteArrayOutputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.nio.file.Path;
27  import java.util.ArrayList;
28  import java.util.Collection;
29  import java.util.List;
30  
31  import org.apache.commons.compress.archivers.ArchiveEntry;
32  import org.apache.commons.compress.archivers.ArchiveException;
33  import org.apache.commons.compress.archivers.ArchiveInputStream;
34  import org.apache.commons.compress.archivers.ArchiveStreamFactory;
35  import org.apache.commons.io.IOUtils;
36  import org.apache.rat.ReportConfiguration;
37  import org.apache.rat.api.Document;
38  import org.apache.rat.api.RatException;
39  import org.apache.rat.document.impl.ArchiveEntryDocument;
40  import org.apache.rat.report.RatReport;
41  import org.apache.rat.utils.Log;
42  
43  /**
44   * Walks various kinds of archives files
45   */
46  public class ArchiveWalker extends Walker {
47      private final Log log;
48  
49      /**
50       * Constructs a walker.
51       * @param config the report configuration for this run.
52       * @param document the document to process.
53       */
54      public ArchiveWalker(final ReportConfiguration config, final Document document) {
55          super(document, config.getFilesToIgnore());
56          this.log = config.getLog();
57      }
58  
59      /**
60       * Run a report over all files and directories in this GZIPWalker,
61       * ignoring any files/directories set to be ignored.
62       *
63       * @param report the defined RatReport to run on this GZIP walker.
64       *
65       */
66      public void run(final RatReport report) throws RatException {
67          for (Document document : getDocuments(log)) {
68              report.report(document);
69          }
70      }
71  
72      /**
73       * Creates an input stream from the Directory being walked.
74       * @return A buffered input stream reading the archive data.
75       * @throws IOException on error
76       */
77      private InputStream createInputStream() throws IOException {
78          return new BufferedInputStream(getDocument().inputStream());
79      }
80      /**
81       * Retrieves the documents from the archive.
82       * @param log The log to write messages to.
83       * @return A collection of documents that pass the file filter.
84       * @throws RatException on error.
85       */
86      public Collection<Document> getDocuments(final Log log) throws RatException {
87          List<Document> result = new ArrayList<>();
88          try (ArchiveInputStream<? extends ArchiveEntry> input = new ArchiveStreamFactory().createArchiveInputStream(createInputStream())) {
89              ArchiveEntry entry = null;
90              while ((entry = input.getNextEntry()) != null) {
91                  Path path = this.getDocument().getPath().resolve("#" + entry.getName());
92                  if (!entry.isDirectory() && this.isNotIgnored(path) && input.canReadEntryData(entry)) {
93                      ByteArrayOutputStream baos = new ByteArrayOutputStream();
94                      IOUtils.copy(input, baos);
95                      result.add(new ArchiveEntryDocument(path, baos.toByteArray()));
96                  }
97              }
98          } catch (ArchiveException e) {
99              log.warn(String.format("Unable to process %s: %s", getDocument().getName(), e.getMessage()));
100         } catch (IOException e) {
101             throw RatException.asRatException(e);
102         }
103         return result;
104     }
105 }