]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.workbench/src/org/simantics/workbench/internal/Initializer.java.keep
Initial version of SCL tab contributions
[simantics/platform.git] / bundles / org.simantics.workbench / src / org / simantics / workbench / internal / Initializer.java.keep
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.workbench.internal;\r
13 \r
14 import java.lang.reflect.InvocationTargetException;\r
15 import java.net.InetSocketAddress;\r
16 import java.util.HashSet;\r
17 import java.util.Set;\r
18 \r
19 import org.eclipse.core.runtime.IProgressMonitor;\r
20 import org.eclipse.core.runtime.IStatus;\r
21 import org.eclipse.core.runtime.MultiStatus;\r
22 import org.eclipse.core.runtime.Status;\r
23 import org.eclipse.jface.action.IAction;\r
24 import org.eclipse.jface.dialogs.ProgressMonitorDialog;\r
25 import org.eclipse.jface.operation.IRunnableWithProgress;\r
26 import org.eclipse.swt.widgets.Display;\r
27 import org.eclipse.ui.IWorkbenchWindow;\r
28 import org.simantics.application.arguments.ApplicationUtils;\r
29 import org.simantics.application.arguments.IArguments;\r
30 import org.simantics.application.arguments.SimanticsArguments;\r
31 import org.simantics.db.ReadGraph;\r
32 import org.simantics.db.Resource;\r
33 import org.simantics.db.Session;\r
34 import org.simantics.db.common.request.ReadRequest;\r
35 import org.simantics.db.common.utils.NameUtils;\r
36 import org.simantics.db.exception.DatabaseException;\r
37 import org.simantics.db.layer0.util.SimanticsKeys;\r
38 import org.simantics.db.management.ISessionContext;\r
39 import org.simantics.db.management.discovery.InetAddressUtils;\r
40 import org.simantics.db.request.Read;\r
41 import org.simantics.project.IProject;\r
42 import org.simantics.project.ProjectKeys;\r
43 import org.simantics.project.ProjectUtil;\r
44 import org.simantics.project.exception.ProjectException;\r
45 import org.simantics.project.utils.GraphPathUtils;\r
46 import org.simantics.ui.db.SessionData;\r
47 import org.simantics.ui.db.SessionRestoreUtils;\r
48 import org.simantics.ui.internal.Activator;\r
49 import org.simantics.ui.workbench.action.ChooseActionRequest;\r
50 import org.simantics.utils.ui.ExceptionUtils;\r
51 import org.simantics.utils.ui.action.IPriorityAction;\r
52 import org.simantics.utils.ui.dialogs.ShowMessage;\r
53 \r
54 public class Initializer implements Runnable {\r
55 \r
56     private final IArguments      args;\r
57 \r
58 //    private String          defaultPerspectiveId;\r
59 \r
60     /**\r
61      * This will be !ok if something fatal for startup has happened.\r
62      */\r
63     private final IStatus         status = Status.OK_STATUS;\r
64 \r
65     private ISessionContext ctx;\r
66 \r
67     private IProject        project;\r
68 \r
69     private Resource        model;\r
70 \r
71     private final IWorkbenchWindow window;\r
72 \r
73 //    private Resource        experiment;\r
74 \r
75 \r
76     public Initializer(IArguments args, IWorkbenchWindow window) {\r
77         this.args = args;\r
78         this.window = window;\r
79 //        this.defaultPerspectiveId = defaultPerspectiveId;\r
80     }\r
81 \r
82     @Override\r
83     public void run() {\r
84         try {\r
85             perform();\r
86         } catch (DatabaseException e) {\r
87             e.printStackTrace();\r
88         } catch (ProjectException e) {\r
89             e.printStackTrace();\r
90         }\r
91     }\r
92 \r
93     public IStatus getStatus() {\r
94         return status;\r
95     }\r
96 \r
97     public ISessionContext getSessionContext() {\r
98         return ctx;\r
99     }\r
100 \r
101     public IProject getProject() {\r
102         return project;\r
103     }\r
104 \r
105     public Resource getModel() {\r
106         return model;\r
107     }\r
108 \r
109     public boolean perform() throws DatabaseException, ProjectException {\r
110         // Nothing further can be done if no server is specified\r
111         if (!args.contains(SimanticsArguments.SERVER))\r
112             return true;\r
113 \r
114         // Try to connect to designated server and project.\r
115         // Use null local server location to indicate checkout\r
116         String server = args.get(SimanticsArguments.SERVER);\r
117         if(server.indexOf(':') == -1 && args.contains(SimanticsArguments.PORT)) {\r
118             server = server+":"+args.get(SimanticsArguments.PORT);\r
119         }\r
120         InetSocketAddress serverAddress = InetAddressUtils.parseUnresolved(server);\r
121         String[] projectPath = ApplicationUtils.decodePath(args.get(SimanticsArguments.PROJECT));\r
122         final SessionData data = new SessionData(null, serverAddress, projectPath);\r
123 \r
124         final MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, "Database session could not be initialized.", null);\r
125         // final ProgressMonitorDialog dialog = new ProgressMonitorDialog(null);\r
126 \r
127         final ProgressMonitorDialog dialog = new ProgressMonitorDialog(null);\r
128         try {\r
129             dialog.run(false, true, new IRunnableWithProgress() {\r
130                 @Override\r
131                 public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {\r
132                     ctx = SessionRestoreUtils.restoreSession(status, monitor, data);\r
133                     //ctx = sessionResult;\r
134                 }\r
135             });\r
136         } catch (InvocationTargetException e) {\r
137             ExceptionUtils.logAndShowError(e);\r
138         } catch (InterruptedException e) {\r
139             ExceptionUtils.logAndShowError(e);\r
140         }\r
141 \r
142         //IDiscoveryModel model =\r
143 \r
144 \r
145 //        IDiscoveryData[] iData = ProjectPlugin.getWorkspace().getDiscoveryModel().getDataSources();\r
146 //        for(int i = 0; i < iData.length; i++) {\r
147 //            IDiscoveryData d = iData[i];\r
148 //            if(d.getLabel().equals(IWorkspaceConstants.DIRECT_SERVERS_LABEL)) {\r
149 //                ServerInfo serverInfo = new ServerInfo(d.getLabel(), serverAddress);\r
150 //                ServerData serverData = new ServerData(null, serverInfo, null);\r
151 //                IServerData[] iServerData = d.getServers();\r
152 //\r
153 //                IServerData[] newServerData = new IServerData[iServerData.length+1];\r
154 //\r
155 //                int y;\r
156 //                for(y = 0; y < iServerData.length; y++) {\r
157 //                    newServerData[y] = iServerData[y];\r
158 //                }\r
159 //\r
160 //                newServerData[y] = serverData;\r
161 //\r
162 //                d.setServers(newServerData);\r
163 //                ProjectPlugin.getWorkspace().getDiscoveryModel().updateDataSource(d);\r
164 //                break;\r
165 //            }\r
166 //\r
167 //        }\r
168 \r
169         //status = sessionResult.status;\r
170         //if (!status.isOK()) {\r
171         //    return false;\r
172         //}\r
173 \r
174         if (ctx == null) {\r
175             // Its okay to start the workbench, it will just be reset as the\r
176             // connection failed.\r
177             return true;\r
178         }\r
179 \r
180         // FIXME: COMPLETE HACK for simupedia\r
181         // Add a discovery service to get in touch\r
182         /*\r
183         IDiscoveryModel discoveryModel = ProjectPlugin.getWorkspace().getDiscoveryModel();\r
184         File discoveryFile = ProjectPlugin.getDefault().getStateLocation().append("simupedia-discovery.txt").toFile();\r
185         FileWriter fw = null;\r
186         try {\r
187             // Overwrite the file.\r
188             fw = new FileWriter(discoveryFile, false);\r
189             String serverLine = String.format("'%s' %s\n", data.getAddress().getHostName(), server);\r
190             fw.write(serverLine);\r
191         } catch (IOException e) {\r
192             e.printStackTrace();\r
193         } finally {\r
194             FileUtils.uncheckedClose(fw);\r
195         }\r
196         try {\r
197             // Add a non-persistent simupedia discovery\r
198             DiscoveryData d = new DiscoveryData(IDiscoveryType.REMOTE, "Simupedia", discoveryFile);\r
199             discoveryModel.addDataSource(d);\r
200         } catch (MalformedURLException e) {\r
201             // Should never happen.\r
202             throw new Error(e);\r
203         }\r
204          */\r
205 \r
206         // Initialize project\r
207         if (args.contains(SimanticsArguments.NEW_PROJECT)) {\r
208             throw new UnsupportedOperationException();\r
209             //project = newProject(ctx);\r
210         } else if (args.contains(SimanticsArguments.PROJECT)) {\r
211             project = loadProject(ctx, projectPath);\r
212         }\r
213 \r
214         // Only proceed with model and experiment loading if a project was\r
215         // successfully created or loaded.\r
216         if (project != null) {\r
217             ctx.setHint(ProjectKeys.KEY_PROJECT, project);\r
218             ctx.setHint(SimanticsKeys.KEY_PROJECT, project.get());\r
219 \r
220             // Load model\r
221             if (args.contains(SimanticsArguments.NEW_MODEL)) {\r
222                 //model = newModel(ctx.getSession(), project);\r
223             } else if (args.contains(SimanticsArguments.MODEL)) {\r
224                 String[] modelPath = ApplicationUtils.decodePath(args.get(SimanticsArguments.MODEL));\r
225                 model = findModel(ctx.getSession(), project, modelPath);\r
226             }\r
227 //            if (model != null) {\r
228 //                findDiagram(ctx.getSession(), model, project);\r
229 //            }\r
230 \r
231             // TODO: load experiment\r
232             if (args.contains(SimanticsArguments.EXPERIMENT)) {\r
233                 // String[] experimentPath = decodePath(args.get(ProConfArguments.EXPERIMENT));\r
234             }\r
235         }\r
236 \r
237         return true;\r
238     }\r
239 \r
240     IProject loadProject(ISessionContext ctx, final String[] projectNamePath) throws DatabaseException, ProjectException {\r
241 \r
242         IProject project = ctx.getSession().syncRequest(new Read<IProject>() {\r
243 \r
244             @Override\r
245             public IProject perform(ReadGraph graph) throws DatabaseException {\r
246                 Resource projects = graph.getResource("http://Projects");\r
247                 Resource[] path = GraphPathUtils.toResourcePath(graph, projects, projectNamePath, graph\r
248                         .getBuiltins().ConsistsOf);\r
249                 if (path.length == 0) {\r
250                     IllegalArgumentException e = new IllegalArgumentException("");\r
251                     ShowMessage.showError("Error loading the existing project", e.getMessage());\r
252                     throw new DatabaseException(e);\r
253                 }\r
254                 return ProjectUtil.loadProject(graph, path[path.length - 1]);\r
255             }\r
256 \r
257         });\r
258 \r
259         project.activate();\r
260 \r
261         return project;\r
262 \r
263 //        final GraphRequestWithResult<IProject> request = new GraphRequestWithResult<IProject>() {\r
264 //            @Override\r
265 //            public IProject performWithResult(Graph g) throws Exception {\r
266 //            }\r
267 //        };\r
268 //        ctx.getSession().syncRead(request);\r
269 //        if (request.getException() != null) {\r
270 //            ShowMessage.showError("Error loading the existing project", request.getException().getMessage());\r
271 //            return null;\r
272 //        }\r
273 //        return request.getResult();\r
274     }\r
275 \r
276     Resource findModel(final Session session, final IProject project, final String[] modelPath) throws DatabaseException {\r
277 \r
278         return session.syncRequest(new Read<Resource>() {\r
279 \r
280             @Override\r
281             public Resource perform(ReadGraph graph) throws DatabaseException {\r
282                 Resource[] path = GraphPathUtils.toResourcePath(graph, project.get(), modelPath, graph\r
283                         .getBuiltins().ConsistsOf);\r
284                 if (path.length == 0) {\r
285                     IllegalArgumentException e = new IllegalArgumentException("");\r
286                     ShowMessage.showError("Error loading the existing project", e.getMessage());\r
287                     throw new DatabaseException(e);\r
288                 }\r
289                 else return path[path.length - 1];\r
290             }\r
291 \r
292         });\r
293 \r
294 //        final GraphRequestWithResult<Resource> request = new GraphRequestWithResult<Resource>() {\r
295 //            @Override\r
296 //            public Resource performWithResult(Graph g) {\r
297 //                Resource[] path = GraphPathUtils.toResourcePath(g, project.getResource(), modelPath,\r
298 //                        g.getBuiltins().ConsistsOf);\r
299 //                if (path.length == 0)\r
300 //                    throw new IllegalArgumentException("");\r
301 //                return path[path.length - 1];\r
302 //            }\r
303 //        };\r
304 //        session.syncRead(request);\r
305 //        if (request.getException() != null) {\r
306 //            ShowMessage.showError("Error loading the existing project", request.getException().getMessage());\r
307 //            return null;\r
308 //        }\r
309 //        return request.getResult();\r
310     }\r
311 \r
312     final Set<String> reservedProjectNames = new HashSet<String>();\r
313 //    IProject newProject(final ISessionContext ctx) throws DatabaseException {\r
314 //        // ---------------------------------------------------------------------\r
315 //        // Show the wizard to the user.\r
316 //        final NewProjectModel2 model = ProjectWizardUtil.initializeNewProjectModel2(new NullProgressMonitor(), ctx);\r
317 //        final NewProjectWizard2 wizard = new NewProjectWizard2(ctx.getSession(), model, null);\r
318 //        int ok = new WizardDialog(null, wizard).open();\r
319 //        if (ok != Window.OK) {\r
320 //            // User cancelled the wizard.\r
321 //            return null;\r
322 //        }\r
323 //\r
324 //        final DataContainer<IProject> project = new DataContainer<IProject>();\r
325 //\r
326 //        ctx.getSession().syncRequest(new WriteRequest() {\r
327 //\r
328 //            @Override\r
329 //            public void perform(WriteGraph g) {\r
330 //\r
331 //                try {\r
332 //\r
333 //                    // TODO: add features\r
334 //                    System.out.println("TODO: add features to project");\r
335 //                    Collection<IProjectFeatureDescriptor> fds = Collections.emptyList();\r
336 //                    Resource res = ProjectUtil.createProject(g, model.projectName, fds);\r
337 //                    project.set(ProjectUtil.loadProject(g, res, false));\r
338 //\r
339 //                } catch (Exception e) {\r
340 //                    ShowMessage.showError("Error creating new project", e.getMessage());\r
341 //                }\r
342 //\r
343 //            }\r
344 //\r
345 //        });\r
346 //\r
347 //        return project.get();\r
348 //\r
349 //    }\r
350 \r
351     /*\r
352     Resource newModel(final Session session, final IProject project) {\r
353         final ISimulationProjectParticipant sim = project.getSingleParticipant(ISimulationProjectParticipant.class);\r
354         if (sim == null)\r
355             return null;\r
356 \r
357         final Resource[] result = { null };\r
358         final Semaphore sem = new Semaphore(0);\r
359         findModelLibrary(session, project.getResource(), new RunnableWithParameter<Resource>() {\r
360             @Override\r
361             public void run(Resource modelLibrary) {\r
362                 sim.createModel(modelLibrary,\r
363                         new RunnableWithParameter<Resource>() {\r
364                     @Override\r
365                     public void run(Resource model) {\r
366                         result[0] = model;\r
367                         sem.release();\r
368                     }\r
369                 },\r
370                 new RunnableWithParameter<Throwable>() {\r
371                     @Override\r
372                     public void run(Throwable e) {\r
373                         ErrorLogger.defaultLogError("New model creation failed, see exception for details.", e);\r
374                         sem.release();\r
375                     }\r
376                 });\r
377             }\r
378         },\r
379         new RunnableWithParameter<Throwable>() {\r
380             @Override\r
381             public void run(Throwable e) {\r
382                 if (e != null)\r
383                     ErrorLogger.defaultLogError("New model creation failed, see exception for details.", e);\r
384                 else\r
385                     ErrorLogger.defaultLogError("New model creation failed, no model library found.", null);\r
386                 sem.release();\r
387             }\r
388         });\r
389 \r
390         // Wait until the model creation has finished or failed.\r
391         try {\r
392             sem.acquire();\r
393         } catch (InterruptedException e) {\r
394         }\r
395         return result[0];\r
396     }\r
397      */\r
398 \r
399     /*\r
400     void findModelLibrary(Session session,\r
401             final Resource project,\r
402             final RunnableWithParameter<Resource> libraryAction,\r
403             final RunnableWithParameter<Throwable> errorCallback)\r
404     {\r
405         // TODO: all of this is not that generic, what is someone decices he/she\r
406         // doesn't want a model library called Models at the root of his/her\r
407         // project ??\r
408 \r
409         // If the new model consists of a single diagram, open it.\r
410         session.asyncRequest(new WriteRequest() {\r
411             @Override\r
412             public void perform(WriteGraph g) throws Exception {\r
413                 Resource modelLibrary = null;\r
414                 try {\r
415                     Builtins b = g.getBuiltins();\r
416                     for (Resource r : g.getObjects2(project, b.ConsistsOf)) {\r
417                         if (g.isInstanceOf2(r, b.ModelLibrary)) {\r
418                             modelLibrary = r;\r
419                             break;\r
420                         }\r
421                     }\r
422                     // FIXME: this is definitely project specific, not generic.\r
423                     if (modelLibrary == null) {\r
424                         modelLibrary = InstanceFactory.instantiate(g, b.ModelLibrary);\r
425                         GraphUtils.addRelatedScalarString(g, modelLibrary, b.HasName, "Models");\r
426                         g.claim(project, b.ConsistsOf, modelLibrary);\r
427                     }\r
428                     libraryAction.run(modelLibrary);\r
429                 } catch (Exception e) {\r
430                     errorCallback.run(e);\r
431                 }\r
432             }\r
433         });\r
434     }\r
435      */\r
436 \r
437 //    void findDiagram(Session session, final Resource model, final IProject project) {\r
438 //        // If the new model consists of a single diagram, open it.\r
439 //        session.asyncRequest(new ReadRequest() {\r
440 //                      @Override\r
441 //                      public void run(ReadGraph g) throws DatabaseException {\r
442 //                Builtins b = g.getBuiltins();\r
443 //                DiagramResource dr = DiagramResource.getInstance(g);\r
444 //                for (Resource r : g.getObjects(model, b.ConsistsOf)) {\r
445 //                    if (g.isInstanceOf(r, dr.Diagram)) {\r
446 //                        String defaultPerspective = project.getHint(ProjectKeys.DEFAULT_PERSPECTIVE);\r
447 //                        openPreferredEditor(ctx.getSession(), r, defaultPerspective);\r
448 //                        break;\r
449 //                    }\r
450 //                }\r
451 //            }\r
452 //        });\r
453 //    }\r
454 \r
455     void openPreferredEditor(Session s, final Resource r, final String defaultPerspective) {\r
456 \r
457         s.asyncRequest(new ReadRequest() {\r
458 \r
459             @Override\r
460             public void run(ReadGraph g) throws DatabaseException {\r
461                 final String resourceName = NameUtils.getSafeName(g, r);\r
462                 final IPriorityAction[] actions = ChooseActionRequest.findActions(g, r, defaultPerspective);\r
463                 if (actions == null)\r
464                     return;\r
465                 Display.getDefault().asyncExec(new Runnable() {\r
466                     @Override\r
467                     public void run() {\r
468                         IAction action = ChooseActionRequest.chooseAction(null, actions, resourceName);\r
469                         if (action == null)\r
470                             return;\r
471                         action.run();\r
472                     }\r
473                 });\r
474             }\r
475 \r
476         });\r
477     }\r
478 \r
479 }\r