1 package org.simantics.acorn.internal;
4 import java.io.IOException;
5 import java.io.RandomAccessFile;
6 import java.nio.channels.FileLock;
7 import java.nio.file.DirectoryStream;
8 import java.nio.file.FileVisitOption;
9 import java.nio.file.FileVisitResult;
10 import java.nio.file.Files;
11 import java.nio.file.Path;
12 import java.nio.file.SimpleFileVisitor;
13 import java.nio.file.attribute.BasicFileAttributes;
14 import java.util.EnumSet;
15 import java.util.Properties;
17 import org.simantics.acorn.GraphClientImpl2;
18 import org.simantics.db.Database;
19 import org.simantics.db.DatabaseUserAgent;
20 import org.simantics.db.ServiceLocator;
21 import org.simantics.db.common.utils.Logger;
22 import org.simantics.db.exception.SDBException;
23 import org.simantics.db.server.DatabaseStartException;
24 import org.simantics.db.server.ProCoreException;
25 import org.simantics.db.server.internal.InternalException;
28 * @author Tuukka Lehtonen
30 public class AcornDatabase implements Database {
32 private final Path folder;
34 private GraphClientImpl2 currentClient;
36 private DatabaseUserAgent userAgent;
38 private RandomAccessFile raLockFile;
40 private FileLock lock;
42 private boolean isRunning;
44 public AcornDatabase(Path folder) {
49 public DatabaseUserAgent getUserAgent() {
54 public void setUserAgent(DatabaseUserAgent dbUserAgent) {
55 userAgent = dbUserAgent;
59 public Status getStatus() {
64 public File getFolder() {
65 return folder.toFile();
69 public boolean isFolderOk() {
70 return isFolderOk(folder.toFile());
74 public boolean isFolderOk(File aFolder) {
75 if (!aFolder.isDirectory())
81 public boolean isFolderEmpty() {
82 return isFolderEmpty(folder.toFile());
86 public boolean isFolderEmpty(File aFolder) {
87 Path path = aFolder.toPath();
88 if (!Files.isDirectory(path))
90 try (DirectoryStream<Path> folderStream = Files.newDirectoryStream(path)) {
91 return !folderStream.iterator().hasNext();
92 } catch (IOException e) {
93 Logger.defaultLogError("Failed to open folder stream. folder=" + path, e);
99 public void initFolder(Properties properties) throws ProCoreException {
101 Files.createDirectories(folder);
102 } catch (IOException e) {
103 throw new ProCoreException(e);
108 public void deleteFiles() throws ProCoreException {
113 public void start() throws ProCoreException {
114 Path lockFile = folder.resolve("lock");
116 if (!Files.exists(lockFile))
117 Files.createFile(lockFile);
119 raLockFile = new RandomAccessFile(lockFile.toFile(), "rw");
120 lock = raLockFile.getChannel().tryLock();
122 throw new ProCoreException("The database in folder " + folder.toAbsolutePath() + " is already in use!");
127 } catch (IOException e) {
133 public boolean isRunning() throws ProCoreException {
138 public boolean tryToStop() throws ProCoreException {
143 Files.deleteIfExists(folder.resolve("lock"));
147 } catch (IOException e) {
155 public void connect() throws ProCoreException {
159 public boolean isConnected() throws ProCoreException {
164 public String execute(String command) throws ProCoreException {
165 throw new UnsupportedOperationException("execute(" + command + ")");
169 public void disconnect() throws ProCoreException {
173 public void clone(File to, int revision, boolean saveHistory) throws ProCoreException {
175 throw new UnsupportedOperationException();
179 public Path createFromChangeSets(int revision) throws ProCoreException {
181 throw new UnsupportedOperationException();
185 public void deleteGuard() throws ProCoreException {
187 throw new UnsupportedOperationException();
191 public Path dumpChangeSets() throws ProCoreException {
193 throw new UnsupportedOperationException();
197 public void purgeDatabase() throws ProCoreException {
198 if(currentClient == null) throw new IllegalStateException("No current session.");
199 currentClient.purgeDatabase();
203 public long serverGetTailChangeSetId() throws ProCoreException {
204 if(currentClient == null) throw new IllegalStateException("No current session.");
205 return currentClient.getTailChangeSetId();
209 public Session newSession(ServiceLocator locator) throws ProCoreException {
211 if(currentClient != null) throw new DatabaseStartException(folder.toFile(), "A session is already running. Only one session is supported.");
212 currentClient = new GraphClientImpl2(this, folder, locator);
213 return currentClient;
214 } catch (IOException e) {
215 throw new ProCoreException(e);
220 public Journal getJournal() throws ProCoreException {
222 throw new UnsupportedOperationException();
225 private static void deleteTree(Path path) throws ProCoreException {
226 if (!Files.exists(path))
229 class Visitor extends SimpleFileVisitor<Path> {
231 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
234 } catch (IOException ioe) {
235 ioe.printStackTrace();
238 return FileVisitResult.CONTINUE;
241 public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
245 } catch (IOException ioe) {
246 ioe.printStackTrace();
249 return FileVisitResult.CONTINUE;
255 Visitor v = new Visitor();
256 EnumSet<FileVisitOption> opts = EnumSet.noneOf(FileVisitOption.class);
257 Files.walkFileTree(path, opts, Integer.MAX_VALUE, v);
258 } catch (IOException e) {
259 throw new ProCoreException("Could not delete " + path, e);
264 public String getCompression() {