]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Merge "(refs #7102) Fixed comparator NodeEventHandler.TreePreOrderComparator"
authorHannu Niemistö <hannu.niemisto@semantum.fi>
Tue, 21 Mar 2017 08:33:45 +0000 (10:33 +0200)
committerGerrit Code Review <gerrit2@www.simantics.org>
Tue, 21 Mar 2017 08:33:45 +0000 (10:33 +0200)
17 files changed:
bundles/org.simantics.charts/src/org/simantics/charts/Charts.java
bundles/org.simantics.charts/src/org/simantics/charts/TrendSupport.java
bundles/org.simantics.db.indexing/src/org/simantics/db/indexing/DatabaseIndexing.java
bundles/org.simantics.db.indexing/src/org/simantics/db/indexing/IndexedRelationsImpl.java
bundles/org.simantics.db.indexing/src/org/simantics/db/indexing/internal/IndexChangedWriter.java [new file with mode: 0644]
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java
bundles/org.simantics.diagram/src/org/simantics/diagram/symbollibrary/ui/SymbolLibraryComposite.java
bundles/org.simantics.history/src/org/simantics/history/HistorySampler.java
bundles/org.simantics.modeling/scl/Simantics/Simulation.scl
bundles/org.simantics.project/src/org/simantics/project/ProjectFeatures.java
bundles/org.simantics.project/src/org/simantics/project/internal/ProjectFeatureRegistry.java
bundles/org.simantics.simulation/src/org/simantics/simulation/experiment/Experiment.java
bundles/org.simantics.simulation/src/org/simantics/simulation/experiment/ExperimentUtil.java
bundles/org.simantics.utils.thread/META-INF/MANIFEST.MF
bundles/org.simantics.utils.thread/src/org/simantics/utils/threads/Executors2.java [deleted file]
bundles/org.simantics.utils/src/org/simantics/utils/FileService.java
bundles/org.simantics.utils/src/org/simantics/utils/FileUtils.java

