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