1 /*******************************************************************************
\r
2 * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
\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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.g3d.wizard;
\r
14 import java.io.File;
\r
15 import java.io.IOException;
\r
16 import java.lang.reflect.InvocationTargetException;
\r
17 import java.util.Deque;
\r
18 import java.util.Iterator;
\r
19 import java.util.LinkedList;
\r
20 import java.util.Set;
\r
21 import java.util.TreeSet;
\r
23 import org.eclipse.jface.dialogs.MessageDialog;
\r
24 import org.eclipse.jface.operation.IRunnableWithProgress;
\r
25 import org.eclipse.jface.preference.IPersistentPreferenceStore;
\r
26 import org.eclipse.jface.preference.IPreferenceStore;
\r
27 import org.eclipse.jface.viewers.IStructuredSelection;
\r
28 import org.eclipse.jface.wizard.Wizard;
\r
29 import org.eclipse.jface.wizard.WizardPage;
\r
30 import org.eclipse.ui.IExportWizard;
\r
31 import org.eclipse.ui.IMemento;
\r
32 import org.eclipse.ui.IWorkbench;
\r
33 import org.simantics.db.management.ISessionContext;
\r
34 import org.simantics.project.IProject;
\r
35 import org.simantics.project.ProjectKeys;
\r
36 import org.simantics.Simantics;
\r
37 import org.simantics.utils.ui.ErrorLogger;
\r
38 import org.simantics.utils.ui.ExceptionUtils;
\r
39 import org.simantics.utils.ui.workbench.StringMemento;
\r
41 public abstract class ModelExportWizard<T extends IExportModel> extends Wizard implements IExportWizard {
\r
43 private static final int MAX_RECENT_EXPORT_PATHS = 10;
\r
44 Deque<String> recentExportPaths;
\r
49 protected abstract T createExportModel(Deque<String> recentExportPaths);
\r
51 protected abstract ModelExportWizardPage<T> createExportPage(T exportModel);
\r
53 protected abstract IPersistentPreferenceStore getPreferenceStore();
\r
55 protected abstract IRunnableWithProgress createExportRunnable(T exportModel);
\r
57 protected abstract String getExportLocationId();
\r
58 protected abstract String getExportOverwriteId();
\r
61 public void init(IWorkbench workbench, IStructuredSelection selection) {
\r
64 ISessionContext ctx = Simantics.getSessionContext();
\r
67 IProject project = ctx.getHint(ProjectKeys.KEY_PROJECT);
\r
68 if (project == null)
\r
71 exportModel = createExportModel(recentExportPaths);
\r
72 exportModel.setSelection(selection.getFirstElement());
\r
73 exportModel.setOverwrite(overwrite);
\r
77 public void addPages() {
\r
79 if (exportModel != null) {
\r
80 addPage(createExportPage(exportModel));
\r
87 public boolean performFinish() {
\r
89 recentExportPaths.addFirst(exportModel.getExportLocation().getAbsolutePath());
\r
90 removeDuplicates(recentExportPaths);
\r
91 if (recentExportPaths.size() > MAX_RECENT_EXPORT_PATHS)
\r
92 recentExportPaths.pollLast();
\r
95 } catch (IOException e) {
\r
96 ErrorLogger.defaultLogError("Failed to write preferences", e);
\r
99 if (exportModel.usesFile()) {
\r
101 File outputFile = exportModel.getExportLocation();
\r
103 if (outputFile.exists()) {
\r
104 if (!outputFile.isFile()) {
\r
105 MessageDialog.openError(getShell(), "File Problem", "Output target is not a file " + outputFile.getAbsolutePath());
\r
108 if (!exportModel.isOverwrite()) {
\r
109 boolean ok = MessageDialog.openConfirm(getShell(), "Overwrite", "A file by the name " + outputFile.getAbsolutePath() + " contains files.\n\nDo you want to overwrite the files?");
\r
113 if (!outputFile.delete()) {
\r
114 MessageDialog.openError(getShell(), "Delete Problem", "Could not overwrite previously existing file " + outputFile.getAbsolutePath());
\r
120 File outputFolder = exportModel.getExportLocation();
\r
122 if (outputFolder.exists()) {
\r
123 if (!outputFolder.isDirectory()) {
\r
124 MessageDialog.openError(getShell(), "Folder Problem", "Output target is not a folder " + outputFolder.getAbsolutePath());
\r
127 String files[] = outputFolder.list();
\r
128 if (files.length > 0) {
\r
129 if (!exportModel.isOverwrite()) {
\r
130 boolean ok = MessageDialog.openConfirm(getShell(), "Overwrite", "A folder by the name " + outputFolder.getAbsolutePath() + " contains files.\n\nDo you want to overwrite the files?");
\r
138 if (!outputFolder.mkdir()) {
\r
139 MessageDialog.openError(getShell(), "Folder Problem", "Could not create new folder " + outputFolder);
\r
146 getContainer().run(true, true,createExportRunnable(exportModel));
\r
147 } catch (InvocationTargetException e) {
\r
148 Throwable t = e.getTargetException();
\r
149 WizardPage cp = (WizardPage) getContainer().getCurrentPage();
\r
150 if (t instanceof IOException) {
\r
151 ErrorLogger.defaultLogError("An I/O problem occurred while exporting the model. See exception for details.", t);
\r
152 cp.setErrorMessage("An I/O problem occurred while exporting the model.\n\nMessage: " + e.getMessage());
\r
154 ErrorLogger.defaultLogError("Unexpected exception while exporting the model. See exception for details.", t);
\r
155 cp.setErrorMessage("Unexpected exception while exporting the model. See error log for details.\n\nMessage: " + e.getMessage());
\r
158 } catch (InterruptedException e) {
\r
159 ExceptionUtils.logAndShowError(e);
\r
169 private boolean readPreferences() {
\r
170 IPreferenceStore store = getPreferenceStore();
\r
172 String recentPathsPref = store.getString(getExportLocationId());
\r
173 recentExportPaths = decodePaths(recentPathsPref);
\r
174 overwrite = store.getBoolean(getExportOverwriteId());
\r
179 private void writePreferences() throws IOException {
\r
180 IPersistentPreferenceStore store = getPreferenceStore();
\r
182 store.putValue(getExportLocationId(), encodePaths(recentExportPaths));
\r
183 store.setValue(getExportOverwriteId(), exportModel.isOverwrite());
\r
185 if (store.needsSaving())
\r
189 private static final String TAG_PATH = "path";
\r
190 private static final String ATTR_NAME = "name";
\r
193 public static Deque<String> decodePaths(String recentPathsPref) {
\r
194 Deque<String> result = new LinkedList<String>();
\r
196 StringMemento sm = new StringMemento(recentPathsPref);
\r
197 for (IMemento m : sm.getChildren(TAG_PATH)) {
\r
198 String name = m.getString(ATTR_NAME);
\r
199 if (name != null && !name.isEmpty())
\r
202 } catch (IllegalArgumentException e) {
\r
207 public static String encodePaths(Deque<String> recentPaths) {
\r
208 StringMemento sm = new StringMemento();
\r
209 for (String path : recentPaths) {
\r
210 IMemento m = sm.createChild(TAG_PATH);
\r
211 m.putString(ATTR_NAME, path);
\r
213 return sm.toString();
\r
216 public static <T> void removeDuplicates(Iterable<String> iter) {
\r
217 // Remove duplicates
\r
218 Set<String> dups = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
\r
219 for (Iterator<String> it = iter.iterator(); it.hasNext();) {
\r
220 String path = it.next();
\r
221 if (!dups.add(path)) {
\r