Sharing org.simantics.acorn for everyone to use
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / internal / AcornDatabase.java
1 package org.simantics.acorn.internal;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.nio.file.DirectoryStream;
6 import java.nio.file.FileVisitOption;
7 import java.nio.file.FileVisitResult;
8 import java.nio.file.Files;
9 import java.nio.file.Path;
10 import java.nio.file.SimpleFileVisitor;
11 import java.nio.file.attribute.BasicFileAttributes;
12 import java.util.EnumSet;
13 import java.util.Properties;
14
15 import org.simantics.acorn.GraphClientImpl2;
16 import org.simantics.db.Database;
17 import org.simantics.db.DatabaseUserAgent;
18 import org.simantics.db.ServiceLocator;
19 import org.simantics.db.common.utils.Logger;
20 import org.simantics.db.server.ProCoreException;
21
22 /**
23  * @author Tuukka Lehtonen
24  */
25 public class AcornDatabase implements Database {
26
27     private final Path folder;
28
29     private DatabaseUserAgent userAgent;
30
31     public AcornDatabase(Path folder) {
32         this.folder = folder;
33     }
34
35     @Override
36     public DatabaseUserAgent getUserAgent() {
37         return userAgent;
38     }
39
40     @Override
41     public void setUserAgent(DatabaseUserAgent dbUserAgent) {
42         userAgent = dbUserAgent;
43     }
44
45     @Override
46     public Status getStatus() {
47         return Status.Local;
48     }
49
50     @Override
51     public File getFolder() {
52         return folder.toFile();
53     }
54
55     @Override
56     public boolean isFolderOk() {
57         return isFolderOk(folder.toFile());
58     }
59
60     @Override
61     public boolean isFolderOk(File aFolder) {
62         if (!aFolder.isDirectory())
63             return false;
64         return true;
65     }
66
67     @Override
68     public boolean isFolderEmpty() {
69         return isFolderEmpty(folder.toFile());
70     }
71
72     @Override
73     public boolean isFolderEmpty(File aFolder) {
74         Path path = aFolder.toPath();
75         if (!Files.isDirectory(path))
76             return false;
77         try (DirectoryStream<Path> folderStream = Files.newDirectoryStream(path)) {
78             return !folderStream.iterator().hasNext();
79         } catch (IOException e) {
80             Logger.defaultLogError("Failed to open folder stream. folder=" + path, e);
81             return false;
82         }
83     }
84
85     @Override
86     public void initFolder(Properties properties) throws ProCoreException {
87         try {
88             Files.createDirectories(folder);
89         } catch (IOException e) {
90             throw new ProCoreException(e);
91         }
92     }
93
94     @Override
95     public void deleteFiles() throws ProCoreException {
96         // TODO: somehow check that the acorn client is not active.
97         deleteTree(folder);
98     }
99
100     @Override
101     public void start() throws ProCoreException {
102     }
103
104     @Override
105     public boolean isRunning() throws ProCoreException {
106         return true;
107     }
108
109     @Override
110     public boolean tryToStop() throws ProCoreException {
111         return true;
112 //        throw new UnsupportedOperationException();
113     }
114
115     @Override
116     public void connect() throws ProCoreException {
117     }
118
119     @Override
120     public boolean isConnected() throws ProCoreException {
121         return true;
122     }
123
124     @Override
125     public String execute(String command) throws ProCoreException {
126         throw new UnsupportedOperationException("execute(" + command + ")");
127     }
128
129     @Override
130     public void disconnect() throws ProCoreException {
131     }
132
133     @Override
134     public void clone(File to, int revision, boolean saveHistory) throws ProCoreException {
135         // TODO: implement
136         throw new UnsupportedOperationException();
137     }
138
139     @Override
140     public Path createFromChangeSets(int revision) throws ProCoreException {
141         // TODO: implement
142         throw new UnsupportedOperationException();
143     }
144
145     @Override
146     public void deleteGuard() throws ProCoreException {
147         // TODO: implement
148         throw new UnsupportedOperationException();
149     }
150
151     @Override
152     public Path dumpChangeSets() throws ProCoreException {
153         // TODO: implement
154         throw new UnsupportedOperationException();
155     }
156
157     @Override
158     public void purgeDatabase() throws ProCoreException {
159         // TODO: implement
160         throw new UnsupportedOperationException();
161     }
162
163     @Override
164     public long serverGetTailChangeSetId() throws ProCoreException {
165         // "We have it all"
166         // But after purging we don't so beware.
167         // TODO: beware for purge
168         return 1;
169     }
170
171     @Override
172     public Session newSession(ServiceLocator locator) throws ProCoreException {
173         try {
174             return new GraphClientImpl2(this, folder, locator);
175         } catch (IOException e) {
176             throw new ProCoreException(e);
177         }
178     }
179
180     @Override
181     public Journal getJournal() throws ProCoreException {
182         // TODO: implement
183         throw new UnsupportedOperationException();
184     }
185
186     private static void deleteTree(Path path) throws ProCoreException {
187         if (!Files.exists(path))
188             return;
189
190         class Visitor extends SimpleFileVisitor<Path> {
191             @Override
192             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
193                 try {
194                     Files.delete(file);
195                 } catch (IOException ioe) {
196                     ioe.printStackTrace();
197                     throw ioe;
198                 }
199                 return FileVisitResult.CONTINUE;
200             }
201             @Override
202             public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
203                 if (e == null) {
204                     try {
205                         Files.delete(dir);
206                     } catch (IOException ioe) {
207                         ioe.printStackTrace();
208                         throw ioe;
209                     }
210                     return FileVisitResult.CONTINUE;
211                 }
212                 throw e;
213             }
214         }
215         try {
216             Visitor v = new Visitor();
217             EnumSet<FileVisitOption> opts = EnumSet.noneOf(FileVisitOption.class);
218             Files.walkFileTree(path, opts, Integer.MAX_VALUE, v);
219         } catch (IOException e) {
220             throw new ProCoreException("Could not delete " + path, e);
221         }
222     }
223
224         @Override
225         public String getCompression() {
226                 return "LZ4";
227         }
228
229 }