1 package org.simantics.internal;
4 import java.io.FileFilter;
5 import java.io.IOException;
6 import java.util.ArrayDeque;
7 import java.util.Collection;
9 import org.eclipse.core.runtime.IProgressMonitor;
10 import org.eclipse.core.runtime.IStatus;
11 import org.eclipse.core.runtime.Status;
12 import org.eclipse.core.runtime.jobs.Job;
13 import org.simantics.utils.FileService;
14 import org.simantics.utils.IOperation;
15 import org.simantics.utils.IOperationListener;
18 * @author Tuukka Lehtonen
20 public class FileServiceImpl implements FileService {
22 private static final long DELETION_DELAY_MS = 10000;
23 private static final long DELETION_ATTEMPT_INTERVAL_MS = 10000;
25 private static abstract class Op<R, E extends Exception> implements IOperation<R, E> {
26 protected boolean done;
28 @SuppressWarnings("unused")
29 protected E lastException;
32 public R waitFor() throws E {
37 } catch (InterruptedException e) {
45 public boolean isDone() {
50 public void addListener(IOperationListener<R, E> listener) {
51 throw new UnsupportedOperationException();
54 public abstract boolean tryExecute();
58 private static class Deletion extends Op<Boolean, IOException> {
65 public Deletion(File f, DeleteOption... options) {
67 parseOptions(options);
70 private void parseOptions(DeleteOption[] options) {
71 for (DeleteOption opt : options) {
72 if (opt instanceof EffortOption) {
73 effort = (EffortOption) opt;
79 public boolean tryExecute() {
81 if (tries > effort.maxTries) {
91 } catch (IOException e) {
98 public void deleteAll(File dir) throws IOException {
101 throw new IOException("Could not delete file: " + dir.getAbsolutePath());
104 if (dir.isDirectory()) {
105 File[] fs = dir.listFiles((FileFilter) null);
110 if (f.isDirectory()) {
114 throw new IOException("Could not delete file: " + f.getAbsolutePath());
120 throw new IOException("Could not delete directory: " + dir.getAbsolutePath());
122 } else if (dir.exists()) {
124 throw new IOException("Could not delete file: " + dir.getAbsolutePath());
131 private ArrayDeque<Deletion> deletionQueue = new ArrayDeque<Deletion>();
132 private DeletionJob deletionJob = new DeletionJob();
135 public IOperation<Boolean, IOException> scheduleDeleteIfExists(File file, DeleteOption... options) {
138 synchronized (deletionQueue) {
139 Deletion d = new Deletion(file, options);
140 if (deletionQueue.contains(d))
142 deletionQueue.addLast(d);
143 deletionJob.schedule(DELETION_DELAY_MS);
148 class DeletionJob extends Job {
150 public DeletionJob() {
151 super("File background deletion");
154 @SuppressWarnings("unchecked")
155 private <O extends Op<?,?>> void process(Collection<O> ops) {
156 Object[] opa = ops.toArray();
157 for (int i = 0; i < opa.length; ++i) {
159 if (op.tryExecute()) {
160 // Success. Will be removed from queue.
166 for (int i = 0; i < opa.length; ++i) {
174 protected IStatus run(IProgressMonitor monitor) {
175 process(deletionQueue);
176 if (!deletionQueue.isEmpty())
177 schedule(DELETION_ATTEMPT_INTERVAL_MS);
178 return Status.OK_STATUS;