ImportPage.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.workingsets;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IElementFactory;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.internal.IWorkbenchConstants;
import org.osate.ui.OsateUiPlugin;
/**
* @author Andrey
*/
@SuppressWarnings("restriction")
public class ImportPage extends WSPage {
private static final String TITLE = "Import working sets from the local file system";
private static final String DESCRIPTION = "Select the file path to import working "
+ "sets from and working sets to import";
protected boolean isMerge;
protected ImportPage(String pageName, Shell shell) {
super(pageName, TITLE, DESCRIPTION, "icons/workingsets/import_wiz.gif", shell, SWT.OPEN);
isMerge = true;
}
@Override
public void createControl(Composite parent) {
super.createControl(parent);
final Button chooserBtn = new Button(comp, SWT.CHECK);
chooserBtn.setSelection(isMerge);
chooserBtn.setText("Merge with existing working sets");
chooserBtn.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// ignored
}
@Override
public void widgetSelected(SelectionEvent e) {
isMerge = chooserBtn.getSelection();
}
});
}
private String readSets() {
String pathname = getFileString();
if (pathname == null) {
return "Please select a file";
}
File file = new File(pathname);
FileInputStream input = null;
BufferedReader reader;
IMemento memento;
try {
input = new FileInputStream(file);
reader = new BufferedReader(new InputStreamReader(input, "utf-8"));
memento = XMLMemento.createReadRoot(reader);
} catch (FileNotFoundException e) {
return "Couldn't read working set file: " + file + ": " + e.getMessage();
} catch (IOException e) {
return "Couldn't read working set file: " + file + ": " + e.getMessage();
} catch (CoreException e) {
return "Couldn't read working set file: " + file + ": " + e.getMessage();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
OsateUiPlugin.log(e);
}
}
}
IMemento[] mementos = memento.getChildren("workingSet");
List<IWorkingSet> sets = new ArrayList<IWorkingSet>();
for (int i = 0; i < mementos.length; i++) {
IWorkingSet set = restoreWorkingSet(mementos[i]);
if (set != null) {
sets.add(set);
}
}
setInput(sets.toArray(new IWorkingSet[sets.size()]));
try {
String lastUsedFile = file.getCanonicalPath();
IPreferenceStore store = OsateUiPlugin.getDefault().getPreferenceStore();
store.setValue(LAST_USED_WS_FILE, lastUsedFile);
} catch (IOException e) {
OsateUiPlugin.log(e);
}
return null;
}
// see org.eclipse.ui.internal.AbstractWorkingSet
protected IWorkingSet restoreWorkingSet(IMemento memento) {
String factoryID = memento.getString(IWorkbenchConstants.TAG_FACTORY_ID);
if (factoryID == null) {
// if the factory id was not set in the memento
// then assume that the memento was created using
// IMemento.saveState, and should be restored using WorkingSetFactory
factoryID = "org.eclipse.ui.internal.WorkingSetFactory";
}
IElementFactory factory = PlatformUI.getWorkbench().getElementFactory(factoryID);
if (factory == null) {
OsateUiPlugin.logErrorMessage("Unable to restore working set - cannot instantiate factory: " + factoryID);
return null;
}
IAdaptable adaptable = factory.createElement(memento);
if (adaptable == null) {
OsateUiPlugin.logErrorMessage("Unable to restore working set - cannot instantiate working set: " + factoryID);
return null;
}
if (!(adaptable instanceof IWorkingSet)) {
OsateUiPlugin.logErrorMessage("Unable to restore working set - element is not an IWorkingSet: " + factoryID);
return null;
}
return (IWorkingSet) adaptable;
}
public boolean finish() {
importSelectedSets();
return true;
}
private void importSelectedSets() {
Object[] selected = getSelectedWorkingSets();
if (selected == null) {
return;
}
IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager();
List<IWorkingSet> added = new ArrayList<IWorkingSet>();
for (int i = 0; i < selected.length; i++) {
IWorkingSet workingSet = (IWorkingSet) selected[i];
IWorkingSet oldWorkingSet = workingSetManager.getWorkingSet(workingSet.getName());
if (oldWorkingSet == null) {
removeNonExistingChildren(workingSet);
workingSetManager.addWorkingSet(workingSet);
added.add(workingSet);
} else if (isMerge) {
removeNonExistingChildren(workingSet);
mergeWorkingSets(oldWorkingSet, workingSet);
}
}
}
private static void removeNonExistingChildren(IWorkingSet workingSet) {
IAdaptable[] elements = workingSet.getElements();
List<IResource> existing = new ArrayList<>();
for (int i = 0; i < elements.length; i++) {
IResource resource = getResource(elements[i]);
if (resource != null && resource.exists()) {
existing.add(resource);
}
}
workingSet.setElements(existing.toArray(new IAdaptable[existing.size()]));
}
public static class WorkingSetContentProvider implements ITreeContentProvider {
private IWorkingSet[] workingSets;
@Override
public void dispose() {
// noop
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (newInput instanceof IWorkingSet[]) {
workingSets = (IWorkingSet[]) newInput;
}
}
@Override
public Object[] getElements(Object inputElement) {
if (workingSets == null) {
return new Object[0];
}
List<IWorkingSet> sets = new ArrayList<IWorkingSet>();
for (int i = 0; i < workingSets.length; i++) {
IWorkingSet workingSet = workingSets[i];
if (!workingSet.isAggregateWorkingSet()) {
sets.add(workingSet);
}
}
return sets.toArray(new IWorkingSet[sets.size()]);
}
@Override
public Object[] getChildren(Object parentElement) {
return new Object[0];
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
return false;
}
}
@Override
protected IStructuredContentProvider createContentProvider() {
return new WorkingSetContentProvider();
}
@Override
protected void selectionChanged() {
String errorMessage = null;
if (getSelectedWorkingSets().length == 0) {
errorMessage = "Please select at least one working set";
}
setErrorMessage(errorMessage);
setPageComplete(errorMessage == null);
}
@Override
protected boolean validateInput() {
String errorMessage = null;
String text = getFileString();
if (text == null) {
errorMessage = "Please select a file";
}
if (errorMessage != null) {
setInput(new IWorkingSet[0]);
setErrorMessage(errorMessage);
setPageComplete(false);
return false;
}
errorMessage = readSets();
if (errorMessage != null) {
errorMessage = "Working set import failed: " + errorMessage;
} else if (getSelectedWorkingSets().length == 0) {
errorMessage = "Please select at least one working set";
}
setErrorMessage(errorMessage);
setPageComplete(errorMessage == null);
if (errorMessage != null) {
setInput(new IWorkingSet[0]);
}
return errorMessage == null;
}
public void setInitialSelection(IStructuredSelection selection) {
if (selection == null) {
return;
}
IResource resource = getResource(selection);
if (resource == null) {
return;
}
IPath location = resource.getLocation();
if (location != null && "wst".equals(location.getFileExtension()) && location.toFile().isFile()) {
usedFiles.add(location.toOSString());
}
}
private void mergeWorkingSets(IWorkingSet oldWorkingSet, IWorkingSet newWorkingSet) {
if (!oldWorkingSet.isEditable()) {
return;
}
IAdaptable[] elementsOld = oldWorkingSet.getElements();
IAdaptable[] elementsNew = newWorkingSet.getElements();
if (elementsNew == null || elementsOld == null || elementsNew.length == 0) {
return;
}
LinkedHashSet<IAdaptable> set = new LinkedHashSet<IAdaptable>(Arrays.asList(elementsOld));
ArrayList<IAdaptable> newList = new ArrayList<IAdaptable>(Arrays.asList(elementsNew));
newList.removeAll(set);
if (newList.size() == 0) {
return;
}
elementsNew = oldWorkingSet.adaptElements(newList.toArray(new IAdaptable[newList.size()]));
newList = new ArrayList<IAdaptable>(Arrays.asList(elementsNew));
newList.removeAll(set);
if (newList.size() == 0) {
return;
}
set.addAll(newList);
oldWorkingSet.setElements(set.toArray(new IAdaptable[set.size()]));
}
/**
* @param o
* selection or some object which is or can be adapted to resource
* @return given object as resource, may return null
*/
private static IResource getResource(Object o) {
IResource r = getAdapter(o, IResource.class);
if (r != null) {
return r;
}
return getAdapter(o, IFile.class);
}
/**
* Adapt object to given target class type
*
* @param o
* selection or some object which is or can be adapted to given type
* @param target
* @param <V> type of target
* @return adapter from given object to given type, may return null
*/
private static <V> V getAdapter(Object o, Class<V> target) {
if (o instanceof IStructuredSelection) {
IStructuredSelection selection = (IStructuredSelection) o;
if (selection.isEmpty()) {
return null;
}
o = selection.getFirstElement();
}
if (o == null) {
return null;
}
if (target.isInstance(o)) {
return target.cast(o);
}
if (o instanceof IAdaptable) {
V adapter = (V) ((IAdaptable) o).getAdapter(target);
if (adapter != null) {
return adapter;
}
}
// If the source object is a platform object then it's already tried calling AdapterManager.getAdapter
if (o instanceof PlatformObject) {
return null;
}
Object adapted = Platform.getAdapterManager().getAdapter(o, target);
return target.cast(adapted);
}
}