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