]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics/src/org/simantics/Simantics.java
1e01acf71f1c7cc097a418ac18deaa82c214add5
[simantics/platform.git] / bundles / org.simantics / src / org / simantics / Simantics.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics;\r
13 \r
14 import java.io.File;\r
15 import java.util.UUID;\r
16 import java.util.concurrent.ScheduledFuture;\r
17 import java.util.concurrent.TimeUnit;\r
18 \r
19 import org.eclipse.core.runtime.IProgressMonitor;\r
20 import org.eclipse.core.runtime.NullProgressMonitor;\r
21 import org.eclipse.core.runtime.Platform;\r
22 import org.simantics.SimanticsPlatform.OntologyRecoveryPolicy;\r
23 import org.simantics.SimanticsPlatform.RecoveryPolicy;\r
24 import org.simantics.application.arguments.IArguments;\r
25 import org.simantics.application.arguments.SimanticsArguments;\r
26 import org.simantics.db.ReadGraph;\r
27 import org.simantics.db.Resource;\r
28 import org.simantics.db.Session;\r
29 import org.simantics.db.WriteGraph;\r
30 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;\r
31 import org.simantics.db.exception.DatabaseException;\r
32 import org.simantics.db.exception.RuntimeDatabaseException;\r
33 import org.simantics.db.indexing.IndexUtils;\r
34 import org.simantics.db.layer0.util.SimanticsClipboard;\r
35 import org.simantics.db.layer0.util.SimanticsKeys;\r
36 import org.simantics.db.layer0.variable.Variable;\r
37 import org.simantics.db.layer0.variable.Variables;\r
38 import org.simantics.db.management.ISessionContext;\r
39 import org.simantics.db.management.ISessionContextProvider;\r
40 import org.simantics.db.management.ISessionContextProviderSource;\r
41 import org.simantics.db.management.SessionContextProvider;\r
42 import org.simantics.db.management.SingleSessionContextProviderSource;\r
43 import org.simantics.db.request.ReadInterface;\r
44 import org.simantics.db.request.WriteInterface;\r
45 import org.simantics.internal.FileServiceImpl;\r
46 import org.simantics.layer0.Layer0;\r
47 import org.simantics.project.IProject;\r
48 import org.simantics.project.ProjectKeys;\r
49 import org.simantics.scl.compiler.top.ValueNotFound;\r
50 import org.simantics.scl.osgi.SCLOsgi;\r
51 import org.simantics.scl.runtime.SCLContext;\r
52 import org.simantics.scl.runtime.function.Function;\r
53 import org.simantics.scl.runtime.function.Function1;\r
54 import org.simantics.scl.runtime.function.Function2;\r
55 import org.simantics.utils.FileService;\r
56 import org.simantics.utils.FileUtils;\r
57 import org.simantics.utils.TempFiles;\r
58 import org.simantics.utils.threads.ThreadUtils;\r
59 \r
60 /**\r
61  * A facade for accessing basic Simantics platform services. Usable without a\r
62  * graphical UI, i.e. in headless contexts.\r
63  *\r
64  * TODO: in time, move headless functionality of SimanticsUI into this class but\r
65  * originals as delegates in SimanticsUI.\r
66  *\r
67  * TODO: duplicate of org.simantics.db.layer0.util.Simantics, do something about this!!\r
68  */\r
69 public class Simantics {\r
70 \r
71     private static ISessionContextProviderSource providerSource = null;\r
72     private static volatile FileServiceImpl fileService = null;\r
73 \r
74     /**\r
75      * @param args\r
76      * @param progress\r
77      * @return\r
78      * @throws PlatformException\r
79      */\r
80     public static ISessionContext startUpHeadless(IArguments args, IProgressMonitor progress) throws PlatformException {\r
81         if (SimanticsPlatform.INSTANCE.sessionContext != null) {\r
82             throw new RuntimeDatabaseException("Simantics is already up and running.");\r
83         }\r
84 \r
85         RecoveryPolicy workspacePolicy = Platform.inDevelopmentMode() ? RecoveryPolicy.FixError : RecoveryPolicy.ThrowError;\r
86         OntologyRecoveryPolicy ontologyPolicy = Platform.inDevelopmentMode() ? OntologyRecoveryPolicy.Merge : OntologyRecoveryPolicy.ThrowError;\r
87 \r
88         if (args.contains(SimanticsArguments.RECOVERY_POLICY_FIX_ERRORS)) {\r
89             workspacePolicy = RecoveryPolicy.FixError;\r
90             ontologyPolicy = OntologyRecoveryPolicy.Merge;\r
91         }\r
92 \r
93         if (args.contains(SimanticsArguments.ONTOLOGY_RECOVERY_POLICY_REINSTALL)) {\r
94             ontologyPolicy = OntologyRecoveryPolicy.ReinstallDatabase;\r
95         }\r
96 \r
97         if (args.contains(SimanticsArguments.ONTOLOGY_RECOVERY_POLICY_REINSTALL)) {\r
98             ontologyPolicy = OntologyRecoveryPolicy.ReinstallDatabase;\r
99         }\r
100 \r
101         int localPort = 0;\r
102         if (args.contains(SimanticsArguments.LOCAL_SERVER_PORT)) {\r
103             try {\r
104                 localPort = args.get(SimanticsArguments.LOCAL_SERVER_PORT);\r
105             } catch (IllegalArgumentException e) {\r
106                 throw new PlatformException("Failed to open database session", e);\r
107             }\r
108         }\r
109 \r
110 //        ServerAddress remoteDatabase = null;\r
111 //        if (args.contains(SimanticsArguments.SERVER)) {\r
112 //            String serverAddress = args.get(SimanticsArguments.SERVER);\r
113 //            try {\r
114 //                remoteDatabase = new ServerAddress(serverAddress);\r
115 //            } catch (IllegalArgumentException e) {\r
116 //                throw new PlatformException("Failed to open database session", e);\r
117 //            }\r
118 //        }\r
119 \r
120         return startUpHeadless(progress, workspacePolicy, ontologyPolicy, localPort /*, remoteDatabase*/);\r
121     }\r
122 \r
123     /**\r
124      * @param progress\r
125      * @param workspacePolicy\r
126      * @param ontologyPolicy\r
127      * @param localPort\r
128      * @param remoteDatabase\r
129      * @return\r
130      * @throws PlatformException\r
131      */\r
132     public static ISessionContext startUpHeadless(IProgressMonitor progress, RecoveryPolicy workspacePolicy, OntologyRecoveryPolicy ontologyPolicy, int localPort) throws PlatformException {\r
133         if (SimanticsPlatform.INSTANCE.sessionContext != null) {\r
134             throw new RuntimeDatabaseException("Simantics is already up and running.");\r
135         }\r
136 \r
137         // Set session context provider.\r
138         final ISessionContextProvider provider = new SessionContextProvider(null);\r
139         ISessionContextProviderSource source = new SingleSessionContextProviderSource(provider);\r
140         setSessionContextProviderSource(source);\r
141         org.simantics.db.layer0.internal.SimanticsInternal.setSessionContextProviderSource(source);\r
142 \r
143         if (progress == null)\r
144             progress = new NullProgressMonitor();\r
145         return SimanticsPlatform.INSTANCE.startUp(null, progress, workspacePolicy, ontologyPolicy, true, new ConsoleUserAgent());\r
146     }\r
147 \r
148     /**\r
149      * @param progress\r
150      * @throws PlatformException\r
151      */\r
152     public static void shutdown(IProgressMonitor progress) throws PlatformException {\r
153         SimanticsPlatform.INSTANCE.shutdown(progress);\r
154     }\r
155 \r
156     /**\r
157      * Queue execution of a runnable.\r
158      *\r
159      * @param runnable\r
160      */\r
161     public static void async(Runnable runnable) {\r
162         ThreadUtils.getBlockingWorkExecutor().execute(runnable);\r
163     }\r
164 \r
165     public static void async(Runnable runnable, int delay, TimeUnit unit) {\r
166         ThreadUtils.getTimer().schedule(runnable, delay, unit);\r
167     }\r
168 \r
169     public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, int initialDelay, int period, TimeUnit unit) {\r
170         return ThreadUtils.getTimer().scheduleAtFixedRate(runnable, initialDelay, period, unit);\r
171     }\r
172 \r
173     /**\r
174      * Queue execution of a non-blocking runnable. Use this method with caution.\r
175      * A non-blocking runnable nevers locks anything, No Locks, No semaphores,\r
176      * No Object.wait(), No synchronized() {} blocks.\r
177      *\r
178      * @param runnable a non-blocking runnable\r
179      */\r
180     public static void asyncNonblocking(Runnable runnable) {\r
181         ThreadUtils.getNonBlockingWorkExecutor().execute(runnable);\r
182     }\r
183 \r
184     /**\r
185      * Schedule execution of a non-blocking runnable. Use this method with caution.\r
186      * A non-blocking runnable never locks anything, No Locks, No semaphores,\r
187      * No Object,wait(), No synchronized() {} blocks.\r
188      *\r
189      * @param runnable a non-blocking runnable\r
190      * @param initialDelay\r
191      * @param period\r
192      */\r
193     public static void asyncNonblocking(Runnable runnable, int initialDelay, int period) {\r
194         ThreadUtils.getNonBlockingWorkExecutor().scheduleAtFixedRate(runnable, initialDelay, period, TimeUnit.MILLISECONDS);\r
195     }\r
196 \r
197     public static synchronized ISessionContext setSessionContext(ISessionContext ctx) {\r
198         return getSessionContextProvider().setSessionContext(ctx);\r
199     }\r
200 \r
201     public static void setSessionContextProviderSource(ISessionContextProviderSource source) {\r
202         if (source == null)\r
203             throw new IllegalArgumentException("null provider source");\r
204         providerSource = source;\r
205     }\r
206 \r
207     public static ISessionContextProviderSource getProviderSource() {\r
208         if (providerSource == null)\r
209             throw new IllegalStateException(\r
210             "providerSource must be initialized by the application before using class Simantics");\r
211         return providerSource;\r
212     }\r
213 \r
214     public static ISessionContextProvider getSessionContextProvider() {\r
215         return getProviderSource().getActive();\r
216     }\r
217 \r
218     /**\r
219      * Returns the database session context associated with the currently active\r
220      * context. This method should be used to retrieve session contexts only\r
221      * when the client is sure that the correct context is active.\r
222      *\r
223      * @return the session context associated with the currently active context\r
224      *         or <code>null</code> if the context has no session context\r
225      */\r
226     public static ISessionContext getSessionContext() {\r
227         ISessionContextProvider provider = getSessionContextProvider();\r
228         return provider != null ? provider.getSessionContext() : null;\r
229     }\r
230 \r
231     /**\r
232      * Returns the database Session bound to the currently active context.\r
233      *\r
234      * <p>\r
235      * The method always returns a non-null Session or produces an\r
236      * IllegalStateException if a Session was not attainable.\r
237      * </p>\r
238      *\r
239      * @return the Session bound to the currently active workbench window\r
240      * @throws IllegalStateException if no Session was available\r
241      */\r
242     public static Session getSession() {\r
243         ISessionContext ctx = getSessionContext();\r
244         if (ctx == null)\r
245             throw new IllegalStateException("Session unavailable, no database session open");\r
246         return ctx.getSession();\r
247     }\r
248 \r
249     /**\r
250      * Returns the database Session bound to the currently active context.\r
251      * Differently from {@link #getSession()}, this method returns\r
252      * <code>null</code> if there is no current Session available.\r
253      *\r
254      * @see #getSession()\r
255      * @return the Session bound to the currently active context or\r
256      *         <code>null</code>\r
257      */\r
258     public static Session peekSession() {\r
259         ISessionContext ctx = getSessionContext();\r
260         return ctx == null ? null : ctx.peekSession();\r
261     }\r
262 \r
263     /**\r
264      * @return the currently open and active project as a Resource\r
265      * @throws IllegalStateException if there is no currently active database\r
266      *         session, which also means there is no active project at the\r
267      *         moment\r
268      */\r
269     public static Resource getProjectResource() {\r
270         ISessionContext ctx = getSessionContext();\r
271         if (ctx == null)\r
272             throw new IllegalStateException("No current database session");\r
273         Resource project = ctx.getHint(SimanticsKeys.KEY_PROJECT);\r
274         if (project == null)\r
275             throw new IllegalStateException("No current project resource in session context " + ctx);\r
276         return project;\r
277     }\r
278 \r
279     /**\r
280      * @return the currently open and active project as a {@link Resource}\r
281      */\r
282     public static Resource peekProjectResource() {\r
283         ISessionContext ctx = getSessionContext();\r
284         return ctx != null ? ctx.<Resource>getHint(SimanticsKeys.KEY_PROJECT) : null;\r
285     }\r
286 \r
287     /**\r
288      * @return the currently open and active project as an {@link IProject}\r
289      * @throws IllegalStateException if there is no currently active database\r
290      *         session, which also means there is no active project at the\r
291      *         moment\r
292      */\r
293     public static IProject getProject() {\r
294         ISessionContext ctx = getSessionContext();\r
295         if (ctx == null)\r
296             throw new IllegalStateException("No current database session");\r
297         IProject project = ctx.getHint(ProjectKeys.KEY_PROJECT);\r
298         if (project == null)\r
299             throw new IllegalStateException("No current project in session context " + ctx);\r
300         return project;\r
301     }\r
302 \r
303     /**\r
304      * @return the currently open and active project as an {@link IProject} or\r
305      *         <code>null</code> if there is no active session or project\r
306      */\r
307     public static IProject peekProject() {\r
308         ISessionContext ctx = getSessionContext();\r
309         return ctx == null ? null : ctx.<IProject>getHint(ProjectKeys.KEY_PROJECT);\r
310     }\r
311 \r
312     // FIXME: once org.simantics.db.layer0.util.Simantics is gone, re-enable this\r
313 //    private static SimanticsClipboard clipboard = SimanticsClipboard.EMPTY;\r
314 \r
315     /**\r
316      * @param content\r
317      */\r
318     public static void setClipboard(SimanticsClipboard content) {\r
319         // FIXME: once org.simantics.db.layer0.util.Simantics is gone, re-enable this\r
320 //        if (content == null)\r
321 //            throw new NullPointerException("null clipboard content");\r
322 //        clipboard = content;\r
323         org.simantics.db.layer0.internal.SimanticsInternal.setClipboard(content);\r
324     }\r
325 \r
326     public static SimanticsClipboard getClipboard() {\r
327         // FIXME: once org.simantics.db.layer0.util.Simantics is gone, re-enable this\r
328         //return clipboard;\r
329         return org.simantics.db.layer0.internal.SimanticsInternal.getClipboard();\r
330     }\r
331 \r
332     public static Layer0 getLayer0() throws DatabaseException {\r
333         return Layer0.getInstance(getSession());\r
334     }\r
335 \r
336     public static <T> T sync(ReadInterface<T> r) throws DatabaseException {\r
337         return getSession().sync(r);\r
338     }\r
339 \r
340     public static <T> T sync(WriteInterface<T> r) throws DatabaseException {\r
341         return getSession().sync(r);\r
342     }\r
343 \r
344     public static <T> void async(ReadInterface<T> r) {\r
345         getSession().async(r, new ProcedureAdapter<T>());\r
346     }\r
347 \r
348     public static <T> void async(WriteInterface<T> r) {\r
349         getSession().async(r);\r
350     }\r
351 \r
352     public static void clearTemporaryDirectory() {\r
353         FileUtils.deleteDir(getTemporaryDirectory());\r
354     }\r
355 \r
356     public static File getTempfile(String directory, String suffix) {\r
357         File dir = getTemporaryDirectory(directory);\r
358         return new File(dir, UUID.randomUUID().toString() + "." + suffix);\r
359     }\r
360 \r
361     public static File getTemporaryDirectory(String directory) {\r
362         File sub = new File(getTemporaryDirectory(), directory);\r
363         sub.mkdirs();\r
364         return sub;\r
365     }\r
366 \r
367     public static File getTemporaryDirectory() {\r
368         File workspace = Platform.getLocation().toFile();\r
369         File temp = new File(workspace, "tempFiles");\r
370         temp.mkdirs();\r
371         return temp;\r
372     }\r
373 \r
374     public static TempFiles getTempFiles() {\r
375         return TEMP_FILES;\r
376     }\r
377 \r
378     private static class TempFilesImpl implements TempFiles {\r
379         private final TempFilesImpl parent;\r
380         private final String prefix;\r
381         private final String fullPrefix;\r
382 \r
383         private TempFilesImpl(TempFilesImpl parent, String directory) {\r
384             this.parent = parent;\r
385             this.prefix = directory;\r
386             this.fullPrefix = getPrefix(new StringBuilder()).toString();\r
387         }\r
388 \r
389         private StringBuilder getPrefix(StringBuilder sb) {\r
390             if (parent != null)\r
391                 parent.getPrefix(sb);\r
392             if (prefix != null && !prefix.isEmpty())\r
393                 sb.append(prefix).append(File.separatorChar);\r
394             return sb;\r
395         }\r
396 \r
397         @Override\r
398         public File getRoot() {\r
399             return Simantics.getTemporaryDirectory(fullPrefix);\r
400         }\r
401 \r
402         @Override\r
403         public File getTempfile(String directory, String suffix) {\r
404             return Simantics.getTempfile(fullPrefix.isEmpty() ? directory : fullPrefix + directory, suffix);\r
405         }\r
406 \r
407         @Override\r
408         public TempFiles subdirectory(String directory) {\r
409             return new TempFilesImpl(this, directory);\r
410         }\r
411     }\r
412 \r
413     public static TempFiles TEMP_FILES = new TempFilesImpl(null, null);\r
414 \r
415     public static void flushIndexCaches(IProgressMonitor progress, Session session) {\r
416         try {\r
417             IndexUtils.flushIndexCaches(progress, session);\r
418         } catch (Exception e) {\r
419             Logger.defaultLogError(e);\r
420         }\r
421     }\r
422 \r
423 \r
424     @SuppressWarnings({ "unchecked", "rawtypes" })\r
425         public static <T> T applySCL(String module, String function, ReadGraph graph, Object ... args) throws DatabaseException {\r
426         SCLContext sclContext = SCLContext.getCurrent();\r
427             Object oldGraph = sclContext.put("graph", graph);\r
428                 try {\r
429                         T t = (T)((Function)SCLOsgi.MODULE_REPOSITORY.getValue(module, function)).applyArray(args);\r
430                         return t;\r
431                 } catch (ValueNotFound e) {\r
432                         throw new DatabaseException("SCL Value not found: " + e.name);\r
433                 } catch (Throwable t) {\r
434                         throw new DatabaseException(t);\r
435                 } finally {\r
436                         sclContext.put("graph", oldGraph);\r
437                 }\r
438 \r
439     }\r
440 \r
441     @SuppressWarnings("unchecked")\r
442     public static <T> T applySCLWrite(WriteGraph graph, @SuppressWarnings("rawtypes") Function f, Object ... args) throws DatabaseException {\r
443         SCLContext sclContext = SCLContext.getCurrent();\r
444         Object oldGraph = sclContext.put("graph", graph);\r
445         try {\r
446             return (T)f.applyArray(args);\r
447         } catch (Throwable t) {\r
448             throw new DatabaseException(t);\r
449         } finally {\r
450             sclContext.put("graph", oldGraph);\r
451         }\r
452     }\r
453 \r
454     @SuppressWarnings("unchecked")\r
455     public static <T> T applySCLRead(ReadGraph graph, @SuppressWarnings("rawtypes") Function f, Object ... args) throws DatabaseException {\r
456         SCLContext sclContext = SCLContext.getCurrent();\r
457         Object oldGraph = sclContext.put("graph", graph);\r
458         try {\r
459             return (T)f.applyArray(args);\r
460         } catch (Throwable t) {\r
461             throw new DatabaseException(t);\r
462         } finally {\r
463             sclContext.put("graph", oldGraph);\r
464         }\r
465     }\r
466     \r
467     public static <P0,R> R applySCLWrite(WriteGraph graph, Function1<P0,R> function, P0 p0) throws DatabaseException {\r
468         SCLContext sclContext = SCLContext.getCurrent();\r
469         Object oldGraph = sclContext.put("graph", graph);\r
470         try {\r
471             return function.apply(p0);\r
472         } catch (Throwable t) {\r
473             throw new DatabaseException(t);\r
474         } finally {\r
475             sclContext.put("graph", oldGraph);\r
476         }\r
477     }\r
478 \r
479     public static <P0,R> R applySCLRead(ReadGraph graph, Function1<P0,R> function, P0 p0) throws DatabaseException {\r
480         SCLContext sclContext = SCLContext.getCurrent();\r
481         Object oldGraph = sclContext.put("graph", graph);\r
482         try {\r
483             return function.apply(p0);\r
484         } catch (Throwable t) {\r
485             throw new DatabaseException(t);\r
486         } finally {\r
487             sclContext.put("graph", oldGraph);\r
488         }\r
489     }\r
490 \r
491     public static <P0,P1,R> R applySCLRead(ReadGraph graph, Function2<P0,P1,R> function, P0 p0, P1 p1) throws DatabaseException {\r
492         SCLContext sclContext = SCLContext.getCurrent();\r
493         Object oldGraph = sclContext.put("graph", graph);\r
494         try {\r
495             return function.apply(p0, p1);\r
496         } catch (Throwable t) {\r
497             throw new DatabaseException(t);\r
498         } finally {\r
499             sclContext.put("graph", oldGraph);\r
500         }\r
501     }\r
502 \r
503     public static <P0,R> R invokeSCLWrite(WriteGraph graph, Variable property, P0 p0) throws DatabaseException {\r
504         Function1<P0,R> fn = property.getPossibleValue(graph);\r
505         if(fn == null) throw new DatabaseException("No function for " + property.getURI(graph));\r
506         return Simantics.applySCLWrite(graph, fn, p0);\r
507     }\r
508 \r
509     public static <P0,R> R invokeSCL(ReadGraph graph, Variable property, P0 p0) throws DatabaseException {\r
510         Function1<P0,R> fn = property.getPossibleValue(graph);\r
511         if(fn == null) throw new DatabaseException("No function for " + property.getURI(graph));\r
512         return Simantics.applySCLRead(graph, fn, p0);\r
513     }\r
514 \r
515     public static <P0,P1,R> R invokeSCL(ReadGraph graph, Variable property, P0 p0, P1 p1) throws DatabaseException {\r
516         Function2<P0,P1,R> fn = property.getPossibleValue(graph);\r
517         if(fn == null) throw new DatabaseException("No function for " + property.getURI(graph));\r
518         return Simantics.applySCLRead(graph, fn, p0, p1);\r
519     }\r
520 \r
521     public static <P0,R> R invokeSCLWrite(WriteGraph graph, Resource entity, Resource property, P0 p0) throws DatabaseException {\r
522         return invokeSCLWrite(graph, getProperty(graph, entity, property), p0);\r
523     }\r
524 \r
525     public static <P0,R> R invokeSCL(ReadGraph graph, Resource entity, Resource property, P0 p0) throws DatabaseException {\r
526         return invokeSCL(graph, getProperty(graph, entity, property), p0);\r
527     }\r
528 \r
529     public static <P0,P1,R> R invokeSCL(ReadGraph graph, Resource entity, Resource property, P0 p0, P1 p1) throws DatabaseException {\r
530         return invokeSCL(graph, getProperty(graph, entity, property), p0, p1);\r
531     }\r
532 \r
533         public static <P0,R> R tryInvokeSCL(ReadGraph graph, Resource entity, Resource property, P0 p0) throws DatabaseException {\r
534         Variable p = Variables.tryGetProperty(graph, entity, property);\r
535         if (p == null)\r
536                 return null;\r
537         return invokeSCL(graph, p, p0);\r
538     }\r
539 \r
540         public static <P0,P1,R> R tryInvokeSCL(ReadGraph graph, Resource entity, Resource property, P0 p0, P1 p1) throws DatabaseException {\r
541         Variable p = Variables.tryGetProperty(graph, entity, property);\r
542         if (p == null)\r
543                 return null;\r
544         return invokeSCL(graph, p, p0, p1);\r
545     }\r
546 \r
547         private static Variable getProperty(ReadGraph graph, Resource entity, Resource property) throws DatabaseException {\r
548         return Variables.getVariable(graph, entity).getProperty(graph, property);\r
549     }\r
550 \r
551     public static boolean ensureMemoryBytes(long bytes) {\r
552 \r
553         Runtime runtime = Runtime.getRuntime();\r
554         long consumedMemory = runtime.totalMemory() - runtime.freeMemory();\r
555         long available = runtime.maxMemory() - consumedMemory;\r
556 \r
557         return available > bytes;\r
558 \r
559     }\r
560 \r
561     public static long getDiskBytes() {\r
562 \r
563         File ws = new File(Platform.getInstanceLocation().getURL().getFile());\r
564         return ws.getUsableSpace();\r
565 \r
566     }\r
567 \r
568     /**\r
569      * @return a service for dealing with recurring file system handling cases\r
570      */\r
571     public static FileService getFileService() {\r
572         FileService fs = fileService;\r
573         if (fs == null) {\r
574             synchronized (Simantics.class) {\r
575                 fs = fileService;\r
576                 if (fs == null)\r
577                     fs = fileService = new FileServiceImpl();\r
578             }\r
579         }\r
580         return fs;\r
581     }\r
582 \r
583 }\r