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.server.ProCoreException;
25 * @author Tuukka Lehtonen
27 public class AcornDatabase implements Database {
29 private final Path folder;
31 private DatabaseUserAgent userAgent;
33 private RandomAccessFile raLockFile;
35 private FileLock lock;
37 private boolean isRunning;
39 public AcornDatabase(Path folder) {
44 public DatabaseUserAgent getUserAgent() {
49 public void setUserAgent(DatabaseUserAgent dbUserAgent) {
50 userAgent = dbUserAgent;
54 public Status getStatus() {
59 public File getFolder() {
60 return folder.toFile();
64 public boolean isFolderOk() {
65 return isFolderOk(folder.toFile());
69 public boolean isFolderOk(File aFolder) {
70 if (!aFolder.isDirectory())
76 public boolean isFolderEmpty() {
77 return isFolderEmpty(folder.toFile());
81 public boolean isFolderEmpty(File aFolder) {
82 Path path = aFolder.toPath();
83 if (!Files.isDirectory(path))
85 try (DirectoryStream<Path> folderStream = Files.newDirectoryStream(path)) {
86 return !folderStream.iterator().hasNext();
87 } catch (IOException e) {
88 Logger.defaultLogError("Failed to open folder stream. folder=" + path, e);
94 public void initFolder(Properties properties) throws ProCoreException {
96 Files.createDirectories(folder);
97 } catch (IOException e) {
98 throw new ProCoreException(e);
103 public void deleteFiles() throws ProCoreException {
108 public void start() throws ProCoreException {
109 Path lockFile = folder.resolve("lock");
111 if (!Files.exists(lockFile))
112 Files.createFile(lockFile);
114 raLockFile = new RandomAccessFile(lockFile.toFile(), "rw");
115 lock = raLockFile.getChannel().tryLock();
117 throw new ProCoreException("The database in folder " + folder.toAbsolutePath() + " is already in use!");
122 } catch (IOException e) {
128 public boolean isRunning() throws ProCoreException {
133 public boolean tryToStop() throws ProCoreException {
138 Files.deleteIfExists(folder.resolve("lock"));
142 } catch (IOException e) {
150 public void connect() throws ProCoreException {
154 public boolean isConnected() throws ProCoreException {
159 public String execute(String command) throws ProCoreException {
160 throw new UnsupportedOperationException("execute(" + command + ")");
164 public void disconnect() throws ProCoreException {
168 public void clone(File to, int revision, boolean saveHistory) throws ProCoreException {
170 throw new UnsupportedOperationException();
174 public Path createFromChangeSets(int revision) throws ProCoreException {
176 throw new UnsupportedOperationException();
180 public void deleteGuard() throws ProCoreException {
182 throw new UnsupportedOperationException();
186 public Path dumpChangeSets() throws ProCoreException {
188 throw new UnsupportedOperationException();
192 public void purgeDatabase() throws ProCoreException {
194 throw new UnsupportedOperationException();
198 public long serverGetTailChangeSetId() throws ProCoreException {
200 // But after purging we don't so beware.
201 // TODO: beware for purge
206 public Session newSession(ServiceLocator locator) throws ProCoreException {
208 return new GraphClientImpl2(this, folder, locator);
209 } catch (IOException e) {
210 throw new ProCoreException(e);
215 public Journal getJournal() throws ProCoreException {
217 throw new UnsupportedOperationException();
220 private static void deleteTree(Path path) throws ProCoreException {
221 if (!Files.exists(path))
224 class Visitor extends SimpleFileVisitor<Path> {
226 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
229 } catch (IOException ioe) {
230 ioe.printStackTrace();
233 return FileVisitResult.CONTINUE;
236 public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
240 } catch (IOException ioe) {
241 ioe.printStackTrace();
244 return FileVisitResult.CONTINUE;
250 Visitor v = new Visitor();
251 EnumSet<FileVisitOption> opts = EnumSet.noneOf(FileVisitOption.class);
252 Files.walkFileTree(path, opts, Integer.MAX_VALUE, v);
253 } catch (IOException e) {
254 throw new ProCoreException("Could not delete " + path, e);
259 public String getCompression() {