]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java
cfc3f4f1579c5f232c6f6746d4af913d7f1b9d1d
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / GraphModuleSourceRepository.java
1 package org.simantics.modeling.scl;\r
2 \r
3 import org.simantics.Simantics;\r
4 import org.simantics.db.ReadGraph;\r
5 import org.simantics.db.RequestProcessorSpecific;\r
6 import org.simantics.db.Resource;\r
7 import org.simantics.db.WriteGraph;\r
8 import org.simantics.db.common.request.UnaryRead;\r
9 import org.simantics.db.common.request.WriteRequest;\r
10 import org.simantics.db.exception.DatabaseException;\r
11 import org.simantics.db.procedure.SyncListener;\r
12 import org.simantics.db.request.Read;\r
13 import org.simantics.layer0.Layer0;\r
14 import org.simantics.modeling.ModelingUtils;\r
15 import org.simantics.scl.compiler.module.repository.UpdateListener;\r
16 import org.simantics.scl.compiler.source.ModuleSource;\r
17 import org.simantics.scl.compiler.source.StringModuleSource;\r
18 import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;\r
19 import org.simantics.scl.runtime.SCLContext;\r
20 \r
21 import gnu.trove.procedure.TObjectProcedure;\r
22 import gnu.trove.set.hash.THashSet;\r
23 \r
24 public enum GraphModuleSourceRepository implements ModuleSourceRepository {\r
25     INSTANCE;\r
26 \r
27     @Override\r
28     public ModuleSource getModuleSource(final String moduleName, UpdateListener listener) {\r
29         if(!moduleName.startsWith("http://"))\r
30             return null;\r
31 \r
32         Object graph = SCLContext.getCurrent().get("graph");\r
33         RequestProcessorSpecific requestProcessor;\r
34         if(graph instanceof ReadGraph)\r
35             requestProcessor = (ReadGraph)graph;\r
36         else\r
37             requestProcessor = Simantics.getSession();\r
38 \r
39         Read<ModuleSource> request = new ReadModuleSource(moduleName);\r
40 \r
41         try {\r
42             if(listener != null)\r
43                 return requestProcessor.syncRequest(request, new ModuleListener(listener, moduleName));\r
44             else\r
45                 return requestProcessor.syncRequest(request);\r
46         } catch (DatabaseException e) {\r
47             e.printStackTrace();\r
48             return null;\r
49         }\r
50     }\r
51 \r
52     static class ModuleListener implements SyncListener<ModuleSource> {\r
53         UpdateListener listener;\r
54         boolean alreadyExecutedOnce;\r
55         final String moduleName;\r
56         public ModuleListener(UpdateListener listener, String moduleName) {\r
57             this.listener = listener;\r
58             this.moduleName = moduleName;\r
59         }\r
60         @Override\r
61         public boolean isDisposed() {\r
62             return listener == null;\r
63         }\r
64         private void fireUpdate(ReadGraph graph) {\r
65             if(listener != null) {\r
66                 SCLContext context = SCLContext.getCurrent();\r
67                 Object oldGraph = context.put("graph", graph);\r
68                 try {\r
69                     listener.notifyAboutUpdate();\r
70                 } finally {\r
71                     listener = null;\r
72                     context.put("graph", oldGraph);\r
73                 }\r
74             }\r
75         }\r
76         @Override\r
77         public void execute(ReadGraph graph, ModuleSource result)\r
78                 throws DatabaseException {\r
79             if(alreadyExecutedOnce)\r
80                 fireUpdate(graph);\r
81             else\r
82                 alreadyExecutedOnce = true;\r
83         }\r
84         @Override\r
85         public void exception(ReadGraph graph, Throwable t)\r
86                 throws DatabaseException {\r
87             t.printStackTrace();\r
88             if(alreadyExecutedOnce && listener != null)\r
89                 fireUpdate(graph);\r
90         }\r
91     };\r
92     \r
93     public static class GraphModuleSource extends StringModuleSource {\r
94 \r
95         public GraphModuleSource(String moduleName, ClassLoader classLoader, String moduleText) {\r
96             super(moduleName, classLoader, moduleText);\r
97         }\r
98         \r
99         @Override\r
100         public boolean isUpdateable() {\r
101             return true;\r
102         }\r
103         \r
104         @Override\r
105         public void update(String newSourceText) {\r
106             try {\r
107                 Simantics.getSession().syncRequest(new WriteModuleSource(getModuleName(), newSourceText));\r
108             } catch (DatabaseException e) {\r
109                 e.printStackTrace();\r
110             }\r
111         }\r
112     }\r
113 \r
114     static class ReadModuleSource extends UnaryRead<String, ModuleSource> {\r
115         public ReadModuleSource(String moduleName) {\r
116             super(moduleName);\r
117         }\r
118 \r
119         @Override\r
120         public ModuleSource perform(ReadGraph graph) throws DatabaseException {\r
121             Resource moduleResource = graph.getPossibleResource(parameter);\r
122             if(moduleResource == null)\r
123                 return null;\r
124             Layer0 L0 = Layer0.getInstance(graph);\r
125             if(!graph.isInstanceOf(moduleResource, L0.SCLModule))\r
126                 return null;\r
127             String text = graph.getRelatedValue(moduleResource, L0.SCLModule_definition);\r
128             return new GraphModuleSource(parameter, getClass().getClassLoader(), text);\r
129         }\r
130     }\r
131     \r
132     static class WriteModuleSource extends WriteRequest {\r
133         private final String moduleURI;\r
134         private final String sourceText;\r
135         \r
136         public WriteModuleSource(String moduleURI, String sourceText) {\r
137             this.moduleURI = moduleURI;\r
138             this.sourceText = sourceText;\r
139         }\r
140 \r
141         @Override\r
142         public void perform(WriteGraph graph) throws DatabaseException {\r
143             Resource moduleResource = graph.getPossibleResource(moduleURI);\r
144             if(moduleResource == null)\r
145                 return;\r
146             Layer0 L0 = Layer0.getInstance(graph);\r
147             if(!graph.isInstanceOf(moduleResource, L0.SCLModule))\r
148                 return;\r
149             graph.claimLiteral(moduleResource, L0.SCLModule_definition, sourceText);\r
150         }\r
151     }\r
152 \r
153     @Override\r
154     public void forAllModules(TObjectProcedure<String> procedure) {\r
155         THashSet<String> moduleURIs;\r
156         try {\r
157             moduleURIs = Simantics.getSession().syncRequest(new Read<THashSet<String>>() {\r
158                 @Override\r
159                 public THashSet<String> perform(ReadGraph graph)\r
160                         throws DatabaseException {\r
161                     THashSet<String> result = new THashSet<String>(); \r
162                     Resource projectResource = Simantics.getProjectResource();\r
163                     Layer0 L0 = Layer0.getInstance(graph);\r
164                     for(Resource model : graph.getObjects(projectResource, L0.ConsistsOf)) {\r
165                         if(graph.isInstanceOf(model, L0.IndexRoot)) {\r
166                             for(Resource module : ModelingUtils.searchByType(graph, model, L0.SCLModule))\r
167                                 result.add(graph.getURI(module));\r
168                         }\r
169                     }\r
170                     return result;\r
171                 }\r
172             });\r
173             moduleURIs.forEach(procedure);\r
174         } catch (DatabaseException e) {\r
175             e.printStackTrace();\r
176         }\r
177     }\r
178 \r
179     @Override\r
180     public void checkUpdates() {\r
181     }\r
182 \r
183     @Override\r
184     public String getDocumentation(String documentationName) {\r
185         return null;\r
186     }\r
187 \r
188     @Override\r
189     public void forAllDocumentations(TObjectProcedure<String> procedure) {\r
190     }\r
191 \r
192     @Override\r
193     public void clear() {\r
194     }\r
195 }\r