]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics/src/org/simantics/Simantics.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics / src / org / simantics / Simantics.java
diff --git a/bundles/org.simantics/src/org/simantics/Simantics.java b/bundles/org.simantics/src/org/simantics/Simantics.java
new file mode 100644 (file)
index 0000000..1e01acf
--- /dev/null
@@ -0,0 +1,583 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics;\r
+\r
+import java.io.File;\r
+import java.util.UUID;\r
+import java.util.concurrent.ScheduledFuture;\r
+import java.util.concurrent.TimeUnit;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.NullProgressMonitor;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.simantics.SimanticsPlatform.OntologyRecoveryPolicy;\r
+import org.simantics.SimanticsPlatform.RecoveryPolicy;\r
+import org.simantics.application.arguments.IArguments;\r
+import org.simantics.application.arguments.SimanticsArguments;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.procedure.adapter.ProcedureAdapter;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.RuntimeDatabaseException;\r
+import org.simantics.db.indexing.IndexUtils;\r
+import org.simantics.db.layer0.util.SimanticsClipboard;\r
+import org.simantics.db.layer0.util.SimanticsKeys;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.management.ISessionContextProvider;\r
+import org.simantics.db.management.ISessionContextProviderSource;\r
+import org.simantics.db.management.SessionContextProvider;\r
+import org.simantics.db.management.SingleSessionContextProviderSource;\r
+import org.simantics.db.request.ReadInterface;\r
+import org.simantics.db.request.WriteInterface;\r
+import org.simantics.internal.FileServiceImpl;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.project.IProject;\r
+import org.simantics.project.ProjectKeys;\r
+import org.simantics.scl.compiler.top.ValueNotFound;\r
+import org.simantics.scl.osgi.SCLOsgi;\r
+import org.simantics.scl.runtime.SCLContext;\r
+import org.simantics.scl.runtime.function.Function;\r
+import org.simantics.scl.runtime.function.Function1;\r
+import org.simantics.scl.runtime.function.Function2;\r
+import org.simantics.utils.FileService;\r
+import org.simantics.utils.FileUtils;\r
+import org.simantics.utils.TempFiles;\r
+import org.simantics.utils.threads.ThreadUtils;\r
+\r
+/**\r
+ * A facade for accessing basic Simantics platform services. Usable without a\r
+ * graphical UI, i.e. in headless contexts.\r
+ *\r
+ * TODO: in time, move headless functionality of SimanticsUI into this class but\r
+ * originals as delegates in SimanticsUI.\r
+ *\r
+ * TODO: duplicate of org.simantics.db.layer0.util.Simantics, do something about this!!\r
+ */\r
+public class Simantics {\r
+\r
+    private static ISessionContextProviderSource providerSource = null;\r
+    private static volatile FileServiceImpl fileService = null;\r
+\r
+    /**\r
+     * @param args\r
+     * @param progress\r
+     * @return\r
+     * @throws PlatformException\r
+     */\r
+    public static ISessionContext startUpHeadless(IArguments args, IProgressMonitor progress) throws PlatformException {\r
+        if (SimanticsPlatform.INSTANCE.sessionContext != null) {\r
+            throw new RuntimeDatabaseException("Simantics is already up and running.");\r
+        }\r
+\r
+        RecoveryPolicy workspacePolicy = Platform.inDevelopmentMode() ? RecoveryPolicy.FixError : RecoveryPolicy.ThrowError;\r
+        OntologyRecoveryPolicy ontologyPolicy = Platform.inDevelopmentMode() ? OntologyRecoveryPolicy.Merge : OntologyRecoveryPolicy.ThrowError;\r
+\r
+        if (args.contains(SimanticsArguments.RECOVERY_POLICY_FIX_ERRORS)) {\r
+            workspacePolicy = RecoveryPolicy.FixError;\r
+            ontologyPolicy = OntologyRecoveryPolicy.Merge;\r
+        }\r
+\r
+        if (args.contains(SimanticsArguments.ONTOLOGY_RECOVERY_POLICY_REINSTALL)) {\r
+            ontologyPolicy = OntologyRecoveryPolicy.ReinstallDatabase;\r
+        }\r
+\r
+        if (args.contains(SimanticsArguments.ONTOLOGY_RECOVERY_POLICY_REINSTALL)) {\r
+            ontologyPolicy = OntologyRecoveryPolicy.ReinstallDatabase;\r
+        }\r
+\r
+        int localPort = 0;\r
+        if (args.contains(SimanticsArguments.LOCAL_SERVER_PORT)) {\r
+            try {\r
+                localPort = args.get(SimanticsArguments.LOCAL_SERVER_PORT);\r
+            } catch (IllegalArgumentException e) {\r
+                throw new PlatformException("Failed to open database session", e);\r
+            }\r
+        }\r
+\r
+//        ServerAddress remoteDatabase = null;\r
+//        if (args.contains(SimanticsArguments.SERVER)) {\r
+//            String serverAddress = args.get(SimanticsArguments.SERVER);\r
+//            try {\r
+//                remoteDatabase = new ServerAddress(serverAddress);\r
+//            } catch (IllegalArgumentException e) {\r
+//                throw new PlatformException("Failed to open database session", e);\r
+//            }\r
+//        }\r
+\r
+        return startUpHeadless(progress, workspacePolicy, ontologyPolicy, localPort /*, remoteDatabase*/);\r
+    }\r
+\r
+    /**\r
+     * @param progress\r
+     * @param workspacePolicy\r
+     * @param ontologyPolicy\r
+     * @param localPort\r
+     * @param remoteDatabase\r
+     * @return\r
+     * @throws PlatformException\r
+     */\r
+    public static ISessionContext startUpHeadless(IProgressMonitor progress, RecoveryPolicy workspacePolicy, OntologyRecoveryPolicy ontologyPolicy, int localPort) throws PlatformException {\r
+        if (SimanticsPlatform.INSTANCE.sessionContext != null) {\r
+            throw new RuntimeDatabaseException("Simantics is already up and running.");\r
+        }\r
+\r
+        // Set session context provider.\r
+        final ISessionContextProvider provider = new SessionContextProvider(null);\r
+        ISessionContextProviderSource source = new SingleSessionContextProviderSource(provider);\r
+        setSessionContextProviderSource(source);\r
+        org.simantics.db.layer0.internal.SimanticsInternal.setSessionContextProviderSource(source);\r
+\r
+        if (progress == null)\r
+            progress = new NullProgressMonitor();\r
+        return SimanticsPlatform.INSTANCE.startUp(null, progress, workspacePolicy, ontologyPolicy, true, new ConsoleUserAgent());\r
+    }\r
+\r
+    /**\r
+     * @param progress\r
+     * @throws PlatformException\r
+     */\r
+    public static void shutdown(IProgressMonitor progress) throws PlatformException {\r
+        SimanticsPlatform.INSTANCE.shutdown(progress);\r
+    }\r
+\r
+    /**\r
+     * Queue execution of a runnable.\r
+     *\r
+     * @param runnable\r
+     */\r
+    public static void async(Runnable runnable) {\r
+        ThreadUtils.getBlockingWorkExecutor().execute(runnable);\r
+    }\r
+\r
+    public static void async(Runnable runnable, int delay, TimeUnit unit) {\r
+        ThreadUtils.getTimer().schedule(runnable, delay, unit);\r
+    }\r
+\r
+    public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, int initialDelay, int period, TimeUnit unit) {\r
+        return ThreadUtils.getTimer().scheduleAtFixedRate(runnable, initialDelay, period, unit);\r
+    }\r
+\r
+    /**\r
+     * Queue execution of a non-blocking runnable. Use this method with caution.\r
+     * A non-blocking runnable nevers locks anything, No Locks, No semaphores,\r
+     * No Object.wait(), No synchronized() {} blocks.\r
+     *\r
+     * @param runnable a non-blocking runnable\r
+     */\r
+    public static void asyncNonblocking(Runnable runnable) {\r
+        ThreadUtils.getNonBlockingWorkExecutor().execute(runnable);\r
+    }\r
+\r
+    /**\r
+     * Schedule execution of a non-blocking runnable. Use this method with caution.\r
+     * A non-blocking runnable never locks anything, No Locks, No semaphores,\r
+     * No Object,wait(), No synchronized() {} blocks.\r
+     *\r
+     * @param runnable a non-blocking runnable\r
+     * @param initialDelay\r
+     * @param period\r
+     */\r
+    public static void asyncNonblocking(Runnable runnable, int initialDelay, int period) {\r
+        ThreadUtils.getNonBlockingWorkExecutor().scheduleAtFixedRate(runnable, initialDelay, period, TimeUnit.MILLISECONDS);\r
+    }\r
+\r
+    public static synchronized ISessionContext setSessionContext(ISessionContext ctx) {\r
+        return getSessionContextProvider().setSessionContext(ctx);\r
+    }\r
+\r
+    public static void setSessionContextProviderSource(ISessionContextProviderSource source) {\r
+        if (source == null)\r
+            throw new IllegalArgumentException("null provider source");\r
+        providerSource = source;\r
+    }\r
+\r
+    public static ISessionContextProviderSource getProviderSource() {\r
+        if (providerSource == null)\r
+            throw new IllegalStateException(\r
+            "providerSource must be initialized by the application before using class Simantics");\r
+        return providerSource;\r
+    }\r
+\r
+    public static ISessionContextProvider getSessionContextProvider() {\r
+        return getProviderSource().getActive();\r
+    }\r
+\r
+    /**\r
+     * Returns the database session context associated with the currently active\r
+     * context. This method should be used to retrieve session contexts only\r
+     * when the client is sure that the correct context is active.\r
+     *\r
+     * @return the session context associated with the currently active context\r
+     *         or <code>null</code> if the context has no session context\r
+     */\r
+    public static ISessionContext getSessionContext() {\r
+        ISessionContextProvider provider = getSessionContextProvider();\r
+        return provider != null ? provider.getSessionContext() : null;\r
+    }\r
+\r
+    /**\r
+     * Returns the database Session bound to the currently active context.\r
+     *\r
+     * <p>\r
+     * The method always returns a non-null Session or produces an\r
+     * IllegalStateException if a Session was not attainable.\r
+     * </p>\r
+     *\r
+     * @return the Session bound to the currently active workbench window\r
+     * @throws IllegalStateException if no Session was available\r
+     */\r
+    public static Session getSession() {\r
+        ISessionContext ctx = getSessionContext();\r
+        if (ctx == null)\r
+            throw new IllegalStateException("Session unavailable, no database session open");\r
+        return ctx.getSession();\r
+    }\r
+\r
+    /**\r
+     * Returns the database Session bound to the currently active context.\r
+     * Differently from {@link #getSession()}, this method returns\r
+     * <code>null</code> if there is no current Session available.\r
+     *\r
+     * @see #getSession()\r
+     * @return the Session bound to the currently active context or\r
+     *         <code>null</code>\r
+     */\r
+    public static Session peekSession() {\r
+        ISessionContext ctx = getSessionContext();\r
+        return ctx == null ? null : ctx.peekSession();\r
+    }\r
+\r
+    /**\r
+     * @return the currently open and active project as a Resource\r
+     * @throws IllegalStateException if there is no currently active database\r
+     *         session, which also means there is no active project at the\r
+     *         moment\r
+     */\r
+    public static Resource getProjectResource() {\r
+        ISessionContext ctx = getSessionContext();\r
+        if (ctx == null)\r
+            throw new IllegalStateException("No current database session");\r
+        Resource project = ctx.getHint(SimanticsKeys.KEY_PROJECT);\r
+        if (project == null)\r
+            throw new IllegalStateException("No current project resource in session context " + ctx);\r
+        return project;\r
+    }\r
+\r
+    /**\r
+     * @return the currently open and active project as a {@link Resource}\r
+     */\r
+    public static Resource peekProjectResource() {\r
+        ISessionContext ctx = getSessionContext();\r
+        return ctx != null ? ctx.<Resource>getHint(SimanticsKeys.KEY_PROJECT) : null;\r
+    }\r
+\r
+    /**\r
+     * @return the currently open and active project as an {@link IProject}\r
+     * @throws IllegalStateException if there is no currently active database\r
+     *         session, which also means there is no active project at the\r
+     *         moment\r
+     */\r
+    public static IProject getProject() {\r
+        ISessionContext ctx = getSessionContext();\r
+        if (ctx == null)\r
+            throw new IllegalStateException("No current database session");\r
+        IProject project = ctx.getHint(ProjectKeys.KEY_PROJECT);\r
+        if (project == null)\r
+            throw new IllegalStateException("No current project in session context " + ctx);\r
+        return project;\r
+    }\r
+\r
+    /**\r
+     * @return the currently open and active project as an {@link IProject} or\r
+     *         <code>null</code> if there is no active session or project\r
+     */\r
+    public static IProject peekProject() {\r
+        ISessionContext ctx = getSessionContext();\r
+        return ctx == null ? null : ctx.<IProject>getHint(ProjectKeys.KEY_PROJECT);\r
+    }\r
+\r
+    // FIXME: once org.simantics.db.layer0.util.Simantics is gone, re-enable this\r
+//    private static SimanticsClipboard clipboard = SimanticsClipboard.EMPTY;\r
+\r
+    /**\r
+     * @param content\r
+     */\r
+    public static void setClipboard(SimanticsClipboard content) {\r
+        // FIXME: once org.simantics.db.layer0.util.Simantics is gone, re-enable this\r
+//        if (content == null)\r
+//            throw new NullPointerException("null clipboard content");\r
+//        clipboard = content;\r
+        org.simantics.db.layer0.internal.SimanticsInternal.setClipboard(content);\r
+    }\r
+\r
+    public static SimanticsClipboard getClipboard() {\r
+        // FIXME: once org.simantics.db.layer0.util.Simantics is gone, re-enable this\r
+        //return clipboard;\r
+        return org.simantics.db.layer0.internal.SimanticsInternal.getClipboard();\r
+    }\r
+\r
+    public static Layer0 getLayer0() throws DatabaseException {\r
+        return Layer0.getInstance(getSession());\r
+    }\r
+\r
+    public static <T> T sync(ReadInterface<T> r) throws DatabaseException {\r
+       return getSession().sync(r);\r
+    }\r
+\r
+    public static <T> T sync(WriteInterface<T> r) throws DatabaseException {\r
+       return getSession().sync(r);\r
+    }\r
+\r
+    public static <T> void async(ReadInterface<T> r) {\r
+       getSession().async(r, new ProcedureAdapter<T>());\r
+    }\r
+\r
+    public static <T> void async(WriteInterface<T> r) {\r
+       getSession().async(r);\r
+    }\r
+\r
+    public static void clearTemporaryDirectory() {\r
+        FileUtils.deleteDir(getTemporaryDirectory());\r
+    }\r
+\r
+    public static File getTempfile(String directory, String suffix) {\r
+        File dir = getTemporaryDirectory(directory);\r
+        return new File(dir, UUID.randomUUID().toString() + "." + suffix);\r
+    }\r
+\r
+    public static File getTemporaryDirectory(String directory) {\r
+        File sub = new File(getTemporaryDirectory(), directory);\r
+        sub.mkdirs();\r
+        return sub;\r
+    }\r
+\r
+    public static File getTemporaryDirectory() {\r
+        File workspace = Platform.getLocation().toFile();\r
+        File temp = new File(workspace, "tempFiles");\r
+        temp.mkdirs();\r
+        return temp;\r
+    }\r
+\r
+    public static TempFiles getTempFiles() {\r
+        return TEMP_FILES;\r
+    }\r
+\r
+    private static class TempFilesImpl implements TempFiles {\r
+        private final TempFilesImpl parent;\r
+        private final String prefix;\r
+        private final String fullPrefix;\r
+\r
+        private TempFilesImpl(TempFilesImpl parent, String directory) {\r
+            this.parent = parent;\r
+            this.prefix = directory;\r
+            this.fullPrefix = getPrefix(new StringBuilder()).toString();\r
+        }\r
+\r
+        private StringBuilder getPrefix(StringBuilder sb) {\r
+            if (parent != null)\r
+                parent.getPrefix(sb);\r
+            if (prefix != null && !prefix.isEmpty())\r
+                sb.append(prefix).append(File.separatorChar);\r
+            return sb;\r
+        }\r
+\r
+        @Override\r
+        public File getRoot() {\r
+            return Simantics.getTemporaryDirectory(fullPrefix);\r
+        }\r
+\r
+        @Override\r
+        public File getTempfile(String directory, String suffix) {\r
+            return Simantics.getTempfile(fullPrefix.isEmpty() ? directory : fullPrefix + directory, suffix);\r
+        }\r
+\r
+        @Override\r
+        public TempFiles subdirectory(String directory) {\r
+            return new TempFilesImpl(this, directory);\r
+        }\r
+    }\r
+\r
+    public static TempFiles TEMP_FILES = new TempFilesImpl(null, null);\r
+\r
+    public static void flushIndexCaches(IProgressMonitor progress, Session session) {\r
+        try {\r
+            IndexUtils.flushIndexCaches(progress, session);\r
+        } catch (Exception e) {\r
+            Logger.defaultLogError(e);\r
+        }\r
+    }\r
+\r
+\r
+    @SuppressWarnings({ "unchecked", "rawtypes" })\r
+       public static <T> T applySCL(String module, String function, ReadGraph graph, Object ... args) throws DatabaseException {\r
+        SCLContext sclContext = SCLContext.getCurrent();\r
+           Object oldGraph = sclContext.put("graph", graph);\r
+               try {\r
+                       T t = (T)((Function)SCLOsgi.MODULE_REPOSITORY.getValue(module, function)).applyArray(args);\r
+                       return t;\r
+               } catch (ValueNotFound e) {\r
+                       throw new DatabaseException("SCL Value not found: " + e.name);\r
+               } catch (Throwable t) {\r
+                       throw new DatabaseException(t);\r
+               } finally {\r
+                       sclContext.put("graph", oldGraph);\r
+               }\r
+\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    public static <T> T applySCLWrite(WriteGraph graph, @SuppressWarnings("rawtypes") Function f, Object ... args) throws DatabaseException {\r
+        SCLContext sclContext = SCLContext.getCurrent();\r
+        Object oldGraph = sclContext.put("graph", graph);\r
+        try {\r
+            return (T)f.applyArray(args);\r
+        } catch (Throwable t) {\r
+            throw new DatabaseException(t);\r
+        } finally {\r
+            sclContext.put("graph", oldGraph);\r
+        }\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    public static <T> T applySCLRead(ReadGraph graph, @SuppressWarnings("rawtypes") Function f, Object ... args) throws DatabaseException {\r
+        SCLContext sclContext = SCLContext.getCurrent();\r
+        Object oldGraph = sclContext.put("graph", graph);\r
+        try {\r
+            return (T)f.applyArray(args);\r
+        } catch (Throwable t) {\r
+            throw new DatabaseException(t);\r
+        } finally {\r
+            sclContext.put("graph", oldGraph);\r
+        }\r
+    }\r
+    \r
+    public static <P0,R> R applySCLWrite(WriteGraph graph, Function1<P0,R> function, P0 p0) throws DatabaseException {\r
+        SCLContext sclContext = SCLContext.getCurrent();\r
+        Object oldGraph = sclContext.put("graph", graph);\r
+        try {\r
+            return function.apply(p0);\r
+        } catch (Throwable t) {\r
+            throw new DatabaseException(t);\r
+        } finally {\r
+            sclContext.put("graph", oldGraph);\r
+        }\r
+    }\r
+\r
+    public static <P0,R> R applySCLRead(ReadGraph graph, Function1<P0,R> function, P0 p0) throws DatabaseException {\r
+        SCLContext sclContext = SCLContext.getCurrent();\r
+        Object oldGraph = sclContext.put("graph", graph);\r
+        try {\r
+            return function.apply(p0);\r
+        } catch (Throwable t) {\r
+            throw new DatabaseException(t);\r
+        } finally {\r
+            sclContext.put("graph", oldGraph);\r
+        }\r
+    }\r
+\r
+    public static <P0,P1,R> R applySCLRead(ReadGraph graph, Function2<P0,P1,R> function, P0 p0, P1 p1) throws DatabaseException {\r
+        SCLContext sclContext = SCLContext.getCurrent();\r
+        Object oldGraph = sclContext.put("graph", graph);\r
+        try {\r
+            return function.apply(p0, p1);\r
+        } catch (Throwable t) {\r
+            throw new DatabaseException(t);\r
+        } finally {\r
+            sclContext.put("graph", oldGraph);\r
+        }\r
+    }\r
+\r
+    public static <P0,R> R invokeSCLWrite(WriteGraph graph, Variable property, P0 p0) throws DatabaseException {\r
+        Function1<P0,R> fn = property.getPossibleValue(graph);\r
+        if(fn == null) throw new DatabaseException("No function for " + property.getURI(graph));\r
+        return Simantics.applySCLWrite(graph, fn, p0);\r
+    }\r
+\r
+    public static <P0,R> R invokeSCL(ReadGraph graph, Variable property, P0 p0) throws DatabaseException {\r
+        Function1<P0,R> fn = property.getPossibleValue(graph);\r
+        if(fn == null) throw new DatabaseException("No function for " + property.getURI(graph));\r
+        return Simantics.applySCLRead(graph, fn, p0);\r
+    }\r
+\r
+    public static <P0,P1,R> R invokeSCL(ReadGraph graph, Variable property, P0 p0, P1 p1) throws DatabaseException {\r
+        Function2<P0,P1,R> fn = property.getPossibleValue(graph);\r
+        if(fn == null) throw new DatabaseException("No function for " + property.getURI(graph));\r
+        return Simantics.applySCLRead(graph, fn, p0, p1);\r
+    }\r
+\r
+    public static <P0,R> R invokeSCLWrite(WriteGraph graph, Resource entity, Resource property, P0 p0) throws DatabaseException {\r
+        return invokeSCLWrite(graph, getProperty(graph, entity, property), p0);\r
+    }\r
+\r
+    public static <P0,R> R invokeSCL(ReadGraph graph, Resource entity, Resource property, P0 p0) throws DatabaseException {\r
+        return invokeSCL(graph, getProperty(graph, entity, property), p0);\r
+    }\r
+\r
+    public static <P0,P1,R> R invokeSCL(ReadGraph graph, Resource entity, Resource property, P0 p0, P1 p1) throws DatabaseException {\r
+        return invokeSCL(graph, getProperty(graph, entity, property), p0, p1);\r
+    }\r
+\r
+       public static <P0,R> R tryInvokeSCL(ReadGraph graph, Resource entity, Resource property, P0 p0) throws DatabaseException {\r
+       Variable p = Variables.tryGetProperty(graph, entity, property);\r
+       if (p == null)\r
+               return null;\r
+        return invokeSCL(graph, p, p0);\r
+    }\r
+\r
+       public static <P0,P1,R> R tryInvokeSCL(ReadGraph graph, Resource entity, Resource property, P0 p0, P1 p1) throws DatabaseException {\r
+       Variable p = Variables.tryGetProperty(graph, entity, property);\r
+       if (p == null)\r
+               return null;\r
+        return invokeSCL(graph, p, p0, p1);\r
+    }\r
+\r
+       private static Variable getProperty(ReadGraph graph, Resource entity, Resource property) throws DatabaseException {\r
+        return Variables.getVariable(graph, entity).getProperty(graph, property);\r
+    }\r
+\r
+    public static boolean ensureMemoryBytes(long bytes) {\r
+\r
+       Runtime runtime = Runtime.getRuntime();\r
+       long consumedMemory = runtime.totalMemory() - runtime.freeMemory();\r
+       long available = runtime.maxMemory() - consumedMemory;\r
+\r
+       return available > bytes;\r
+\r
+    }\r
+\r
+    public static long getDiskBytes() {\r
+\r
+        File ws = new File(Platform.getInstanceLocation().getURL().getFile());\r
+        return ws.getUsableSpace();\r
+\r
+    }\r
+\r
+    /**\r
+     * @return a service for dealing with recurring file system handling cases\r
+     */\r
+    public static FileService getFileService() {\r
+        FileService fs = fileService;\r
+        if (fs == null) {\r
+            synchronized (Simantics.class) {\r
+                fs = fileService;\r
+                if (fs == null)\r
+                    fs = fileService = new FileServiceImpl();\r
+            }\r
+        }\r
+        return fs;\r
+    }\r
+\r
+}\r