]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/sharedontology/wizard/SharedOntologyImportWizard.java
Improved error handling in shared library import wizard
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / sharedontology / wizard / SharedOntologyImportWizard.java
1 /*******************************************************************************
2  * Copyright (c) 2012 Association for Decentralized Information Management in
3  * 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.modeling.ui.sharedontology.wizard;
13
14 import java.io.File;
15 import java.io.IOException;
16 import java.lang.reflect.InvocationTargetException;
17 import java.util.Deque;
18 import java.util.HashMap;
19 import java.util.Map;
20
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.SubMonitor;
23 import org.eclipse.core.runtime.preferences.InstanceScope;
24 import org.eclipse.jface.operation.IRunnableWithProgress;
25 import org.eclipse.jface.preference.IPersistentPreferenceStore;
26 import org.eclipse.jface.preference.IPreferenceStore;
27 import org.eclipse.jface.viewers.IStructuredSelection;
28 import org.eclipse.jface.wizard.Wizard;
29 import org.eclipse.jface.wizard.WizardPage;
30 import org.eclipse.ui.IImportWizard;
31 import org.eclipse.ui.IWorkbench;
32 import org.eclipse.ui.preferences.ScopedPreferenceStore;
33 import org.simantics.databoard.binding.Binding;
34 import org.simantics.databoard.binding.mutable.Variant;
35 import org.simantics.databoard.container.DataContainer;
36 import org.simantics.databoard.container.DataContainers;
37 import org.simantics.databoard.container.FormatHandler;
38 import org.simantics.db.Resource;
39 import org.simantics.db.Session;
40 import org.simantics.db.layer0.migration.MigrationUtils;
41 import org.simantics.db.layer0.util.DraftStatusBean;
42 import org.simantics.db.management.ISessionContext;
43 import org.simantics.graph.db.MissingDependencyException;
44 import org.simantics.graph.representation.TransferableGraph1;
45 import org.simantics.modeling.ui.Activator;
46 import org.simantics.modeling.ui.utils.NoProjectPage;
47 import org.simantics.project.IProject;
48 import org.simantics.project.ProjectKeys;
49 import org.simantics.ui.SimanticsUI;
50 import org.simantics.ui.utils.ResourceAdaptionUtils;
51 import org.simantics.utils.ui.ErrorLogger;
52 import org.simantics.utils.ui.ExceptionUtils;
53
54 /**
55  * @author Tuukka Lehtonen
56  */
57 public class SharedOntologyImportWizard extends Wizard implements IImportWizard {
58
59     private static final int MAX_RECENT_IMPORT_PATHS = 10;
60
61     ImportPlan        importModel;
62
63     private boolean readPreferences(IStructuredSelection selection) {
64         IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);
65
66         String recentPathsPref = store.getString(Preferences.RECENT_SHARED_LIBRARY_IMPORT_LOCATIONS);
67         Deque<String> recentImportPaths = Preferences.decodePaths(recentPathsPref);
68
69         ISessionContext ctx = SimanticsUI.getSessionContext();
70         if (ctx == null)
71             return false;
72         IProject project = ctx.getHint(ProjectKeys.KEY_PROJECT);
73         if (project == null)
74             return false;
75
76         importModel = new ImportPlan(ctx, recentImportPaths);
77         importModel.project = project;
78         importModel.selection = selection.getFirstElement();
79
80         return true;
81     }
82
83     private void writePreferences() throws IOException {
84         IPersistentPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);
85
86         store.putValue(Preferences.RECENT_SHARED_LIBRARY_IMPORT_LOCATIONS, Preferences.encodePaths(importModel.recentLocations));
87
88         if (store.needsSaving())
89             store.save();
90     }
91
92     public SharedOntologyImportWizard() {
93         setWindowTitle("Import Shared Library");
94         setNeedsProgressMonitor(true);
95     }
96
97     @Override
98     public void init(IWorkbench workbench, IStructuredSelection selection) {
99         readPreferences(selection);
100     }
101
102     @Override
103     public void addPages() {
104         super.addPages();
105         if (importModel != null) {
106             addPage(new SharedOntologyImportPage(importModel));
107         } else {
108             addPage(new NoProjectPage("Import Shared Library"));
109         }
110     }
111
112     @Override
113     public boolean performFinish() {
114         try {
115             importModel.recentLocations.addFirst(importModel.importLocation.getAbsolutePath());
116             Preferences.removeDuplicates(importModel.recentLocations);
117             if (importModel.recentLocations.size() > MAX_RECENT_IMPORT_PATHS)
118                 importModel.recentLocations.pollLast();
119
120             writePreferences();
121         } catch (IOException e) {
122             ErrorLogger.defaultLogError("Failed to write preferences", e);
123         }
124
125         try {
126             getContainer().run(true, true, new IRunnableWithProgress() {
127                 @Override
128                 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
129                     try {
130                         Resource target = ResourceAdaptionUtils.toSingleResource(importModel.selection);
131                         importModel.sessionContext.getSession().markUndoPoint();
132                         doImport(monitor, importModel.importLocation, importModel.sessionContext.getSession(), target);
133                     } catch (Exception e) {
134                         throw new InvocationTargetException(e);
135                     } finally {
136                         monitor.done();
137                     }
138                 }
139             });
140         } catch (InvocationTargetException e) {
141             Throwable cause = e.getCause();
142             WizardPage cp = (WizardPage) getContainer().getCurrentPage();
143             if (cause instanceof MissingDependencyException) {
144                 cp.setErrorMessage("Failed to import shared library due to missing dependencies.\n" + cause.getMessage());
145                 ErrorLogger.defaultLogError("Shared Library " + importModel.importLocation + " import failed due to missing database dependencies. See exception for details.", cause);
146                 ExceptionUtils.showError("Failed to import shared library due to missing dependencies.\n\n" + cause.getMessage(), null);
147             } else {
148                 cp.setErrorMessage("Unexpected problem importing shared library.\nMessage: " + cause.getMessage());
149                 ErrorLogger.defaultLogError("Shared Library " + importModel.importLocation + " import failed unexpectedly. See exception for details.", cause);
150                 ExceptionUtils.showError("Unexpected problem importing shared library.\n\n" + cause.getMessage(), cause);
151             }
152             return false;
153         } catch (InterruptedException e) {
154             WizardPage cp = (WizardPage) getContainer().getCurrentPage();
155             cp.setErrorMessage("Import interrupted.\nMessage: " + e.getMessage());
156             ErrorLogger.defaultLogError("Shared Library " + importModel.importLocation + " import interrupted.", e);
157             ExceptionUtils.showError("Shared library import was interrupted.", e);
158             return false;
159         }
160
161         return true;
162     }
163
164     public static void doImport(IProgressMonitor monitor, File modelFile, Session session, Resource target)
165             throws Exception
166     {
167         SubMonitor mon = SubMonitor.convert(monitor);
168         mon.beginTask("Loading shared library from disk", 1000);
169
170         FormatHandler<Object> handler1 = new FormatHandler<Object>() {
171             @Override
172             public Binding getBinding() {
173                 return TransferableGraph1.BINDING;
174             }
175
176             @Override
177             public Object process(DataContainer container) throws Exception {
178                 mon.worked(100);
179                 mon.setTaskName("Importing shared library into database");
180                 Variant draftStatus = container.metadata.get(DraftStatusBean.EXTENSION_KEY);
181                 TransferableGraph1 tg = (TransferableGraph1) container.content.getValue();
182                 MigrationUtils.importSharedOntology(mon.newChild(850, SubMonitor.SUPPRESS_NONE), session, tg, draftStatus == null);
183                 return null;
184             }
185         };
186
187         Map<String, FormatHandler<Object>> handlers = new HashMap<>();
188         handlers.put(Constants.SHARED_LIBRARY_FORMAT_V1, handler1);
189
190         DataContainers.readFile(modelFile, handlers);
191
192         mon.setTaskName("Postprocessing");
193         mon.subTask("");
194         mon.newChild(50).done();
195     }
196
197 }