OsateExampleWizardPage.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.ui.wizards;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.InvalidRegistryObjectException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
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.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.statushandlers.StatusManager;
import org.osate.ui.OsateUiPlugin;
import org.osgi.framework.Bundle;
/**
* @since 5.0
*/
public class OsateExampleWizardPage extends WizardPage {
public OsateExampleWizardPage(String pageName) {
super(pageName);
}
public OsateExampleWizardPage() {
super("Examples");
setTitle("Examples Wizard Page");
setDescription("Examples Wizard");
}
private static final String ATT_NODE = "examples";
private static final String ATT_NAME = "name";
private static final String ATT_EXAMPLEURI = "exampleURI";
private static final String ATT_READMEURI = "readmeURI";
private static final String ATT_CATEGORY = "category";
private static final String ATT_PROJECTPATH = "path";
protected Browser browser;
protected PluginInfo selectedProject;
public PluginInfo getSelectedProject() {
return selectedProject;
}
public class TreeContentProvider implements ITreeContentProvider {
PluginInfo treeContent;
@Override
public void dispose() {
// Nothing to do.
}
@SuppressWarnings("unchecked")
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
treeContent = (PluginInfo) newInput;
}
@Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof PluginInfo) {
return ((PluginInfo) parentElement).getNode().toArray();
} else {
return null;
}
}
@SuppressWarnings("unchecked")
@Override
public Object getParent(Object element) {
if (element instanceof PluginInfo) {
return ((PluginInfo) element).getParent();
}
return null;
}
@Override
public boolean hasChildren(Object element) {
return getChildren(element).length > 0;
}
}
public class FileLabelProvider extends LabelProvider {
public FileLabelProvider(Image fileImg, Image categoryImg) {
super();
}
@Override
public Image getImage(Object element) {
return null;
}
@Override
public void dispose() {
super.dispose();
}
@Override
public String getText(Object element) {
return ((PluginInfo) element).name;
}
}
@Override
public void performHelp() {
PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), "org.osate.ui.help_dialog");
}
@Override
public void createControl(Composite parent) {
try {
Composite panelChoice = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight = 5;
layout.marginWidth = 5;
panelChoice.setLayout(layout);
SashForm sashForm = new SashForm(panelChoice, SWT.HORIZONTAL);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
sashForm.setLayoutData(gd);
initializeDialogUnits(sashForm);
getShell().setSize(convertWidthInCharsToPixels(150), getShell().getSize().y);
PluginInfo root = loadExamples();
final TreeViewer pickTree = createTree(sashForm);
pickTree.setLabelProvider(new FileLabelProvider(null, null));
pickTree.setContentProvider(new TreeContentProvider());
pickTree.setInput(root);
pickTree.setComparator(new ViewerComparator());
pickTree.addSelectionChangedListener(event -> {
browser.setText("<p>Loading readme</p>");
// reset an error message
super.setErrorMessage(null);
if (isCurrentPage()) {
getContainer().updateMessage();
}
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
for (final Iterator<?> iter = selection.iterator(); iter.hasNext();) {
final Object object = iter.next();
if (object instanceof PluginInfo) {
selectedProject = (PluginInfo) object;
// do not show error message if user clicked on category
if (selectedProject.category.equalsIgnoreCase(selectedProject.name)) {
browser.setText("<p>Please select a project</p>");
return;
}
if (selectedProject.readmeURI != null) {
try {
File f = new File(selectedProject.readmeURI.getPath());
if (f.exists()) {
browser.setUrl(f.toURL().toString());
} else {
throw new IOException("Readme file not found");
}
} catch (IllegalArgumentException | IOException e) {
browser.setText("<p>Failed to load readme</p>");
setErrorMessage("Failed to load readme");
catchError(e, e.getMessage());
}
} else {
browser.setText("<p>Failed to load readme</p>");
setErrorMessage("Failed to load readme");
catchError(new IOException(), "Readme file not found or missing");
}
}
}
});
browser = new Browser(sashForm, SWT.NONE);
GridData layoutData = new GridData(GridData.FILL_BOTH);
// layoutData.widthHint = 20 * getShell().getMonitor().getBounds().width;
// layoutData.widthHint = getShell().computeSize(20 * SWT.DEFAULT, SWT.DEFAULT).x;
// layoutData.widthHint = convertWidthInCharsToPixels(500);
layoutData.verticalSpan = 100;
browser.setLayoutData(layoutData);
browser.setText(
"<p>Expand the category on the left and select an example project to import. If the project has a description available, it will be shown here once the project is selected</p>");
sashForm.setWeights(new int[] { 1, 4 });
setControl(panelChoice);
} catch (Exception e) {
catchError(e, e.getMessage());
}
}
public List<PluginInfo> loadExamplesFromPlugin() {
List<PluginInfo> result = new ArrayList<PluginInfo>();
final IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(OsateUiPlugin.PLUGIN_ID, ATT_NODE);
IExtension[] exts = extensionPoint.getExtensions();
for (int i = 0; i < exts.length; i++) {
try {
IConfigurationElement[] configElems = exts[i].getConfigurationElements();
if (configElems != null) {
Bundle bundle = Platform.getBundle(exts[i].getContributor().getName());
for (int j = 0; j < configElems.length; j++) {
PluginInfo project = new PluginInfo(
org.eclipse.core.runtime.FileLocator
.toFileURL(bundle.getEntry(configElems[j].getAttribute(ATT_EXAMPLEURI))),
org.eclipse.core.runtime.FileLocator
.toFileURL(bundle.getEntry(combine(configElems[j].getAttribute(ATT_EXAMPLEURI),
configElems[j].getAttribute(ATT_READMEURI)))),
configElems[j].getAttribute(ATT_NAME), configElems[j].getAttribute(ATT_CATEGORY),
exts[i].getContributor().getName());
if (project != null && project.name != null && project.exampleURI != null) {
project.exampleS = configElems[j].getAttribute(ATT_EXAMPLEURI);
// list of projects
IConfigurationElement[] projectElems = configElems[j].getChildren();
if (projectElems != null) {
for (int k = 0; k < projectElems.length; k++) {
project.addProjectPath(projectElems[k].getAttribute(ATT_PROJECTPATH));
}
}
result.add(project);
}
}
}
} catch (NullPointerException | InvalidRegistryObjectException | IOException e) {
catchError(e, e.getMessage());
}
}
return result;
}
/**
* @since 4.0
*/
protected PluginInfo loadExamples() {
PluginInfo result = new PluginInfo();
List<PluginInfo> projectInfo = loadExamplesFromPlugin();
for (PluginInfo p : projectInfo) {
try {
File file = null;
if (Platform.isRunning()) {
if (p.exampleURI == null) {
continue;
}
file = new File(FileLocator.toFileURL(p.exampleURI).getFile());
}
if (file == null) {
continue; // if example files are not found, there is no point in showing it as an option to import
}
// check if node with this category exists
List<PluginInfo> existingCategories = result.getNode();
Object[] currentNodeCategory = existingCategories.stream().filter(x -> x.category != null
&& p.category != null && x.category.compareToIgnoreCase(p.category) == 0).toArray();
if (currentNodeCategory != null && currentNodeCategory.length > 0) {
for (int j = 0; j < currentNodeCategory.length; j++) {
((PluginInfo) currentNodeCategory[j]).addNode(p);
}
} else {
// add category node to root -> add the project under category
PluginInfo cNode = new PluginInfo(null, null, p.category, p.category, null);
cNode.addNode(p);
result.addNode(cNode);
}
}
catch (IOException e) {
catchError(e, e.getMessage());
}
}
return result;
}
/**
* @since 4.0
*/
protected TreeViewer createTree(Composite parent) {
GridData compLayout = new GridData(GridData.FILL_BOTH);
compLayout.heightHint = 200;
compLayout.widthHint = 200;
Composite treeComposite = new Composite(parent, SWT.NONE);
treeComposite.setLayoutData(compLayout);
GridData dataLayout = new GridData(GridData.FILL_BOTH);
dataLayout.heightHint = compLayout.heightHint;
dataLayout.widthHint = compLayout.widthHint;
int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL;
Tree tree = new Tree(treeComposite, style);
tree.setLayoutData(dataLayout);
tree.setLinesVisible(true);
tree.setHeaderVisible(false);
tree.setFont(parent.getFont());
TreeColumn col = new TreeColumn(tree, SWT.LEFT);
TreeColumnLayout treeLayout = new TreeColumnLayout();
treeLayout.setColumnData(col, new ColumnWeightData(dataLayout.widthHint));
treeComposite.setLayout(treeLayout);
return new TreeViewer(tree);
}
public static String combine(String path1, String path2) {
File file1 = new File(path1);
File file2 = new File(file1, path2);
return file2.getPath();
}
protected void catchError(Exception e, String message) {
IStatus status = new Status(IStatus.ERROR, OsateUiPlugin.PLUGIN_ID, message, e);
StatusManager manager = StatusManager.getManager();
manager.handle(status, StatusManager.LOG);
}
/**
* The <code>WizardPage</code> implementation of this method
* declared on <code>DialogPage</code> updates the container
* if this is the current page.
*/
@Override
public void setErrorMessage(String newMessage) {
super.setErrorMessage(newMessage);
if (isCurrentPage()) {
getContainer().updateMessage();
}
}
}