1   package eu.fbk.knowledgestore;
2   
3   import java.util.List;
4   
5   import javax.annotation.Nullable;
6   
7   import com.google.common.collect.Lists;
8   
9   import org.slf4j.Logger;
10  import org.slf4j.LoggerFactory;
11  
12  public abstract class AbstractKnowledgeStore implements KnowledgeStore {
13  
14      private static final Logger LOGGER = LoggerFactory.getLogger(AbstractKnowledgeStore.class);
15  
16      private final List<Session> sessions;
17  
18      private boolean closed;
19  
20      protected AbstractKnowledgeStore() {
21          this.sessions = Lists.newLinkedList();
22          this.closed = false;
23      }
24  
25      @Override
26      public final synchronized Session newSession() throws IllegalStateException {
27          return newSession(null, null);
28      }
29  
30      @Override
31      public final synchronized Session newSession(@Nullable final String username,
32              @Nullable final String password) throws IllegalStateException {
33          synchronized (this.sessions) {
34              evictClosedSessions();
35              final Session session = doNewSession(username, password);
36              this.sessions.add(session);
37              return session;
38          }
39      }
40  
41      @Override
42      public final synchronized void close() {
43          if (!this.closed) {
44              for (final Session session : this.sessions) {
45                  try {
46                      session.close();
47                  } catch (final Throwable ex) {
48                      LOGGER.error("Error closing session: " + ex.getMessage(), ex);
49                  }
50              }
51              try {
52                  doClose();
53              } finally {
54                  this.closed = true;
55              }
56          }
57      }
58  
59      @Override
60      public String toString() {
61          return getClass().getSimpleName() + "[" + (this.closed ? "closed" : "open") + ", "
62                  + this.sessions.size() + " sessions]";
63      }
64  
65      @Override
66      public final synchronized boolean isClosed() {
67          return this.closed;
68      }
69  
70      protected final void checkNotClosed() {
71          if (this.closed) {
72              throw new IllegalStateException("KnowledgeStore has been closed");
73          }
74      }
75  
76      protected final void evictClosedSessions() {
77          synchronized (this.sessions) {
78              for (int i = this.sessions.size() - 1; i >= 0; --i) {
79                  if (this.sessions.get(i).isClosed()) {
80                      this.sessions.remove(i);
81                  }
82              }
83          }
84      }
85  
86      protected abstract Session doNewSession(@Nullable String username, @Nullable String password);
87  
88      protected void doClose() {
89      }
90  
91  }