1   package eu.fbk.knowledgestore.filestore;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
5   import java.io.OutputStream;
6   
7   import eu.fbk.knowledgestore.data.Stream;
8   import eu.fbk.knowledgestore.runtime.Component;
9   
10  /**
11   * A storage for resource files, supporting CRUD operations.
12   * <p>
13   * A {@code FileStore} abstracts the way resource files are stored in the KnowledgeStore allowing
14   * different implementations to be plugged in. A {@code FileStore} stores a list of files each
15   * identified by a filename, with no (visible) directory structure. Files can be listed (
16   * {@link #list()}), written ({@link #write(String)}), read ( {@link #read(String)}) or deleted (
17   * {@link #delete(String)}), but not modified after they are written the first time. Note that a
18   * {@code FileStore} obeys the general contract and lifecycle of {@link Component}.
19   * </p>
20   */
21  public interface FileStore extends Component {
22  
23      /**
24       * Read a file stored on the {@code FileStore}. The method returns an {@code InputStream} over
25       * the content of the file, starting from its first byte. Sequential access and forward
26       * seeking ( {@link InputStream#skip(long)}) are supported. Note that multiple concurrent read
27       * operations on the same file are allowed.
28       * 
29       * @param filename
30       *            the name of the file
31       * @return an {@code InputStream} allowing access to the content of the file
32       * @throws FileMissingException
33       *             in case no file exists for the name specified, resulting either from a caller
34       *             error or from an external modification (deletion) to the {@code FileStore}
35       * @throws IOException
36       *             in case the file cannot be accessed for whatever reason, with no implication on
37       *             the fact that the file exists or does not exist (e.g., the whole
38       *             {@code FileStore} may temporarily be not accessible)
39       */
40      InputStream read(String filename) throws FileMissingException, IOException;
41  
42      /**
43       * Writes a new file to the {@code FileStore}. The method creates a file with the name
44       * specified, and returns an {@code OutputStream} that can be used to write the content of the
45       * file. Writing is completed by closing that stream, which forces written data to be flushed
46       * to disk; errors in writing the file may result in the stream being forcedly closed and a
47       * truncated file to be written. The file being written may be listed by {@link #list()}
48       * (depending on the {@code FileStore} implementation) but should not be accessed for read or
49       * deletion until writing is completed; the consequences of doing so are not specified.
50       * 
51       * @param filename
52       *            the name of the file
53       * @return an {@code OutputStream} where the content of the file can be written to
54       * @throws FileExistsException
55       *             in case a file with the same name already exists, resulting either from a
56       *             caller error or from an external modification (file creation) to the
57       *             {@code FileStore}.
58       * @throws IOException
59       *             in case the file cannot be created for whatever reason, with no implication on
60       *             the fact that another file with the same name already exists
61       */
62      OutputStream write(String filename) throws FileExistsException, IOException;
63  
64      /**
65       * Deletes a file on the {@code FileStore}. An exception is thrown if the file specified does
66       * not exist. After the method returns, the file cannot be accessed anymore from
67       * {@link #read(String)} or {@link #delete(String)}. Deleting a file being read is allowed and
68       * eventually results in the deletion of the file; whether the concurrent read operation fails
69       * or is permitted to complete is an implementation detail.
70       * 
71       * @param filename
72       *            the name of the file
73       * @throws FileMissingException
74       *             in case the file specified does not exist, possibly because of an external
75       *             modification to the {@code FileStore}
76       * @throws IOException
77       *             in case the file cannot be accessed for whatever reason, with no implication on
78       *             the fact that the file specified actually exists
79       */
80      void delete(String filename) throws FileMissingException, IOException;
81  
82      /**
83       * Lists all the files stored on the {@code FileStore}. The method returns a {@code Stream}
84       * supporting streaming access to the names of the files stored in the {@code FileStore}.
85       * Concurrent modifications to the {@code FileStore} ({@link #write(String)},
86       * {@link #delete(String)}) may be supported, depending on the implementation: in that case,
87       * the stream may either reflect the status before or after the concurrent modification.
88       * 
89       * @return a stream over the names of the files stored in the {@code FileStore}
90       * @throws IOException
91       *             in case of failure, for whatever reason
92       */
93      Stream<String> list() throws IOException;
94  
95  }