Переглянути джерело

Rework example wizard (#2170)

Uses treeviewer and adds categories; opens models and descriptions after import; resizes wizard based on screen size
rherrmannr 7 роки тому
батько
коміт
0ce986166b
13 змінених файлів з 1165 додано та 868 видалено
  1. 132 128
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/ExampleWizard.java
  2. 99 115
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/pages/ExampleContentProvider.java
  3. 17 5
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/pages/ExampleLabelProvider.java
  4. 365 328
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/pages/SelectExamplePage.java
  5. 73 0
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/ExampleImporter.java
  6. 100 0
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/ExampleModelOpener.java
  7. 33 34
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/IExampleService.java
  8. 105 0
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/data/ExampleCategory.java
  9. 16 6
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/ExampleData.java
  10. 25 0
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/data/IExampleData.java
  11. 198 250
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/git/GitRepositoryExampleService.java
  12. 1 1
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/git/IExampleDataReader.java
  13. 1 1
      plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/git/JsonMetaDataReader.java

+ 132 - 128
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/ExampleWizard.java

@@ -1,129 +1,133 @@
-/**
- * Copyright (c) 2016 committers of YAKINDU and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * Contributors:
- * 	committers of YAKINDU - initial API and implementation
- * 
- */
-package org.yakindu.sct.examples.wizard;
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.INewWizard;
-import org.eclipse.ui.IWorkbench;
-import org.yakindu.sct.examples.wizard.pages.SelectExamplePage;
-import org.yakindu.sct.examples.wizard.service.ExampleData;
-import org.yakindu.sct.examples.wizard.service.ExampleWizardConstants;
-import org.yakindu.sct.examples.wizard.service.ExampleWizardModule;
-import org.yakindu.sct.examples.wizard.service.IExampleService;
-
-import com.google.inject.Guice;
-import com.google.inject.Inject;
-
-/**
- * 
- * @author t00manysecretss
- * 
- */
-
-public class ExampleWizard extends Wizard implements INewWizard, ExampleWizardConstants {
-
-	@Inject
-	private IExampleService exampleService;
-	@Inject
-	private SelectExamplePage page;
-
-	public ExampleWizard() {
-		super();
-		setWindowTitle(WINDOW_TITLE);
-		setNeedsProgressMonitor(true);
-		Guice.createInjector(new ExampleWizardModule()).injectMembers(this);
-	}
-
-	public ExampleWizard(String exampleId) {
-		this();
-		page.setInstallExampleId(exampleId);
-	}
-
-	public void init(IWorkbench workbench, IStructuredSelection selection) {
-		// Nothing do do
-	}
-
-	public void addPages() {
-		addPage(page);
-	}
-
-	public boolean performFinish() {
-		final ExampleData selection = page.getSelection();
-		if (selection != null) {
-			try {
-				getContainer().run(true, true, new IRunnableWithProgress() {
-					@Override
-					public void run(IProgressMonitor monitor) throws InvocationTargetException {
-						if (overrideIfExists(selection)) {
-							exampleService.importExample(selection, monitor);
-						}
-					}
-				});
-			} catch (InvocationTargetException | InterruptedException e) {
-				e.printStackTrace();
-			}
-		}
-		return true;
-	}
-
-	protected boolean overrideIfExists(ExampleData selection) {
-		String name = selection.getProjectDir().getName();
-		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
-		if (project.exists()) {
-			OverrideRunnable runnable = new OverrideRunnable(getShell(), name);
-			Display.getDefault().syncExec(runnable);
-			if (runnable.isOverride()) {
-				try {
-					project.delete(true, new NullProgressMonitor());
-				} catch (CoreException e) {
-					e.printStackTrace();
-				}
-			}
-			return runnable.isOverride();
-		}
-		return true;
-	}
-
-	private static class OverrideRunnable implements Runnable {
-
-		private boolean override = false;
-		private Shell shell;
-		private String name;
-
-		public OverrideRunnable(Shell shell, String name) {
-			this.shell = shell;
-			this.name = name;
-		}
-
-		@Override
-		public void run() {
-			override = MessageDialog.openQuestion(shell, "Project Exists",
-					String.format("Project %s already exists in your workspace. Do you want to override it?", name));
-		}
-
-		public boolean isOverride() {
-			return override;
-		}
-
-	}
+/**
+ * Copyright (c) 2016 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.examples.wizard;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.yakindu.sct.examples.wizard.pages.SelectExamplePage;
+import org.yakindu.sct.examples.wizard.service.ExampleImporter;
+import org.yakindu.sct.examples.wizard.service.ExampleModelOpener;
+import org.yakindu.sct.examples.wizard.service.ExampleWizardConstants;
+import org.yakindu.sct.examples.wizard.service.ExampleWizardModule;
+import org.yakindu.sct.examples.wizard.service.data.ExampleData;
+
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+
+/**
+ * 
+ * @author t00manysecretss
+ * 
+ */
+
+public class ExampleWizard extends Wizard implements INewWizard, ExampleWizardConstants {
+
+	@Inject
+	private SelectExamplePage page;
+	@Inject
+	private ExampleModelOpener opener;
+	@Inject
+	private ExampleImporter importer;
+
+	public ExampleWizard() {
+		super();
+		setWindowTitle(WINDOW_TITLE);
+		setNeedsProgressMonitor(true);
+		Guice.createInjector(new ExampleWizardModule()).injectMembers(this);
+	}
+
+	public ExampleWizard(String exampleId) {
+		this();
+		page.setInstallExampleId(exampleId);
+	}
+
+	public void init(IWorkbench workbench, IStructuredSelection selection) {
+		// Nothing do do
+	}
+
+	public void addPages() {
+		addPage(page);
+	}
+
+	public boolean performFinish() {
+		final ExampleData selection = page.getSelection();
+		if (selection != null) {
+			try {
+				getContainer().run(true, true, new IRunnableWithProgress() {
+					@Override
+					public void run(IProgressMonitor monitor) throws InvocationTargetException {
+						if (overrideIfExists(selection)) {
+							IProject project = importer.importExample(selection, monitor);
+							opener.openModelFiles(project);
+						}
+					}
+				});
+			} catch (InvocationTargetException | InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		return true;
+	}
+
+	protected boolean overrideIfExists(ExampleData selection) {
+		String name = selection.getProjectDir().getName();
+		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
+		if (project.exists()) {
+			OverrideRunnable runnable = new OverrideRunnable(getShell(), name);
+			Display.getDefault().syncExec(runnable);
+			if (runnable.isOverride()) {
+				try {
+					project.delete(true, new NullProgressMonitor());
+				} catch (CoreException e) {
+					e.printStackTrace();
+				}
+			}
+			return runnable.isOverride();
+		}
+		return true;
+	}
+
+	private static class OverrideRunnable implements Runnable {
+
+		private boolean override = false;
+		private Shell shell;
+		private String name;
+
+		public OverrideRunnable(Shell shell, String name) {
+			this.shell = shell;
+			this.name = name;
+		}
+
+		@Override
+		public void run() {
+			override = MessageDialog.openQuestion(shell, "Project Exists",
+					String.format("Project %s already exists in your workspace. Do you want to override it?", name));
+		}
+
+		public boolean isOverride() {
+			return override;
+		}
+
+	}
 }

+ 99 - 115
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/pages/ExampleContentProvider.java

@@ -1,115 +1,99 @@
-/**
- * Copyright (c) 2016 committers of YAKINDU and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * Contributors:
- * 	committers of YAKINDU - initial API and implementation
- * 
- */
-package org.yakindu.sct.examples.wizard.pages;
-
-import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-import org.yakindu.sct.examples.wizard.service.ExampleData;
-
-import com.google.common.collect.Lists;
-
-/**
- * 
- * @author t00manysecretss
- * 
- */
-public class ExampleContentProvider implements ITreeContentProvider {
-
-	public static class Category {
-		private String name;
-		private List<ExampleData> children;;
-
-		public Category(String name) {
-			this.name = name;
-			children = new ArrayList<>();
-		}
-
-		public String getName() {
-			return name;
-		}
-
-		public void setName(String name) {
-			this.name = name;
-		}
-
-		public List<ExampleData> getChildren() {
-			return children;
-		}
-
-	}
-
-	private Map<String, Category> categories;
-
-	public ExampleContentProvider() {
-		categories = new LinkedHashMap<>();
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-		categories.clear();
-		if (newInput != null)
-			groupCategories((List<ExampleData>) newInput);
-	}
-
-	protected void groupCategories(List<ExampleData> newInput) {
-		for (ExampleData exampleData : newInput) {
-			String[] category = exampleData.getCategory();
-			for (String string : category) {
-				if (!categories.containsKey(string)) {
-					categories.put(string, new Category(string));
-				}
-				categories.get(string).getChildren().add(exampleData);
-			}
-		}
-	}
-
-	@Override
-	public Object[] getElements(Object inputElement) {
-		List<Category> values = Lists.newArrayList();
-		values.addAll(categories.values());
-		Collections.sort(values, new Comparator<Category>() {
-			@Override
-			public int compare(Category o1, Category o2) {
-				return Collator.getInstance().compare(o1.getName(), o2.getName());
-			}
-		});
-		return values.toArray();
-	}
-
-	@Override
-	public Object[] getChildren(Object parentElement) {
-		return ((Category) parentElement).getChildren().toArray();
-	}
-
-	@Override
-	public Object getParent(Object element) {
-		return categories.get((((ExampleData) element).getCategory()));
-	}
-
-	@Override
-	public boolean hasChildren(Object element) {
-		return element instanceof Category;
-	}
-
-	@Override
-	public void dispose() {
-		categories.clear();
-	}
-}
+/**
+ * Copyright (c) 2016 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.examples.wizard.pages;
+
+import static org.yakindu.sct.examples.wizard.service.data.ExampleCategory.CATEGORY_LABS;
+import static org.yakindu.sct.examples.wizard.service.data.ExampleCategory.CATEGORY_PROFESSIONAL;
+import static org.yakindu.sct.examples.wizard.service.data.ExampleCategory.CATEGORY_STANDARD;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.yakindu.sct.examples.wizard.service.data.ExampleCategory;
+import org.yakindu.sct.examples.wizard.service.data.ExampleData;
+
+import com.google.common.collect.Lists;
+/**
+ * 
+ * @author t00manysecretss
+ * 
+ */
+public class ExampleContentProvider implements ITreeContentProvider {
+
+	private Map<String, ExampleCategory> categories;
+
+	public ExampleContentProvider() {
+		categories = new LinkedHashMap<>();
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		categories.clear();
+		if (newInput != null)
+			groupCategories((List<ExampleData>) newInput);
+	}
+
+	protected void groupCategories(List<ExampleData> newInput) {
+		for (ExampleData exampleData : newInput) {
+			if (exampleData.isProfessional()) {
+				addExampleToCategory(exampleData, CATEGORY_PROFESSIONAL);
+			} else if (exampleData.isLabs()) {
+				addExampleToCategory(exampleData, CATEGORY_LABS);
+			} else {
+				addExampleToCategory(exampleData, CATEGORY_STANDARD);
+			}
+		}
+	}
+
+	protected void addExampleToCategory(ExampleData exampleData, String category) {
+		if (!categories.containsKey(category)) {
+			categories.put(category, new ExampleCategory(category));
+		}
+		categories.get(category).getChildren().add(exampleData);
+	}
+
+	@Override
+	public Object[] getElements(Object inputElement) {
+		List<ExampleCategory> values = Lists.newArrayList();
+		values.addAll(categories.values());
+		Collections.sort(values);
+		return values.toArray();
+	}
+
+	@Override
+	public Object[] getChildren(Object parentElement) {
+		return ((ExampleCategory) parentElement).getChildren().toArray();
+	}
+
+	@SuppressWarnings("unlikely-arg-type")
+	@Override
+	public Object getParent(Object element) {
+		if (element instanceof ExampleData) {
+			return categories.get(((ExampleData) element).getCategory());
+		}
+		return null;
+	}
+
+	@Override
+	public boolean hasChildren(Object element) {
+		return element instanceof ExampleCategory;
+	}
+
+	@Override
+	public void dispose() {
+		categories.clear();
+	}
+}

+ 17 - 5
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/pages/ExampleLabelProvider.java

@@ -11,13 +11,15 @@
 package org.yakindu.sct.examples.wizard.pages;
 
 import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+
+import static org.yakindu.sct.examples.wizard.service.data.ExampleCategory.*;
+
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.jface.viewers.StyledString;
 import org.eclipse.swt.graphics.Image;
-import org.yakindu.sct.examples.wizard.pages.ExampleContentProvider.Category;
-import org.yakindu.sct.examples.wizard.service.ExampleData;
+import org.yakindu.sct.examples.wizard.service.data.ExampleCategory;
+import org.yakindu.sct.examples.wizard.service.data.ExampleData;
 import org.yakindu.sct.ui.editor.StatechartImages;
-
 /**
  * 
  * @author t00manysecretss
@@ -29,8 +31,8 @@ public class ExampleLabelProvider extends LabelProvider implements IStyledLabelP
 	public StyledString getStyledText(Object element) {
 		if (element instanceof ExampleData) {
 			return new StyledString(((ExampleData) element).getTitle());
-		} else if (element instanceof Category) {
-			return new StyledString(((Category) element).getName());
+		} else if (element instanceof ExampleCategory) {
+			return new StyledString(((ExampleCategory) element).getName());
 		}
 		return null;
 	}
@@ -46,6 +48,16 @@ public class ExampleLabelProvider extends LabelProvider implements IStyledLabelP
 				return StatechartImages.LOGO.image();
 			}
 		}
+		if (element instanceof ExampleCategory) {
+			String categoryName = ((ExampleCategory) element).getName();
+			if(CATEGORY_PROFESSIONAL.equals(categoryName)) {
+				return StatechartImages.PRO_LOGO.image();
+			} else if (CATEGORY_LABS.equals(categoryName)) {
+				return StatechartImages.LABS_LOGO.image();
+			} else if (CATEGORY_STANDARD.equals(categoryName)) {
+				return StatechartImages.LOGO.image();
+			}
+		}
 		return StatechartImages.MENU.image();
 	}
 

+ 365 - 328
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/pages/SelectExamplePage.java

@@ -1,329 +1,366 @@
-/**
- * Copyright (c) 2016 committers of YAKINDU and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * Contributors:
- * 	committers of YAKINDU - initial API and implementation
- * 
- */
-package org.yakindu.sct.examples.wizard.pages;
-
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-import java.util.List;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.jface.viewers.ArrayContentProvider;
-import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.program.Program;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.yakindu.sct.examples.wizard.ExampleActivator;
-import org.yakindu.sct.examples.wizard.preferences.ExamplesPreferenceConstants;
-import org.yakindu.sct.examples.wizard.service.ExampleData;
-import org.yakindu.sct.examples.wizard.service.ExampleWizardConstants;
-import org.yakindu.sct.examples.wizard.service.IExampleService;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.inject.Inject;
-
-/**
- * 
- * @author t00manysecretss
- * @author andreas muelder - Replace Image Gallery with Browser widget
- * 
- */
-
-public class SelectExamplePage extends WizardPage
-		implements ExampleWizardConstants, ISelectionChangedListener, SelectionListener, IPropertyChangeListener {
-
-	private static final String PRO_BUNDLE = "com.yakindu.sct.domain.c";
-	private static final String PRO_UPDATE_SITE = "https://info.itemis.com/yakindu/statecharts/pro/";
-	@Inject
-	private IExampleService exampleService;
-	private TableViewer viewer;
-	private ExampleData selection;
-	private Browser browser;
-	private MessageArea messageArea;
-
-	/** ID of example to be installed */
-	private String exampleIdToInstall;
-
-	public SelectExamplePage() {
-		super(SELECT_PAGE_TITLE);
-		setTitle(SELECT_PAGE_TITLE);
-		setDescription(SELECT_PAGE_DESCRIPTION);
-		setPageComplete(false);
-		ExampleActivator.getDefault().getPreferenceStore().addPropertyChangeListener(this);
-	}
-
-	@Override
-	public void dispose() {
-		ExampleActivator.getDefault().getPreferenceStore().removePropertyChangeListener(this);
-		super.dispose();
-	}
-
-	public void createControl(Composite parent) {
-		Composite root = new Composite(parent, SWT.NONE);
-		root.setLayout(new GridLayout(1, true));
-		createUpdateGroup(root);
-		SashForm container = new SashForm(root, SWT.NONE);
-		GridDataFactory.fillDefaults().grab(true, true).applyTo(container);
-		GridLayout layout = new GridLayout(2, false);
-		container.setLayout(layout);
-		createTreeViewer(container);
-		createDetailsPane(container);
-		container.setWeights(new int[] { 1, 2 });
-		setControl(container);
-	}
-
-	private void createUpdateGroup(Composite root) {
-		messageArea = new MessageArea(root);
-		GridDataFactory.fillDefaults().grab(true, false).applyTo(messageArea);
-		messageArea.addSelectionListener(this);
-		messageArea.hide();
-	}
-
-	@Override
-	public void setVisible(boolean visible) {
-		super.setVisible(visible);
-		if (visible) {
-			initAsync();
-		} else {
-			viewer.setInput(null);
-			browser.setUrl("about:blank");
-		}
-
-	}
-
-	private boolean revealExamplesAutomatically() {
-		return (exampleIdToInstall != null) && (!exampleService.exists() || !exampleService.isUpToDate(null));
-	}
-
-	private void initAsync() {
-		try {
-			getWizard().getContainer().run(true, false, new IRunnableWithProgress() {
-				@Override
-				public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
-					init(monitor);
-				}
-			});
-
-			if (revealExamplesAutomatically()) {
-				Display.getCurrent().asyncExec(new Runnable() {
-					@Override
-					public void run() {
-						messageArea.button.setEnabled(false);
-						revealExamples();
-					}
-				});
-			}
-		} catch (InvocationTargetException | InterruptedException e) {
-			e.printStackTrace();
-		}
-	}
-
-	private void init(final IProgressMonitor monitor) {
-		if (!exampleService.exists()) {
-			Display.getDefault().syncExec(new Runnable() {
-				@Override
-				public void run() {
-					messageArea.showDownload();
-					messageArea.getParent().layout(true);
-				}
-			});
-		} else if (!exampleService.isUpToDate(monitor)) {
-			Display.getDefault().syncExec(new Runnable() {
-
-				@Override
-				public void run() {
-					setInput(monitor);
-					messageArea.showUpdate();
-					messageArea.getParent().layout(true);
-				}
-			});
-		} else {
-			Display.getDefault().syncExec(new Runnable() {
-				@Override
-				public void run() {
-					setInput(monitor);
-				}
-			});
-		}
-
-	}
-
-	protected void setInput(final IProgressMonitor monitor) {
-		final List<ExampleData> input = exampleService.getExamples(new NullProgressMonitor());
-
-		messageArea.hide();
-		viewer.setInput(input);
-		// explicit layouting required for Unix systems
-		viewer.getControl().getParent().getParent().layout(true);
-
-		filterAndSelectExampleToInstall(viewer, input);
-	}
-
-	protected void filterAndSelectExampleToInstall(TableViewer viewer, List<ExampleData> input) {
-		final ExampleData exampleToInstall = Iterables.find(input, new Predicate<ExampleData>() {
-			@Override
-			public boolean apply(ExampleData input) {
-				if (exampleIdToInstall != null) {
-					return exampleIdToInstall.equals(input.getId());
-				}
-				return true;
-			}
-
-		});
-		if (exampleToInstall != null) {
-			viewer.addFilter(new ViewerFilter() {
-
-				@Override
-				public boolean select(Viewer viewer, Object parentElement, Object element) {
-					if (exampleIdToInstall == null) {
-						return true;
-					}
-					if (element instanceof ExampleData) {
-						return exampleIdToInstall.equals(((ExampleData) element).getId());
-					}
-					if (element instanceof ExampleContentProvider.Category) {
-						return ((ExampleContentProvider.Category) element).getChildren().contains(exampleToInstall);
-					}
-					return true;
-				}
-			});
-			viewer.setSelection(new StructuredSelection(exampleToInstall), true);
-		}
-	}
-
-	protected void createTreeViewer(Composite container) {
-		viewer = new TableViewer(container, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE);
-		GridDataFactory.fillDefaults().grab(true, true).applyTo(viewer.getControl());
-		viewer.setContentProvider(new ArrayContentProvider());
-		viewer.setLabelProvider(new DelegatingStyledCellLabelProvider(new ExampleLabelProvider()));
-		viewer.addSelectionChangedListener(this);
-	}
-
-	protected void updateSelection(ExampleData data) {
-		selection = data;
-		setDetailPaneContent(data);
-		setPageComplete(true);
-		setErrorMessage(null);
-		checkInstalledPlugins(data);
-		viewer.refresh();
-	}
-
-	private void checkInstalledPlugins(ExampleData data) {
-		if (data.isProfessional() && Platform.getBundle(PRO_BUNDLE) == null) {
-			messageArea.showProInstall();
-		} else {
-			messageArea.hide();
-		}
-		messageArea.getParent().layout(true);
-		this.getControl().update();
-	}
-
-	protected void setDetailPaneContent(ExampleData exampleData) {
-		String url = exampleData.getProjectDir().getAbsolutePath() + File.separator + "index.html";
-		browser.setUrl(url);
-	}
-
-	protected void createDetailsPane(Composite parent) {
-		final Composite composite = new Composite(parent, SWT.BORDER);
-		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-		composite.setLayout(new FillLayout());
-		browser = new Browser(composite, SWT.NONE);
-	}
-
-	public ExampleData getSelection() {
-		return selection;
-	}
-
-	@Override
-	public void selectionChanged(SelectionChangedEvent event) {
-		Object firstElement = ((StructuredSelection) event.getSelection()).getFirstElement();
-		if (firstElement instanceof ExampleData)
-			updateSelection((ExampleData) firstElement);
-	}
-
-	@Override
-	public void widgetSelected(SelectionEvent e) {
-		switch (messageArea.getState()) {
-		case DOWNLOAD:
-		case UPDATE:
-			revealExamples();
-			break;
-		case INSTALL:
-			Program.launch(PRO_UPDATE_SITE);
-			break;
-		default:
-			break;
-		}
-	}
-
-	protected void revealExamples() {
-		try {
-			getWizard().getContainer().run(true, true, new IRunnableWithProgress() {
-				@Override
-				public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
-					final IStatus status = exampleService.fetchAllExamples(monitor);
-					Display.getDefault().asyncExec(new Runnable() {
-						@Override
-						public void run() {
-							if (status.isOK()) {
-								SelectExamplePage.this.setInput(monitor);
-							} else {
-								messageArea.showError();
-							}
-						}
-					});
-				}
-			});
-
-		} catch (InvocationTargetException | InterruptedException e1) {
-			e1.printStackTrace();
-		}
-	}
-
-	@Override
-	public void widgetDefaultSelected(SelectionEvent e) {
-		widgetSelected(e);
-	}
-
-	@Override
-	public void propertyChange(PropertyChangeEvent event) {
-		if (ExamplesPreferenceConstants.STORAGE_LOCATION.equals(event.getProperty())) {
-			initAsync();
-		}
-	}
-
-	public void setInstallExampleId(String exampleId) {
-		this.exampleIdToInstall = exampleId;
-	}
-
+/**
+ * Copyright (c) 2016 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.examples.wizard.pages;
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Monitor;
+import org.yakindu.sct.examples.wizard.ExampleActivator;
+import org.yakindu.sct.examples.wizard.preferences.ExamplesPreferenceConstants;
+import org.yakindu.sct.examples.wizard.service.ExampleWizardConstants;
+import org.yakindu.sct.examples.wizard.service.IExampleService;
+import org.yakindu.sct.examples.wizard.service.data.ExampleCategory;
+import org.yakindu.sct.examples.wizard.service.data.ExampleData;
+import org.yakindu.sct.examples.wizard.service.data.IExampleData;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+/**
+ * 
+ * @author t00manysecretss
+ * @author andreas muelder - Replace Image Gallery with Browser widget
+ * 
+ */
+
+public class SelectExamplePage extends WizardPage
+		implements
+			ExampleWizardConstants,
+			ISelectionChangedListener,
+			SelectionListener,
+			IPropertyChangeListener {
+
+	private static final String PRO_BUNDLE = "com.yakindu.sct.domain.c";
+	private static final String PRO_UPDATE_SITE = "https://info.itemis.com/yakindu/statecharts/pro/";
+	
+	private static final int WIZARD_SIZE_SCALE_FACOTR = 2;
+	private static final int WIZARD_SIZE_OFFSET = 300;
+	
+	@Inject
+	private IExampleService exampleService;
+	private TreeViewer viewer;
+	private ExampleData selection;
+	private Browser browser;
+	private MessageArea messageArea;
+
+	/** ID of example to be installed */
+	private String exampleIdToInstall;
+
+	public SelectExamplePage() {
+		super(SELECT_PAGE_TITLE);
+		setTitle(SELECT_PAGE_TITLE);
+		setDescription(SELECT_PAGE_DESCRIPTION);
+		setPageComplete(false);
+		ExampleActivator.getDefault().getPreferenceStore().addPropertyChangeListener(this);
+	}
+
+	@Override
+	public void dispose() {
+		ExampleActivator.getDefault().getPreferenceStore().removePropertyChangeListener(this);
+		super.dispose();
+	}
+
+	public void createControl(Composite parent) {
+		getShell().setBounds(calculatePosition(WIZARD_SIZE_SCALE_FACOTR, WIZARD_SIZE_OFFSET));
+		Composite root = new Composite(parent, SWT.NONE);
+		root.setLayout(new GridLayout(1, true));
+		createUpdateGroup(root);
+		SashForm container = new SashForm(root, SWT.NONE);
+		GridDataFactory.fillDefaults().grab(true, true).applyTo(container);
+		GridLayout layout = new GridLayout(2, false);
+		container.setLayout(layout);
+		createTreeViewer(container);
+		createDetailsPane(container);
+		container.setWeights(new int[]{1, 2});
+		setControl(container);
+		parent.layout();
+	}
+
+	private Rectangle calculatePosition(int scale, int offset) {
+		Monitor monitor = getShell().getDisplay().getActiveShell().getMonitor();
+		offset = offset * scale;
+		int width = (monitor.getBounds().width + offset) / scale;
+		int height = (monitor.getBounds().height + offset) / scale;
+		int x = monitor.getBounds().x + (width - offset) / scale;
+		int y = monitor.getBounds().y + (height - offset) / scale;
+		return new Rectangle(x, y, width, height);
+	}
+
+	private void createUpdateGroup(Composite root) {
+		messageArea = new MessageArea(root);
+		GridDataFactory.fillDefaults().grab(true, false).applyTo(messageArea);
+		messageArea.addSelectionListener(this);
+		messageArea.hide();
+	}
+
+	@Override
+	public void setVisible(boolean visible) {
+		super.setVisible(visible);
+		if (visible) {
+			initAsync();
+		} else {
+			setPageComplete(false);
+			selection = null;
+			viewer.setInput(null);
+			browser.setUrl("about:blank");
+		}
+
+	}
+
+	private boolean revealExamplesAutomatically() {
+		return (exampleIdToInstall != null) && (!exampleService.exists() || !exampleService.isUpToDate(null));
+	}
+
+	private void initAsync() {
+		try {
+			getWizard().getContainer().run(true, false, new IRunnableWithProgress() {
+				@Override
+				public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+					init(monitor);
+				}
+			});
+
+			if (revealExamplesAutomatically()) {
+				Display.getCurrent().asyncExec(new Runnable() {
+					@Override
+					public void run() {
+						messageArea.button.setEnabled(false);
+						revealExamples();
+					}
+				});
+			}
+		} catch (InvocationTargetException | InterruptedException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void init(final IProgressMonitor monitor) {
+		if (!exampleService.exists()) {
+			Display.getDefault().syncExec(new Runnable() {
+				@Override
+				public void run() {
+					messageArea.showDownload();
+					messageArea.getParent().layout(true);
+				}
+			});
+		} else if (!exampleService.isUpToDate(monitor)) {
+			Display.getDefault().syncExec(new Runnable() {
+
+				@Override
+				public void run() {
+					setInput(monitor);
+					messageArea.showUpdate();
+					messageArea.getParent().layout(true);
+				}
+			});
+		} else {
+			Display.getDefault().syncExec(new Runnable() {
+				@Override
+				public void run() {
+					setInput(monitor);
+				}
+			});
+		}
+
+	}
+
+	protected void setInput(final IProgressMonitor monitor) {
+		final List<ExampleData> input = exampleService.getExamples(new NullProgressMonitor());
+		messageArea.hide();
+		viewer.setInput(input);
+		// explicit layouting required for Unix systems
+		viewer.getControl().getParent().getParent().layout(true);
+
+		filterAndSelectExampleToInstall(viewer, input);
+	}
+
+	protected void filterAndSelectExampleToInstall(TreeViewer viewer, List<ExampleData> input) {
+		final ExampleData exampleToInstall = Iterables.find(input, new Predicate<ExampleData>() {
+			@Override
+			public boolean apply(ExampleData input) {
+				if (exampleIdToInstall != null) {
+					return exampleIdToInstall.equals(input.getId());
+				}
+				return true;
+			}
+
+		});
+		if (exampleToInstall != null) {
+			viewer.addFilter(new ViewerFilter() {
+
+				@Override
+				public boolean select(Viewer viewer, Object parentElement, Object element) {
+					if (exampleIdToInstall == null) {
+						return true;
+					}
+					if (element instanceof ExampleData) {
+						return exampleIdToInstall.equals(((ExampleData) element).getId());
+					}
+					if (element instanceof ExampleCategory) {
+						return ((ExampleCategory) element).getChildren().contains(exampleToInstall);
+					}
+					return true;
+				}
+			});
+			viewer.expandAll();
+			viewer.setSelection(new StructuredSelection(exampleToInstall), true);
+		}
+	}
+
+	protected void createTreeViewer(Composite container) {
+		viewer = new TreeViewer(container, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE);
+		GridDataFactory.fillDefaults().grab(true, true).applyTo(viewer.getControl());
+		viewer.setContentProvider(new ExampleContentProvider());
+		viewer.setLabelProvider(new DelegatingStyledCellLabelProvider(new ExampleLabelProvider()));
+		viewer.addSelectionChangedListener(this);
+	}
+
+	protected void updateSelection(IExampleData data) {
+		if (data instanceof ExampleData) {
+			selection = (ExampleData) data;
+			setPageComplete(true);
+		} else {
+			selection = null;
+			setPageComplete(false);
+		}
+		setDetailPaneContent(data);
+		setErrorMessage(null);
+		checkInstalledPlugins(data);
+		viewer.refresh();
+	}
+
+	private void checkInstalledPlugins(IExampleData data) {
+		if (isProRequiredAndMissing(data)) {
+			messageArea.showProInstall();
+		} else {
+			messageArea.hide();
+		}
+		messageArea.getParent().layout(true);
+		this.getControl().update();
+	}
+
+	protected boolean isProRequiredAndMissing(IExampleData data) {
+		return data.isProfessional() && Platform.getBundle(PRO_BUNDLE) == null;
+	}
+
+	protected void setDetailPaneContent(IExampleData data) {
+		String path = data.getDescriptionPath();
+		if (path != null && new File(path).exists()) {
+			browser.setUrl(path);
+		} else {
+			browser.setUrl("about:blank");
+		}
+	}
+
+	protected void createDetailsPane(Composite parent) {
+		final Composite composite = new Composite(parent, SWT.BORDER);
+		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+		composite.setLayout(new FillLayout());
+		browser = new Browser(composite, SWT.NONE);
+	}
+
+	public ExampleData getSelection() {
+		return selection;
+	}
+
+	@Override
+	public void selectionChanged(SelectionChangedEvent event) {
+		Object firstElement = ((StructuredSelection) event.getSelection()).getFirstElement();
+		if (firstElement instanceof IExampleData) {
+			updateSelection((IExampleData) firstElement);
+		}
+	}
+
+	@Override
+	public void widgetSelected(SelectionEvent e) {
+		switch (messageArea.getState()) {
+			case DOWNLOAD :
+			case UPDATE :
+				revealExamples();
+				break;
+			case INSTALL :
+				Program.launch(PRO_UPDATE_SITE);
+				break;
+			default :
+				break;
+		}
+	}
+
+	protected void revealExamples() {
+		try {
+			getWizard().getContainer().run(true, true, new IRunnableWithProgress() {
+				@Override
+				public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+					final IStatus status = exampleService.fetchAllExamples(monitor);
+					Display.getDefault().asyncExec(new Runnable() {
+						@Override
+						public void run() {
+							if (status.isOK()) {
+								SelectExamplePage.this.setInput(monitor);
+							} else {
+								messageArea.showError();
+							}
+						}
+					});
+				}
+			});
+
+		} catch (InvocationTargetException | InterruptedException e1) {
+			e1.printStackTrace();
+		}
+	}
+
+	@Override
+	public void widgetDefaultSelected(SelectionEvent e) {
+		widgetSelected(e);
+	}
+
+	@Override
+	public void propertyChange(PropertyChangeEvent event) {
+		if (ExamplesPreferenceConstants.STORAGE_LOCATION.equals(event.getProperty())) {
+			initAsync();
+		}
+	}
+
+	public void setInstallExampleId(String exampleId) {
+		this.exampleIdToInstall = exampleId;
+	}
+
 }

+ 73 - 0
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/ExampleImporter.java

@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2018 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.examples.wizard.service;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
+import org.eclipse.ui.wizards.datatransfer.ImportOperation;
+import org.yakindu.sct.examples.wizard.service.data.ExampleData;
+
+/**
+ * 
+ * @author t00manysecretss
+ * 
+ */
+public class ExampleImporter {
+
+	@SuppressWarnings("deprecation")
+	public IProject importExample(ExampleData edata, IProgressMonitor monitor) {
+		try {
+			IProjectDescription original = ResourcesPlugin.getWorkspace()
+					.loadProjectDescription(new Path(edata.getProjectDir().getAbsolutePath()).append("/.project"));
+			IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(edata.getProjectDir().getName());
+
+			IProjectDescription clone = ResourcesPlugin.getWorkspace().newProjectDescription(original.getName());
+			clone.setBuildSpec(original.getBuildSpec());
+			clone.setComment(original.getComment());
+			clone.setDynamicReferences(original.getDynamicReferences());
+			clone.setNatureIds(original.getNatureIds());
+			clone.setReferencedProjects(original.getReferencedProjects());
+			if (project.exists()) {
+				return project;
+			}
+			project.create(clone, monitor);
+			project.open(monitor);
+
+			@SuppressWarnings("unchecked")
+			List<IFile> filesToImport = FileSystemStructureProvider.INSTANCE.getChildren(edata.getProjectDir());
+			ImportOperation io = new ImportOperation(project.getFullPath(), edata.getProjectDir(),
+					FileSystemStructureProvider.INSTANCE, new IOverwriteQuery() {
+
+						@Override
+						public String queryOverwrite(String pathString) {
+							return IOverwriteQuery.ALL;
+						}
+
+					}, filesToImport);
+			io.setOverwriteResources(true);
+			io.setCreateContainerStructure(false);
+			io.run(monitor);
+			project.refreshLocal(IProject.DEPTH_INFINITE, monitor);
+			return project;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+}

+ 100 - 0
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/ExampleModelOpener.java

@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2018 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.examples.wizard.service;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.yakindu.sct.examples.wizard.service.data.ExampleData;
+
+import com.google.common.collect.Lists;
+
+/**
+ * 
+ * @author robin herrmann - Initial API and contribution
+ *
+ */
+public class ExampleModelOpener {
+
+	private static final String SCT_FILE_EXTENSION = ".sct";
+
+	public void openModelFiles(IProject project) {
+		List<IFile> filesToOpen = Lists.newArrayList();
+
+		addExampleDesc(project, filesToOpen);
+		addStatecharts(project, filesToOpen);
+
+		if (filesToOpen != null) {
+			IWorkbenchPage page = getPage();
+			if (page != null) {
+				Display.getDefault().asyncExec(() -> {
+					for (IFile file : filesToOpen) {
+						try {
+							IDE.openEditor(page, file, true);
+						} catch (PartInitException e) {
+							e.printStackTrace();
+						}
+					}
+				});
+			}
+		}
+	}
+
+	protected IWorkbenchPage getPage() {
+		IWorkbenchWindow[] workbenchWindows = PlatformUI.getWorkbench().getWorkbenchWindows();
+		if (workbenchWindows.length > 0) {
+			IWorkbenchWindow workbenchWindow = workbenchWindows[0];
+			IWorkbenchPage[] pages = workbenchWindow.getPages();
+			if (pages.length > 0) {
+				return pages[0];
+			}
+		}
+		return null;
+	}
+
+	protected void addStatecharts(IProject project, List<IFile> filesToOpen) {
+		try {
+			filesToOpen.addAll(findAllFilesRecursively(project, SCT_FILE_EXTENSION));
+		} catch (CoreException e) {
+			e.printStackTrace();
+		}
+	}
+
+	protected void addExampleDesc(IProject project, List<IFile> filesToOpen) {
+		IResource indexFile = project.findMember(ExampleData.DESC_FILE);
+		if (indexFile != null) {
+			filesToOpen.add((IFile) indexFile);
+		}
+	}
+
+	public List<IFile> findAllFilesRecursively(IContainer container, String fileEnding) throws CoreException {
+		List<IFile> files = Lists.newArrayList();
+		for (IResource r : container.members()) {
+			if (r instanceof IContainer) {
+				files.addAll(findAllFilesRecursively((IContainer) r, fileEnding));
+			} else if (r instanceof IFile && r.getName().endsWith(fileEnding)) {
+				files.add((IFile) r);
+			}
+		}
+		return files;
+	}
+
+}

+ 33 - 34
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/IExampleService.java

@@ -1,35 +1,34 @@
-/**
- * Copyright (c) 2016 committers of YAKINDU and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * Contributors:
- * 	committers of YAKINDU - initial API and implementation
- * 
- */
-package org.yakindu.sct.examples.wizard.service;
-
-import java.util.List;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-
-/**
- * 
- * @author t00manysecretss
- * 
- */
-public interface IExampleService {
-	
-	public boolean exists();
-	
-	public boolean isUpToDate(IProgressMonitor monitor);
-	
-	public IStatus fetchAllExamples(IProgressMonitor monitor);
-
-	public List<ExampleData> getExamples(IProgressMonitor monitor);
-
-	public void importExample(ExampleData selection, IProgressMonitor monitor);
-
+/**
+ * Copyright (c) 2016 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.examples.wizard.service;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.yakindu.sct.examples.wizard.service.data.ExampleData;
+
+/**
+ * 
+ * @author t00manysecretss
+ * 
+ */
+public interface IExampleService {
+	
+	public boolean exists();
+	
+	public boolean isUpToDate(IProgressMonitor monitor);
+	
+	public IStatus fetchAllExamples(IProgressMonitor monitor);
+
+	public List<ExampleData> getExamples(IProgressMonitor monitor);
+
 }

+ 105 - 0
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/data/ExampleCategory.java

@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2018 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.examples.wizard.service.data;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+import org.yakindu.sct.examples.wizard.ExampleActivator;
+import org.yakindu.sct.examples.wizard.preferences.ExamplesPreferenceConstants;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+/**
+ * 
+ * @author robin herrmann
+ *
+ */
+public class ExampleCategory implements Comparable<ExampleCategory>, IExampleData {
+	
+	private Map<String, Integer> priorities = ImmutableMap.of(//
+			CATEGORY_PROFESSIONAL, 1, //
+			CATEGORY_STANDARD, 2, //
+			CATEGORY_LABS, 3 //
+	);
+	
+	public static final String CATEGORY_PROFESSIONAL = "Professional Examples";
+	public static final String CATEGORY_LABS = "Labs Examples";
+	public static final String CATEGORY_STANDARD = "Standard Examples";
+	
+	private static final String PREVIEW_PAGES = "org.yakindu.sct.examples.pages";
+	
+	private static final String STANDARD_DESC = "standard.html";
+	private static final String PROFESSIONAL_DESC = "professional.html";
+	private static final String LABS_DESC = "labs.html";
+	
+	private String name;
+	private List<ExampleData> children = Lists.newArrayList();
+	
+	public ExampleCategory(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public List<ExampleData> getChildren() {
+		return children;
+	}
+
+	@Override
+	public int compareTo(ExampleCategory o) {
+		if (this.getPriority() == o.getPriority()) {
+			return 0;
+		} else if (this.getPriority() < o.getPriority()) {
+			return -1;
+		}
+		return 1;
+	}
+
+	public int getPriority() {
+		Integer prio = priorities.get(name);
+		return prio == null ? 4 : prio;
+	}
+
+	@Override
+	public String getDescriptionPath() {
+		if (isProfessional()) {
+			return getStorageLocation() + File.separator + PREVIEW_PAGES + File.separator + PROFESSIONAL_DESC;
+		} else if (isLabs()) {
+			return getStorageLocation() + File.separator + PREVIEW_PAGES + File.separator + LABS_DESC;
+		}
+		return getStorageLocation() + File.separator + PREVIEW_PAGES + File.separator + STANDARD_DESC;
+	}
+	
+	@Override
+	public boolean isProfessional() {
+		return CATEGORY_PROFESSIONAL.equals(getName());
+	}
+	
+	@Override
+	public boolean isLabs() {
+		return CATEGORY_LABS.equals(getName());
+	}
+	
+	protected java.nio.file.Path getStorageLocation() {
+		return java.nio.file.Paths.get(ExampleActivator.getDefault().getPreferenceStore()
+				.getString(ExamplesPreferenceConstants.STORAGE_LOCATION));
+	}
+
+}

+ 16 - 6
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/ExampleData.java

@@ -8,7 +8,7 @@
  * 	committers of YAKINDU - initial API and implementation
  * 
  */
-package org.yakindu.sct.examples.wizard.service;
+package org.yakindu.sct.examples.wizard.service.data;
 
 import java.io.File;
 import java.text.Collator;
@@ -19,10 +19,13 @@ import java.util.Arrays;
  * @author t00manysecretss
  * 
  */
-public class ExampleData implements Comparable<ExampleData> {
+public class ExampleData implements Comparable<ExampleData>, IExampleData {
 
-	private static final String PRO_EXAMPLE = "professional";
-	private static final String LABS_EXAMPLE = "labs";
+	public static final String DESC_FILE = "index.html";
+
+	private static final String PRO_CATEGORY = "professional";
+	private static final String LABS_CATEGORY = "labs";
+	
 	private String id;
 	private String title;
 	private String[] category;
@@ -95,12 +98,19 @@ public class ExampleData implements Comparable<ExampleData> {
 		this.projectDir = projectDir;
 	}
 
+	@Override
 	public boolean isProfessional() {
-		return Arrays.asList(getCategory()).contains(PRO_EXAMPLE);
+		return Arrays.asList(getCategory()).contains(PRO_CATEGORY);
 	}
 	
+	@Override
 	public boolean isLabs() {
-		return Arrays.asList(getCategory()).contains(LABS_EXAMPLE);
+		return Arrays.asList(getCategory()).contains(LABS_CATEGORY);
+	}
+	
+	@Override
+	public String getDescriptionPath() {
+		return getProjectDir().getAbsolutePath() + File.separator + DESC_FILE;
 	}
 
 	@Override

+ 25 - 0
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/data/IExampleData.java

@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2018 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.examples.wizard.service.data;
+
+/**
+ * 
+ * @author thomas kutz - Initial API and contribution
+ * 
+ */
+public interface IExampleData {
+
+	String getDescriptionPath();
+
+	boolean isProfessional();
+	
+	boolean isLabs();
+}

+ 198 - 250
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/git/GitRepositoryExampleService.java

@@ -1,251 +1,199 @@
-/**
- * Copyright (c) 2016 committers of YAKINDU and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * Contributors:
- * 	committers of YAKINDU - initial API and implementation
- * 
- */
-package org.yakindu.sct.examples.wizard.service.git;
-
-import java.io.IOException;
-import java.nio.file.DirectoryStream;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jgit.api.FetchCommand;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.PullResult;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.errors.RepositoryNotFoundException;
-import org.eclipse.jgit.transport.FetchResult;
-import org.eclipse.jgit.transport.TrackingRefUpdate;
-import org.eclipse.ui.dialogs.IOverwriteQuery;
-import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
-import org.eclipse.ui.wizards.datatransfer.ImportOperation;
-import org.yakindu.sct.examples.wizard.ExampleActivator;
-import org.yakindu.sct.examples.wizard.preferences.ExamplesPreferenceConstants;
-import org.yakindu.sct.examples.wizard.service.ExampleData;
-import org.yakindu.sct.examples.wizard.service.IExampleService;
-
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-
-/**
- * 
- * @author t00manysecretss
- * @author andreas muelder - let GitRepositoryExampleService implement
- *         {@link IExampleService} interface
- * 
- */
-@Singleton
-public class GitRepositoryExampleService implements IExampleService {
-
-	private static final String METADATA_JSON = "metadata.json";
-
-	@Inject
-	private IExampleDataReader reader;
-
-	protected java.nio.file.Path getStorageLocation() {
-		return java.nio.file.Paths.get(ExampleActivator.getDefault().getPreferenceStore()
-				.getString(ExamplesPreferenceConstants.STORAGE_LOCATION));
-	}
-
-	@Override
-	public boolean exists() {
-		return Files.exists(getStorageLocation()) && hasMetaData(getStorageLocation());
-	}
-
-	@Override
-	public IStatus fetchAllExamples(IProgressMonitor monitor) {
-		if (!exists()) {
-			java.nio.file.Path storageLocation = getStorageLocation();
-			try {
-				Files.createDirectories(storageLocation);
-			} catch (IOException e1) {
-				return new Status(IStatus.ERROR, ExampleActivator.PLUGIN_ID,
-						"Unable to create folder " + storageLocation.getFileName());
-			}
-			return cloneRepository(monitor);
-		} else {
-			return updateRepository(monitor);
-		}
-	}
-
-	protected IStatus updateRepository(IProgressMonitor monitor) {
-		String repoURL = getPreference(ExamplesPreferenceConstants.REMOTE_LOCATION);
-		try {
-			java.nio.file.Path storageLocation = getStorageLocation();
-			PullResult result = Git.open(storageLocation.toFile()).pull()
-					.setProgressMonitor(new EclipseGitProgressTransformer(monitor)).call();
-			if (!result.isSuccessful()) {
-				return new Status(IStatus.ERROR, ExampleActivator.PLUGIN_ID,
-						"Unable to update repository " + repoURL + "!");
-			}
-		} catch (GitAPIException | IOException e) {
-			return new Status(IStatus.ERROR, ExampleActivator.PLUGIN_ID,
-					"Unable to update repository " + repoURL + "!");
-		}
-		return Status.OK_STATUS;
-	}
-	
-	protected String getPreference(String constant){
-		return ExampleActivator.getDefault().getPreferenceStore().getString(constant);
-	}
-	
-	protected IStatus cloneRepository(IProgressMonitor monitor) {
-		String repoURL = getPreference(ExamplesPreferenceConstants.REMOTE_LOCATION);
-		String remoteBranch = getPreference(ExamplesPreferenceConstants.REMOTE_BRANCH);
-		Git call = null;
-		java.nio.file.Path storageLocation = getStorageLocation();
-		try {
-			call = Git.cloneRepository().setURI(repoURL).setDirectory(storageLocation.toFile())
-					.setProgressMonitor(new EclipseGitProgressTransformer(monitor)).setBranch(remoteBranch).call();
-		} catch (GitAPIException e) {
-			try {
-				deleteFolder(storageLocation);
-			} catch (IOException ex) {
-				ex.printStackTrace();
-			}
-			return new Status(IStatus.ERROR, ExampleActivator.PLUGIN_ID,
-					"Unable to clone repository " + repoURL + "!");
-		} finally {
-			if (call != null)
-				call.close();
-			if (monitor.isCanceled()) {
-				try {
-					deleteFolder(storageLocation);
-				} catch (IOException e) {
-					e.printStackTrace();
-				}
-			}
-		}
-		return Status.OK_STATUS;
-	}
-
-	@Override
-	public List<ExampleData> getExamples(IProgressMonitor monitor) {
-		java.nio.file.Path storageLocation = getStorageLocation();
-		List<java.nio.file.Path> projects = new ArrayList<>();
-		findMetaData(projects, storageLocation);
-		List<ExampleData> result = reader.parse(projects);
-		Collections.sort(result);
-		return result;
-	}
-
-	protected void findMetaData(List<java.nio.file.Path> result, java.nio.file.Path root) {
-		try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(root)) {
-			for (java.nio.file.Path entry : stream) {
-				if (Files.isDirectory(entry)) {
-					findMetaData(result, entry);
-				} else if (entry.getFileName().toString().equals(METADATA_JSON)) {
-					result.add(entry);
-				}
-			}
-			stream.close();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-	}
-	
-	protected boolean hasMetaData(java.nio.file.Path root) {
-		List<java.nio.file.Path> result = new ArrayList<>();
-		findMetaData(result, root);
-		return !result.isEmpty();
-	}
-
-	@Override
-	public void importExample(ExampleData edata, IProgressMonitor monitor) {
-		try {
-			IProjectDescription original = ResourcesPlugin.getWorkspace()
-					.loadProjectDescription(new Path(edata.getProjectDir().getAbsolutePath()).append("/.project"));
-			IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(edata.getProjectDir().getName());
-
-			IProjectDescription clone = ResourcesPlugin.getWorkspace()
-					.newProjectDescription(original.getName());
-			clone.setBuildSpec(original.getBuildSpec());
-			clone.setComment(original.getComment());
-			clone.setDynamicReferences(original
-					.getDynamicReferences());
-			clone.setNatureIds(original.getNatureIds());
-			clone.setReferencedProjects(original
-					.getReferencedProjects());
-			if(project.exists()){
-				return;
-			}
-			project.create(clone, monitor);
-			project.open(monitor);
-			
-			@SuppressWarnings("unchecked")
-			List<IFile> filesToImport = FileSystemStructureProvider.INSTANCE.getChildren(edata.getProjectDir());
-			ImportOperation io = new ImportOperation(project.getFullPath(), edata.getProjectDir(),
-					FileSystemStructureProvider.INSTANCE, new IOverwriteQuery() {
-
-						@Override
-						public String queryOverwrite(String pathString) {
-							return IOverwriteQuery.ALL;
-						}
-
-					}, filesToImport);
-			io.setOverwriteResources(true);
-			io.setCreateContainerStructure(false);
-			io.run(monitor);
-			project.refreshLocal(IProject.DEPTH_INFINITE, monitor);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	public void deleteFolder(java.nio.file.Path path) throws IOException {
-		if (!Files.exists(path))
-			return;
-		Files.walkFileTree(path, new SimpleFileVisitor<java.nio.file.Path>() {
-			@Override
-			public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs) throws IOException {
-				Files.delete(file);
-				return FileVisitResult.CONTINUE;
-			}
-
-			@Override
-			public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc) throws IOException {
-				Files.delete(dir);
-				return FileVisitResult.CONTINUE;
-			}
-		});
-	}
-
-	@Override
-	public boolean isUpToDate(IProgressMonitor monitor) {
-		java.nio.file.Path storageLocation = getStorageLocation();
-		try {
-			FetchCommand fetch = Git.open(storageLocation.toFile()).fetch();
-			FetchResult result = fetch.setProgressMonitor(new EclipseGitProgressTransformer(monitor)).setDryRun(true)
-					.call();
-			Collection<TrackingRefUpdate> trackingRefUpdates = result.getTrackingRefUpdates();
-			return trackingRefUpdates.size() == 0;
-		} catch (RepositoryNotFoundException ex) {
-			// This is the case when the examples are imported manually
-			return true;
-		} catch (Exception ex) {
-			ex.printStackTrace();
-			return true;
-		}
-	}
-
+/**
+ * Copyright (c) 2016 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.examples.wizard.service.git;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jgit.api.FetchCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.PullResult;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.transport.FetchResult;
+import org.eclipse.jgit.transport.TrackingRefUpdate;
+import org.yakindu.sct.examples.wizard.ExampleActivator;
+import org.yakindu.sct.examples.wizard.preferences.ExamplesPreferenceConstants;
+import org.yakindu.sct.examples.wizard.service.IExampleService;
+import org.yakindu.sct.examples.wizard.service.data.ExampleData;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * 
+ * @author t00manysecretss
+ * @author andreas muelder - let GitRepositoryExampleService implement
+ *         {@link IExampleService} interface
+ * 
+ */
+@Singleton
+public class GitRepositoryExampleService implements IExampleService {
+
+	private static final String METADATA_JSON = "metadata.json";
+
+	@Inject
+	private IExampleDataReader reader;
+
+	protected java.nio.file.Path getStorageLocation() {
+		return java.nio.file.Paths.get(ExampleActivator.getDefault().getPreferenceStore()
+				.getString(ExamplesPreferenceConstants.STORAGE_LOCATION));
+	}
+
+	@Override
+	public boolean exists() {
+		return Files.exists(getStorageLocation()) && hasMetaData(getStorageLocation());
+	}
+
+	@Override
+	public IStatus fetchAllExamples(IProgressMonitor monitor) {
+		if (!exists()) {
+			java.nio.file.Path storageLocation = getStorageLocation();
+			try {
+				Files.createDirectories(storageLocation);
+			} catch (IOException e1) {
+				return new Status(IStatus.ERROR, ExampleActivator.PLUGIN_ID,
+						"Unable to create folder " + storageLocation.getFileName());
+			}
+			return cloneRepository(monitor);
+		} else {
+			return updateRepository(monitor);
+		}
+	}
+
+	protected IStatus updateRepository(IProgressMonitor monitor) {
+		String repoURL = getPreference(ExamplesPreferenceConstants.REMOTE_LOCATION);
+		try {
+			java.nio.file.Path storageLocation = getStorageLocation();
+			PullResult result = Git.open(storageLocation.toFile()).pull()
+					.setProgressMonitor(new EclipseGitProgressTransformer(monitor)).call();
+			if (!result.isSuccessful()) {
+				return new Status(IStatus.ERROR, ExampleActivator.PLUGIN_ID,
+						"Unable to update repository " + repoURL + "!");
+			}
+		} catch (GitAPIException | IOException e) {
+			return new Status(IStatus.ERROR, ExampleActivator.PLUGIN_ID,
+					"Unable to update repository " + repoURL + "!");
+		}
+		return Status.OK_STATUS;
+	}
+
+	protected String getPreference(String constant) {
+		return ExampleActivator.getDefault().getPreferenceStore().getString(constant);
+	}
+
+	protected IStatus cloneRepository(IProgressMonitor monitor) {
+		String repoURL = getPreference(ExamplesPreferenceConstants.REMOTE_LOCATION);
+		String remoteBranch = getPreference(ExamplesPreferenceConstants.REMOTE_BRANCH);
+		Git call = null;
+		java.nio.file.Path storageLocation = getStorageLocation();
+		try {
+			call = Git.cloneRepository().setURI(repoURL).setDirectory(storageLocation.toFile())
+					.setProgressMonitor(new EclipseGitProgressTransformer(monitor)).setBranch(remoteBranch).call();
+		} catch (GitAPIException e) {
+			try {
+				deleteFolder(storageLocation);
+			} catch (IOException ex) {
+				ex.printStackTrace();
+			}
+			return new Status(IStatus.ERROR, ExampleActivator.PLUGIN_ID, "Unable to clone repository " + repoURL + "!");
+		} finally {
+			if (call != null)
+				call.close();
+			if (monitor.isCanceled()) {
+				try {
+					deleteFolder(storageLocation);
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return Status.OK_STATUS;
+	}
+
+	@Override
+	public List<ExampleData> getExamples(IProgressMonitor monitor) {
+		java.nio.file.Path storageLocation = getStorageLocation();
+		List<java.nio.file.Path> projects = new ArrayList<>();
+		findMetaData(projects, storageLocation);
+		List<ExampleData> result = reader.parse(projects);
+		Collections.sort(result);
+		return result;
+	}
+
+	protected void findMetaData(List<java.nio.file.Path> result, java.nio.file.Path root) {
+		try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(root)) {
+			for (java.nio.file.Path entry : stream) {
+				if (Files.isDirectory(entry)) {
+					findMetaData(result, entry);
+				} else if (entry.getFileName().toString().equals(METADATA_JSON)) {
+					result.add(entry);
+				}
+			}
+			stream.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	protected boolean hasMetaData(java.nio.file.Path root) {
+		List<java.nio.file.Path> result = new ArrayList<>();
+		findMetaData(result, root);
+		return !result.isEmpty();
+	}
+
+	protected void deleteFolder(java.nio.file.Path path) throws IOException {
+		if (!Files.exists(path))
+			return;
+		Files.walkFileTree(path, new SimpleFileVisitor<java.nio.file.Path>() {
+			@Override
+			public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs) throws IOException {
+				Files.delete(file);
+				return FileVisitResult.CONTINUE;
+			}
+
+			@Override
+			public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc) throws IOException {
+				Files.delete(dir);
+				return FileVisitResult.CONTINUE;
+			}
+		});
+	}
+
+	@Override
+	public boolean isUpToDate(IProgressMonitor monitor) {
+		java.nio.file.Path storageLocation = getStorageLocation();
+		try {
+			FetchCommand fetch = Git.open(storageLocation.toFile()).fetch();
+			FetchResult result = fetch.setProgressMonitor(new EclipseGitProgressTransformer(monitor)).setDryRun(true)
+					.call();
+			Collection<TrackingRefUpdate> trackingRefUpdates = result.getTrackingRefUpdates();
+			return trackingRefUpdates.size() == 0;
+		} catch (RepositoryNotFoundException ex) {
+			// This is the case when the examples are imported manually
+			return true;
+		} catch (Exception ex) {
+			ex.printStackTrace();
+			return true;
+		}
+	}
 }

+ 1 - 1
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/git/IExampleDataReader.java

@@ -13,7 +13,7 @@ package org.yakindu.sct.examples.wizard.service.git;
 import java.nio.file.Path;
 import java.util.List;
 
-import org.yakindu.sct.examples.wizard.service.ExampleData;
+import org.yakindu.sct.examples.wizard.service.data.ExampleData;
 
 /**
  * 

+ 1 - 1
plugins/org.yakindu.sct.examples.wizard/src/org/yakindu/sct/examples/wizard/service/git/JsonMetaDataReader.java

@@ -16,7 +16,7 @@ import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.yakindu.sct.examples.wizard.service.ExampleData;
+import org.yakindu.sct.examples.wizard.service.data.ExampleData;
 
 import com.google.gson.Gson;