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  package org.apache.rat.api;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.InputStreamReader;
24  import java.io.Reader;
25  import java.nio.charset.Charset;
26  import java.util.SortedSet;
27  
28  import org.apache.rat.analysis.TikaProcessor;
29  import org.apache.rat.document.DocumentName;
30  import org.apache.rat.document.DocumentNameMatcher;
31  
32  /**
33   * The representation of a document being scanned.
34   */
35  public abstract class Document implements Comparable<Document> {
36  
37      /**
38       * An enumeration of document types.
39       */
40      public enum Type {
41          /** An archive type document. */
42          ARCHIVE,
43          /** A binary file. */
44          BINARY,
45          /** A generated document that is ignored. */
46          IGNORED,
47          /** A notice document (e.g. LICENSE file). */
48          NOTICE,
49          /** A standard document. */
50          STANDARD,
51          /** An unknown document type. */
52          UNKNOWN
53      }
54  
55      /** The path matcher used by this document */
56      protected final DocumentNameMatcher nameMatcher;
57      /** The metadata for this document */
58      private final MetaData metaData;
59      /** The fully qualified name of this document */
60      protected final DocumentName name;
61  
62      /**
63       * Creates an instance.
64       * @param name the native NameSet of the resource.
65       * @param nameMatcher the document name matcher to filter directories/files.
66       */
67      protected Document(final DocumentName name, final DocumentNameMatcher nameMatcher) {
68          this.name = name;
69          this.nameMatcher = nameMatcher;
70          this.metaData = new MetaData();
71      }
72  
73      /**
74       * Gets the name of the current document.
75       * @return the name of the current document.
76       */
77      public final DocumentName getName() {
78          return name;
79      }
80  
81      /**
82       * Gets the file filter this document was created with.
83       * @return the file filter this document was created with.
84       */
85      public final DocumentNameMatcher getNameMatcher() {
86          return nameMatcher;
87      }
88  
89      @Override
90      public int compareTo(final Document doc) {
91          return name.compareTo(doc.name);
92      }
93  
94      @Override
95      public int hashCode() {
96          return name.hashCode();
97      }
98  
99      @Override
100     public boolean equals(final Object obj) {
101         if (!(obj instanceof Document)) {
102             return false;
103         }
104         return name.equals(((Document) obj).name);
105     }
106 
107     /**
108      * Reads the contents of this document and
109      * relies on the charset detection of the underlying Tika processor.
110      *
111      * @return <code>Reader</code> not null
112      * @throws IOException if this document cannot be read.
113      */
114     public Reader reader() throws IOException {
115         final Charset charset = getMetaData().getCharset();
116         if (charset == null) {
117             throw new IOException(
118                     String.format(
119                             "No charset detected for document `%s`",
120                             getName()));
121         }
122 
123         return new InputStreamReader(
124                 TikaProcessor.markSupportedInputStream(inputStream()),
125                 charset);
126     }
127 
128     /**
129      * Streams the document's contents.
130      * @return a non-null input stream of the document.
131      * @throws IOException when stream could not be opened.
132      */
133     public abstract InputStream inputStream() throws IOException;
134 
135     /**
136      * Gets data describing this resource.
137      * @return a non-null MetaData object.
138      */
139     public final MetaData getMetaData() {
140         return metaData;
141     }
142 
143     /**
144      * Checks if document is ignored or not.
145      * @return {@code true} if the document is of type {@code IGNORED}.
146      */
147     public final boolean isIgnored() {
148         return Type.IGNORED == metaData.getDocumentType();
149     }
150 
151     /**
152      * Representations suitable for logging.
153      * @return a <code>String</code> representation
154      * of this object.
155      */
156     @Override
157     public String toString() {
158         return String.format("%s( name = %s metaData = %s )", this.getClass().getSimpleName(), getName().localized(), getMetaData());
159     }
160 
161     /**
162      * Determines if this document is a directory type.
163      * @return {@code true} if this is a directory.
164      */
165     public abstract boolean isDirectory();
166 
167     /**
168      * Gets a sorted set of documents that are children of this document.
169      * @return A sorted set of child Documents. May be empty.
170      */
171     public abstract SortedSet<Document> listChildren();
172 }