index 1358c402333b40a42d425e66acaef6faf339af42..5e4ef406db3b9185f22e553b43e88c90b1383656 100644 (file)
@@ -48,9 +48,9 @@ public final class Charts {
     public static HistorySamplerItem createHistorySamplerItem(ReadGraph graph, Resource subscriptionItem, ChartData data) throws DatabaseException {
 
         try {
-            Resource model = graph.syncRequest(new PossibleIndexRoot(subscriptionItem));
-            if (model == null) {
-                throw new DatabaseException("There is no model for " + subscriptionItem);
+            Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(subscriptionItem));
+            if (indexRoot == null) {
+                throw new DatabaseException("There is no index root for " + subscriptionItem);
             }
 
             ItemManager im = new ItemManager(data.history.getItems());
index a396d10dacef442fbe089af59e6cdb85b975f369..aeae9f5d3595f05bae50abc8cc168b892947c976 100644 (file)
@@ -41,7 +41,7 @@ import org.simantics.utils.FileUtils;
  * 
  * @author Tuukka Lehtonen
  */
-public class TrendSupport {
+public class TrendSupport implements ITrendSupport {
 
     // Input
     private IDynamicExperiment experiment;
@@ -170,4 +170,13 @@ public class TrendSupport {
         return finalPath.toFile();
     }
 
+    @Override
+    public void setChartData(ReadGraph graph) throws DatabaseException {
+    }
+
+    @Override
+    public ChartData getChartData() {
+       return chartData;
+    }
+    
 }
index c8efdc2509edd9e5fedd59f32f9e5b8ad68bfdc6..abd6e1ba54ef1203f7508ee285b8e26a4ed442fd 100644 (file)
@@ -14,6 +14,7 @@ package org.simantics.db.indexing;
 import java.io.File;
 import java.io.FileFilter;
 import java.io.IOException;
+import java.util.ArrayList;
 
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
@@ -22,6 +23,7 @@ import org.simantics.db.common.request.IndexRoot;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.common.utils.Logger;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.indexing.internal.IndexChangedWriter;
 import org.simantics.db.layer0.adapter.GenericRelationIndex;
 import org.simantics.db.layer0.genericrelation.IndexedRelations;
 import org.simantics.db.layer0.internal.SimanticsInternal;
@@ -75,7 +77,10 @@ public final class DatabaseIndexing {
             return;
         if (DEBUG)
             System.out.println("Marking all indexes dirty");
-        getAllDirtyFile().createNewFile();
+        File allDirtyFile = getAllDirtyFile();
+        if (allDirtyFile.createNewFile()) {
+            FileUtils.syncFile(allDirtyFile);
+        }
     }
 
     public static void clearAllDirty() throws IOException {
@@ -85,39 +90,61 @@ public final class DatabaseIndexing {
         File indexBase = getIndexBaseLocation();
         if (!indexBase.exists() || !indexBase.isDirectory())
             return;
-        delete(getAllDirtyFile());
 
         forEachIndexPath(new Procedure<File, IOException>() {
             @Override
             public void execute(File indexPath) throws IOException {
-                delete(getChangedFile(indexPath));
+                getChangedFile(indexPath).delete();
             }
         });
-    }
 
+        getAllDirtyFile().delete();
+    }
+    
     /**
      * Internal to indexing, invoked by {@link IndexedRelationsImpl} which
      * doesn't want to throw these exceptions forward. Just log it.
      * 
      * @param indexPath
      */
-    static void markIndexChanged(File indexPath) {
-        if (!indexPath.exists())
-            throw new IllegalArgumentException("index path " + indexPath + " does not exist");
-        if (!indexPath.isDirectory())
-            throw new IllegalArgumentException("index path " + indexPath + " is not a directory");
+    static void markIndexChanged(Session session, File indexPath) {
+        if (DEBUG)
+            System.out.println("Marking index dirty: " + indexPath);
         try {
-            if (DEBUG)
-                System.out.println("Marking index dirty: " + indexPath);
-            getChangedFile(indexPath).createNewFile();
+            File changedFile = getChangedFile(indexPath);
+            // Mark change only once per DB session.
+            if (getIndexChangedWriter(session).markDirty(changedFile)) {
+                if (indexPath.mkdirs()) {
+                    if (changedFile.createNewFile()) {
+                        FileUtils.syncFile(changedFile);
+                    }
+                }
+            }
         } catch (IOException e) {
             Logger.defaultLogError(e);
         }
     }
 
+    private static IndexChangedWriter getIndexChangedWriter(Session session) {
+        IndexChangedWriter writer = session.peekService(IndexChangedWriter.class);
+        if (writer == null) {
+            synchronized (IndexChangedWriter.class) {
+                if (writer == null)
+                    session.registerService(IndexChangedWriter.class, writer = new IndexChangedWriter());
+            }
+        }
+        return writer;
+    }
+
     public static void deleteAllIndexes() throws IOException {
         File indexBase = DatabaseIndexing.getIndexBaseLocation();
-        delete(indexBase);
+
+        ArrayList<String> filter = new ArrayList<>(2);
+        filter.add(getAllDirtyFile().getAbsolutePath());
+        filter.add(indexBase.getAbsolutePath());
+
+        FileUtils.deleteAllWithFilter(indexBase, filter);
+        FileUtils.deleteAll(indexBase);
     }
 
     public static void deleteIndex(final Resource relation, final Resource modelPart) throws DatabaseException {
@@ -148,7 +175,13 @@ public final class DatabaseIndexing {
     public static void deleteIndex(File indexPath) throws IOException {
         if (DEBUG)
             System.out.println("Deleting index " + indexPath);
-        delete(indexPath);
+
+        ArrayList<String> filter = new ArrayList<>(2);
+        filter.add(getChangedFile(indexPath).getAbsolutePath());
+        filter.add(indexPath.getAbsolutePath());
+
+        FileUtils.deleteAllWithFilter(indexPath, filter);
+        FileUtils.deleteAll(indexPath);
     }
 
     public static void validateIndexes() throws IOException {
@@ -161,7 +194,7 @@ public final class DatabaseIndexing {
             // Make sure that index-base is a valid directory
             if (DEBUG)
                 System.out.println(indexBase + " is not a directory! Removing it.");
-            delete(indexBase);
+            FileUtils.deleteAll(indexBase);
             indexBase.mkdirs();
             return;
         }
@@ -169,7 +202,6 @@ public final class DatabaseIndexing {
         if (allDirtyFile.isFile()) {
             if (DEBUG)
                 System.out.println("All indexes marked dirty, removing them.");
-            delete(allDirtyFile);
             deleteAllIndexes();
         } else {
             forEachIndexPath(new Procedure<File, IOException>() {
@@ -186,12 +218,6 @@ public final class DatabaseIndexing {
         }
     }
 
-
-    private static void delete(File fileOrDir) throws IOException {
-        if (fileOrDir.exists())
-            FileUtils.deleteAll(fileOrDir);
-    }
-
     interface Procedure<T, E extends Throwable> {
         void execute(T t) throws E;
     }
index aaadc4704d487ddbdce71af7e59a78522648657b..1b4d62a1d6c6cf9c6d199b7454e713232c763526 100644 (file)
@@ -392,13 +392,13 @@ public class IndexedRelationsImpl implements IndexedRelations {
         
         try {
                
+               DatabaseIndexing.markIndexChanged(processor.getSession(), searcher.getIndexPath());
                if(!searcher.startAccess(null, processor.getSession(), true)) {
                 // Could not write index for some reason. Ignore and let the next index query reinitialize the index.
                        return;
                }
                
             searcher.insertIndex(progress.newChild(40), relation, 1, documents);
-            DatabaseIndexing.markIndexChanged(searcher.getIndexPath());
             
         } catch (InvalidResourceReferenceException e) {
             throw new IndexException(e);
@@ -429,13 +429,13 @@ public class IndexedRelationsImpl implements IndexedRelations {
         LockHandle handle = lock(processor, Pair.make(relationResource, input), true);
         try {
                
+            DatabaseIndexing.markIndexChanged(processor.getSession(), searcher.getIndexPath());
                if(!searcher.startAccess(null, processor.getSession(), true)) {
                 // Could not write index for some reason. Ignore and let the next index query reinitialize the index.
                        return;
                }
                
             searcher.removeIndex(progress.newChild(40), relation, processor, key, keyValues);
-            DatabaseIndexing.markIndexChanged(searcher.getIndexPath());
             
         } catch (DatabaseException e) {
             throw new IndexException(e);
@@ -492,13 +492,12 @@ public class IndexedRelationsImpl implements IndexedRelations {
 
         try {
                
+               DatabaseIndexing.markIndexChanged(processor.getSession(), searcher.getIndexPath());
                if(!searcher.startAccess(null, processor.getSession(), true)) {
                 // Could not write index for some reason. Ignore and let the next index query reinitialize the index.
                        return true;
                }
-            didChange = searcher.replaceIndex(progress.newChild(40), key, keyValues, relation, 1, documents);
-            if(didChange)
-               DatabaseIndexing.markIndexChanged(searcher.getIndexPath());
+            searcher.replaceIndex(progress.newChild(40), key, keyValues, relation, 1, documents);
             
         } catch (InvalidResourceReferenceException e) {
             throw new IndexException(e);
diff --git a/bundles/org.simantics.db.indexing/src/org/simantics/db/indexing/internal/IndexChangedWriter.java b/bundles/org.simantics.db.indexing/src/org/simantics/db/indexing/internal/IndexChangedWriter.java
new file mode 100644 (file)
index 0000000..c0e97a2
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.indexing.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * An internal in-memory container for telling whether a certain index has been
+ * changed since the platform was last started up. 
+ * 
+ * @author Jussi Koskela
+ * @since 1.28.0
+ */
+public class IndexChangedWriter {
+       private Set<String> dirtyFiles = new HashSet<>();
+
+       public synchronized boolean markDirty(File dirtyFile) throws IOException {
+               return dirtyFiles.add(dirtyFile.getAbsolutePath());
+       }
+}
index 538f22478d00f1708a4b0c89e2059adae754f1a4..adc51c16d88ef0f74f1f849f421e9156398c69f1 100644 (file)
@@ -1349,6 +1349,18 @@ public class Layer0Utils {
        return null;
     }
     
+    public static Resource getPossiblePredicateByLabel(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException {
+       Layer0 L0 = Layer0.getInstance(graph);
+       for(Resource type : graph.getPrincipalTypes(instance)) {
+               Map<String, Resource> domainOf = getDomainOf(graph, type);
+               for(Resource r : domainOf.values()) {
+                       String label = graph.getPossibleRelatedValue(r, L0.HasLabel, Bindings.STRING);
+                       if(predicateName.equals(label))
+                               return r;
+               }
+       }
+       return null;
+    }
     
     public static void claimLiteralDataboard(WriteGraph graph, Resource container, Resource property, String valueText) throws DatabaseException {
 
index 7d172318bf1b8561c009f2ef55086e62ee7037fc..4ec3258a7822554f228ccbf0ddd83af6b8dce909 100644 (file)
@@ -987,18 +987,20 @@ public class SymbolLibraryComposite extends Composite {
         final boolean expanded = grp.getExpanded();
         final boolean visible = grp.getVisible();
         final boolean filterChanged = !objectEquals(filter, lastFilter);
+        final ISymbolGroup symbolGroup = (ISymbolGroup) grp.getData(SymbolLibraryKeys.KEY_GROUP);
+        final boolean filterMatchesGroup = filter != null && filter.select(viewer, null, symbolGroup);
 
         // Find out how much data would be shown with the new filter.
-        viewer.setFilter(filter);
+        viewer.setFilter(filterMatchesGroup ? null : filter);
         Object[] elements = viewer.getFilteredElements();
 
-        ISymbolGroup symbolGroup = (ISymbolGroup) grp.getData(SymbolLibraryKeys.KEY_GROUP);
-        boolean filterMatchesGroup = filter != null && filter.select(viewer, null, symbolGroup);
         boolean shouldBeVisible = !groupFiltered && (elements.length > 0 || filterMatchesGroup);
         boolean shouldBeExpanded = shouldBeVisible && (filter != null || userExpanded);
 
-//        System.out.format("%40s: visible/should be = %5s %5s,  expanded/user expanded/should be = %5s %5s %5s\n",
+//        System.out.format("%40s: filterMatchesGroup(%s) = %s, visible/should be = %5s %5s,  expanded/user expanded/should be = %5s %5s %5s\n",
 //                grp.getText(),
+//                symbolGroup.getName(),
+//                String.valueOf(filterMatchesGroup),
 //                String.valueOf(visible),
 //                String.valueOf(shouldBeVisible),
 //                String.valueOf(expanded),
index 73df6dc618bbb99e84f3638f8dbff795ea80bc28..1c45a220fcf005ac80bf0e2b92f9c988127987fc 100644 (file)
@@ -15,9 +15,10 @@ public class HistorySampler {
     public synchronized static TDoubleArrayList sample( HistorySamplerItem item, double from, double end, double timeWindow, double timeStep, boolean resample ) throws HistoryException, IOException {
 
        try {
-               item.open();
+               // If there is something pending at this point, flush before opening for read
                if(item.collector != null)
                        item.collector.flush();
+               item.open();
                return sample(item.iter, from, end, timeWindow, timeStep, resample);
        } finally {
                item.close();
@@ -25,10 +26,18 @@ public class HistorySampler {
     }
 
     public static TDoubleArrayList sample( StreamIterator iter, double from, double end, double timeWindow, double timeStep, boolean resample ) throws HistoryException, IOException {
+       return sample(iter, from, end, timeWindow, timeStep, resample, 0.0);
+    }
+
+    public static TDoubleArrayList sample( StreamIterator iter, double from, double end, double timeWindow, double timeStep, boolean resample, Double sampleFrom ) throws HistoryException, IOException {
 
        ExportInterpolation numberInterpolation = ExportInterpolation.LINEAR_INTERPOLATION;
 
-       double startTime = 0.0;
+       double startTime = from;
+       if(sampleFrom != null) {
+                // This option can be used do define the offset of sampling. Samples will be sampleFrom + n * timeStep
+               startTime = sampleFrom;
+       }
 
        TDoubleArrayList result = new TDoubleArrayList();
 
index 4935fafcd043c547853d18984e15eab1380e272c..72166303ea6ec97967454ac9607671dbaf1af7b7 100644 (file)
@@ -6,10 +6,15 @@ importJava "org.simantics.simulation.experiment.ExperimentUtil" where
     stepExperiment :: IExperiment -> Double -> <Proc> ()
     simulateExperiment :: IExperiment -> Boolean -> <Proc> ()
     disposeExperiment :: IExperiment -> <Proc> ()
-    possibleActiveRunVariable ::Resource -> <ReadGraph> Variable
+    getExperimentState :: IExperiment -> <ReadGraph> ExperimentState
+    possibleActiveRunVariable ::Resource -> <ReadGraph> Maybe Variable
     
 importJava "org.simantics.simulation.experiment.IExperiment" where
     data IExperiment
+
+importJava "org.simantics.simulation.experiment.ExperimentState" where
+    data ExperimentState
+    INITIALIZING, RUNNING, STOPPED, DISPOSED :: ExperimentState
     
 experimentFromRun :: Variable -> <ReadGraph> IExperiment
 experimentFromRun run = (run#iExperiment) :: IExperiment
\ No newline at end of file
index 7fedc55d11ae8a5713f83e6e5315dbc192cb4e7b..bb2ba5c2c411310fb1971e6609dce41fcf2f814d 100644 (file)
@@ -14,8 +14,6 @@ package org.simantics.project;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -188,22 +186,25 @@ public class ProjectFeatures {
             return false;
         }
 
-        private Collection<IProjectFeatureExtension> sortTopologically(Collection<IProjectFeatureExtension> toSort) {
-            ArrayList<IProjectFeatureExtension> sorted = new ArrayList<IProjectFeatureExtension>(toSort);
-            Collections.sort(sorted, new Comparator<IProjectFeatureExtension>() {
-                Set<IProjectFeatureExtension> visited = new HashSet<IProjectFeatureExtension>();
-                @Override
-                public int compare(IProjectFeatureExtension e1, IProjectFeatureExtension e2) {
-                    visited.clear();
-                    if (deepRequires(visited, e1, e2))
-                        return 1;
-                    visited.clear();
-                    if (deepRequires(visited, e2, e1))
-                        return -1;
-                    return 0;
+        private void requiresDFS(IProjectFeatureExtension ext, ArrayList<IProjectFeatureExtension> result, Set<IProjectFeatureExtension> visited) {
+            if(visited.add(ext)) {
+                Set<IProjectFeatureExtension> reqs = required.getValues(ext);
+                if(reqs != null) {
+                    for(IProjectFeatureExtension req : reqs) {
+                        requiresDFS(req, result, visited);
+                    }
                 }
-            });
-            return sorted;
+                result.add(ext);
+            }
+        }
+
+        private Collection<IProjectFeatureExtension> sortTopologically(Collection<IProjectFeatureExtension> toSort) {
+            ArrayList<IProjectFeatureExtension> result = new ArrayList<>();
+            Set<IProjectFeatureExtension> visited = new HashSet<>();
+            for(IProjectFeatureExtension ext : toSort) {
+                requiresDFS(ext, result, visited);
+            }
+            return result;
         }
 
         private Collection<IProjectFeatureExtension> requiredExtensions(IProjectFeatureExtension[] allExtensions, Collection<IProjectFeatureExtension> includedExtensions) throws ProjectException {
@@ -234,7 +235,8 @@ public class ProjectFeatures {
                             if (injectionTargetExt != null) {
                                 changed = true;
                                 includedProjectFeatureIds.add(ext.getId());
-                                result.add(ext);
+                                if(!result.contains(ext))
+                                    result.add(ext);
                                 required.add(injectionTargetExt, ext);
                             }
                         }
index e861bc09dc47e81f3b1857889c835db091837048..b07304ed1ce3b8d39af3c5c8d06b1dd5cc6ccf3e 100644 (file)
@@ -94,7 +94,7 @@ public class ProjectFeatureRegistry implements IProjectFeatureRegistry, IExtensi
                 String description = StringUtils.safeString(el.getAttribute("description"));
                 boolean published = "true".equalsIgnoreCase(el.getAttribute("published"));
                 Collection<ProjectFeatureReference> requires = readProjectFeatureReferenceCollection(el, "requires");
-                Collection<InjectedDependency> injections = readInjectedDependencies(el);
+                Collection<InjectedDependency> injections = readInjectedDependencies(el, id);
                 Collection<GroupReference> installGroups = readGroupReferenceCollection(el, "installGroup");
 
                 ProjectFeatureExtension ext = new ProjectFeatureExtension(el, id, label, description, published, requires, injections, installGroups);
@@ -111,19 +111,17 @@ public class ProjectFeatureRegistry implements IProjectFeatureRegistry, IExtensi
         this.extensions = newExtensions.toArray(new IProjectFeatureExtension[newExtensions.size()]);
     }
 
-    private Collection<InjectedDependency> readInjectedDependencies(IConfigurationElement element) {
+    private Collection<InjectedDependency> readInjectedDependencies(IConfigurationElement element, String id) {
         Collection<InjectedDependency> result = new ArrayList<InjectedDependency>();
 
         for (IConfigurationElement child : element.getChildren(INJECT_DEPENDENCY)) {
-            String id = StringUtils.safeString(child.getAttribute("id"));
-            if (id.isEmpty())
-                // Invalid extension
-                return null;
-
             String targetId = StringUtils.safeString(child.getAttribute("targetId"));
             if (targetId.isEmpty())
                 // Invalid extension
                 return null;
+            
+            result.add(new InjectedDependency(new ProjectFeatureReference(id, false), new ProjectFeatureReference(targetId, false)));
+            
         }
 
         return result;
index b4222df012e4a56d8533914fa0c751adfd724fef..41125d0a0ad2f086cb90201c05f15c432d8bebcc 100644 (file)
@@ -19,6 +19,8 @@ import org.simantics.databoard.accessor.Accessor;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.Listener;
+import org.simantics.db.request.ExternalRead;
 import org.simantics.utils.datastructures.ListenerList;
 
 public abstract class Experiment implements IExperiment {
@@ -64,7 +66,7 @@ public abstract class Experiment implements IExperiment {
     
     @Override
     public ExperimentState getState(ReadGraph graph) throws DatabaseException {
-       throw new UnsupportedOperationException();
+       return graph.syncRequest(EXPERIMENT_STATE_READ);
     }
 
     public void changeState(ExperimentState newState) {
@@ -136,4 +138,37 @@ public abstract class Experiment implements IExperiment {
         return identifier;
     }
 
+    static class ExperimentStateRead implements ExternalRead<ExperimentState>, Runnable {
+       
+       final private Experiment experiment;
+        private Listener<ExperimentState> listener = null;
+        
+        ExperimentStateRead(Experiment experiment) {
+               this.experiment = experiment;
+        }
+
+        @Override
+        public void register(ReadGraph graph, final Listener<ExperimentState> procedure) {
+            //System.out.println("IcTrackerRequest.register: " + procedure);
+            listener = procedure;
+            procedure.execute(experiment.state);
+        }
+
+        @Override
+        public void unregistered() {
+            //System.out.println("IcTrackerRequest.unregister: " + listener);
+            listener = null;
+        }
+
+        @Override
+        public void run() {
+            Listener<ExperimentState> l = listener;
+            //System.out.println("IcTrackerRequest.run: " + l);
+            if (l != null)
+                l.execute(experiment.state);
+        }
+    }
+
+    private ExperimentStateRead EXPERIMENT_STATE_READ = new ExperimentStateRead(this);
+    
 }
index 24f6065c5117a6e6660d336edfeefa3c56f43593..a819ef8ed915462da196d5e120ceee3a6a070021 100644 (file)
@@ -47,6 +47,10 @@ public final class ExperimentUtil {
             ((IDynamicExperiment)experiment).simulate(enabled);
     }
 
+    public static ExperimentState getExperimentState(ReadGraph graph, IExperiment experiment) throws DatabaseException {
+       return experiment.getState(graph);
+    }
+        
     public static void disposeExperiment(final IExperiment experiment) {
        
         if(experiment instanceof IDynamicExperiment) {
index c71e2515697d70c6b8c7b93ea604129679204e11..44435fa6ed41421f640db3fa1312de4e0857c81d 100644 (file)
@@ -6,5 +6,4 @@ Bundle-Version: 1.1.0.qualifier
 Export-Package: org.simantics.utils.threads,
  org.simantics.utils.threads.logger
 Bundle-Vendor: VTT Technical Research Centre of Finland
-Require-Bundle: org.eclipse.swt;bundle-version="3.6.0";resolution:=optional
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/bundles/org.simantics.utils.thread/src/org/simantics/utils/threads/Executors2.java b/bundles/org.simantics.utils.thread/src/org/simantics/utils/threads/Executors2.java
deleted file mode 100644 (file)
index 66af979..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     VTT Technical Research Centre of Finland - initial API and implementation
- *******************************************************************************/
-package org.simantics.utils.threads;
-
-import java.util.concurrent.Executor;
-
-import org.eclipse.swt.widgets.Display;
-
-public class Executors2 {
-
-       public static Executor createSWTExecutor(Display display, boolean async) {
-               return async ? new SWTExecutorAsync(display) : new SWTExecutorSync(display);
-       }
-       
-}
-
-class SWTExecutorAsync implements Executor {
-       
-       Display display;
-       public SWTExecutorAsync(Display display)
-       {
-               this.display = display;
-       }
-       
-       @Override
-       public void execute(Runnable command) {
-               // Don't accept work if the SWT thread is disposed.
-               if (display.isDisposed()) 
-                       throw new RuntimeException("The SWT thread has been disposed"); 
-               display.asyncExec(command);
-       }
-       
-}
-
-class SWTExecutorSync implements Executor {
-       
-       Display display;
-       public SWTExecutorSync(Display display)
-       {
-               this.display = display;
-       }
-       
-       @Override
-       public void execute(Runnable command) {
-               // Don't accept work if the SWT thread is disposed.
-               if (display.isDisposed()) 
-                       throw new RuntimeException("The SWT thread has been disposed"); 
-               display.syncExec(command);
-       }
-       
-}
-
index c500c66350b937e6d5d6d61ff6e9d7800ffc4115..ab3d249d3bd95e157dcdb6af12caa87dba737353 100644 (file)
@@ -22,6 +22,31 @@ public interface FileService {
                }
        }
 
+       @FunctionalInterface
+       public static interface FileOperation {
+               IOperation<Boolean, IOException> perform(File file);
+
+               default void perform(File... files) {
+                       for (File f : files)
+                               perform(f);
+               }
+       }
+
+       public static class DeleteOperation implements FileOperation {
+               private final FileService service;
+               private final DeleteOption[] options;
+
+               public DeleteOperation(FileService service, DeleteOption... options) {
+                       this.service = service;
+                       this.options = options;
+               }
+
+               @Override
+               public IOperation<Boolean, IOException> perform(File file) {
+                       return service.scheduleDeleteIfExists(file, options);
+               }
+       }
+
        /**
         * Schedules a file to be deleted at some point in the future when the
         * system allows it to be deleted if ever.
@@ -33,4 +58,16 @@ public interface FileService {
         */
        IOperation<Boolean, IOException> scheduleDeleteIfExists(File file, DeleteOption... options);
 
+       /**
+        * @param options
+        *            the deletion options to be used by the returned FileOperation
+        * @return a FileOperation that runs
+        *         {@link #scheduleDeleteIfExists(File, DeleteOption...)} for any
+        *         files given to it
+        * @since 1.28.0
+        */
+       default FileOperation deleteOperation(DeleteOption... options) {
+               return new DeleteOperation(this, options);
+       }
+
 }
index b3ec46a30c656b2c19fa626785696620b963f1f8..4e68f29c4ac95246da7d81d2b9e14c7b323dafbc 100644 (file)
@@ -1013,4 +1013,10 @@ public class FileUtils {
             return FileVisitResult.CONTINUE;
         }
     }
+    
+    public static void syncFile(File file) throws IOException {
+       try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
+               raf.getFD().sync();
+               }
+    }
 }