1   package eu.fbk.knowledgestore.runtime;
2   
3   import java.io.Closeable;
4   import java.io.IOException;
5   
6   /**
7    * A KnowledgeStore internal component.
8    * <p>
9    * This interface defines the basic API and lifecycle of a generic KnowledgeStore internal
10   * component, and is specialized for specific types of components.
11   * </p>
12   * <p>
13   * The <i>lifecycle</i> of a {@code Component} is the following:
14   * <ul>
15   * <li>The {@code Component} instance is created starting with a number of key/value properties
16   * and using one of the mechanisms supported by {@link Factory} (i.e., constructor, static factory
17   * method, builder pattern). The {@code Component} instance configures itself based on the
18   * supplied properties. In case the configuration is incorrect, an exception will be thrown;
19   * otherwise, the component is now configured, but still inactive, meaning that no activity is
20   * being carried out by the component, no persistent data is being modified and no resource that
21   * needs to be later freed is being allocated.</li>
22   * <li>Method {@link #init()} is called to initialize the {@code Component} instance and make it
23   * operational; differently from the constructor, method {@code init()} is allowed to allocate any
24   * resource, to modify persisted data and to start any task as necessary for the component to
25   * perform its tasks.</li>
26   * <li>Methods in the {@code Component} interface are called by external code (e.g., the
27   * frontend). Whether these methods can be called by a thread at a time (meaning the component can
28   * be thread-unsafe) or concurrently by multiple threads (meaning the component must be
29   * thread-safe) depends on the particular type of component, as documented in itsJavadoc.</li>
30   * <li>Method {@link #close()} is called to dispose the {@code Component} object, allowing it to
31   * free allocated resources (e.g., close files and network connections) in an orderly way. Note
32   * that method {@code close()} can be called at any time after the component has been instantiated
33   * (even before initialization, in case external failure requires the component to be immediately
34   * disposed). In particular, it is possible for the {@code close()} method to be called while a
35   * component method is being invoked by another thread.</li>
36   * </ul>
37   * </p>
38   * <p>
39   * Components are expected to access external resources (e.g., storage) or to communicate to
40   * external processes, hence methods in this interface and its specializations may throw
41   * {@link IOException}s. As a special kind of <tt>IOException</tt>, they may throw a
42   * {@link DataCorruptedException} in case a data corruption situation is detected, possibly
43   * triggering some external recovery procedure.
44   * </p>
45   */
46  public interface Component extends Closeable {
47  
48      /**
49       * Initializes the {@code Component} with the supplied {@code Runtime} object. This method is
50       * called after the instantiation of a {@code Component} and before any other instance method
51       * is called. It provides a {@code Runtime} that can be used to access runtime services such
52       * as locking, serialization and filesystem access. The {@code Component} is allowed to
53       * perform any initialization operation that is necessary in order to become functional; on
54       * failure, these operations may result in a {@link IOException} being thrown.
55       * 
56       * @throws IOException
57       *             in case initialization fails
58       * @throws IllegalStateException
59       *             in case the component has already been initialized or closed
60       */
61      void init() throws IOException, IllegalStateException;
62  
63      /**
64       * Closes this {@code Component} object. If the component has been initialized, closing a it
65       * causes any allocated resource to be freed and any operation or transaction ongoing within
66       * the component being aborted; in case the component has not been initialized yet, or
67       * {@code close()} has already being called, calling this method has no effect. Note that the
68       * operation affects only the local {@code Component} object and not any remote service this
69       * object may rely on to implement its functionalities; in particular, such a remote service
70       * is not shutdown by the operation, so that it can be accessed by other {@code Component}
71       * instances possibly running in other (virtual) machines. Similarly, closing a
72       * {@code Component} object has no impact on stored data, that continues to be persisted and
73       * will be accessed unchanged (provided no external modification occurs) the next time a
74       * similarly configured {@code Component} is created.
75       */
76      @Override
77      void close();
78  
79  }