blob: 70c449d10fe44c3f35997c3168593308d6959b3a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2019 EclipseSource Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* EclipseSource Corporation - initial API and implementation
* IBM Corporation - ongoing enhancements
* Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 541067, 546400
*******************************************************************************/
package org.eclipse.pde.internal.ui.preferences;
import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.*;
import java.util.List;
import java.util.Map.Entry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.target.*;
import org.eclipse.pde.internal.core.*;
import org.eclipse.pde.internal.core.target.*;
import org.eclipse.pde.internal.ui.*;
import org.eclipse.pde.internal.ui.shared.target.*;
import org.eclipse.pde.internal.ui.shared.target.Messages;
import org.eclipse.pde.internal.ui.util.SWTUtil;
import org.eclipse.pde.internal.ui.util.SharedLabelProvider;
import org.eclipse.pde.internal.ui.wizards.target.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.progress.UIJob;
import org.osgi.framework.Version;
/**
* Preference page for managing all known target definitions and setting one as the active target platform.
*/
public class TargetPlatformPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
/**
* The ID of this preference page used to contribute via extension.<br>
* Value is: "org.eclipse.pde.ui.TargetPlatformPreferencePage"
*/
public static final String PAGE_ID = "org.eclipse.pde.ui.TargetPlatformPreferencePage"; //$NON-NLS-1$
private static final String ORG_ECLIPSE_OSGI = "org.eclipse.osgi"; //$NON-NLS-1$
private class TargetLabelProvider extends StyledCellLabelProvider {
// Definition corresponding to running host
private TargetDefinition fRunningHost;
private Font fTextFont;
public TargetLabelProvider() {
PDEPlugin.getDefault().getLabelProvider().connect(this);
}
public void setDefaultTarget(TargetDefinition newDefaultTarget) {
fRunningHost = newDefaultTarget;
}
/**
* @return a bold dialog font
*/
private Font getBoldFont() {
if (fTextFont == null) {
Font dialogFont = JFaceResources.getDialogFont();
FontData[] fontData = dialogFont.getFontData();
for (FontData data : fontData) {
data.setStyle(SWT.BOLD);
}
Display display = getShell().getDisplay();
fTextFont = new Font(display, fontData);
}
return fTextFont;
}
@Override
public String getToolTipText(Object element) {
ITargetDefinition targetDef = (ITargetDefinition) element;
if (targetDef.isResolved())
return null;
if (!isResolved(targetDef)) {
String name = targetDef.getName();
return NLS.bind(Messages.TargetStatus_UnresolvedTarget, name);
}
return null;
}
@Override
public Point getToolTipShift(Object object) {
return new Point(5, 5);
}
@Override
public int getToolTipDisplayDelayTime(Object object) {
return 100;
}
@Override
public int getToolTipTimeDisplayed(Object object) {
return 5000;
}
@Override
public void update(ViewerCell cell) {
final Object element = cell.getElement();
Styler style = new Styler() {
@Override
public void applyStyles(TextStyle textStyle) {
if (element.equals(fActiveTarget)) {
textStyle.font = getBoldFont();
}
}
};
ITargetDefinition targetDef = (ITargetDefinition) element;
ITargetHandle targetHandle = targetDef.getHandle();
String name = targetDef.getName();
if (name == null || name.length() == 0) {
name = targetHandle.toString();
}
if (targetDef.equals(fActiveTarget)) {
name = name + PDEUIMessages.TargetPlatformPreferencePage2_1;
}
StyledString styledString = new StyledString(name, style);
if (targetHandle instanceof WorkspaceFileTargetHandle) {
IFile file = ((WorkspaceFileTargetHandle) targetHandle).getTargetFile();
String location = " - " + file.getFullPath(); //$NON-NLS-1$
styledString.append(location, StyledString.DECORATIONS_STYLER);
} else if (targetHandle instanceof ExternalFileTargetHandle) {
URI uri = ((ExternalFileTargetHandle) targetHandle).getLocation();
String location = " - " + uri.toASCIIString(); //$NON-NLS-1$
styledString.append(location, StyledString.DECORATIONS_STYLER);
} else {
String location = (String) cell.getItem().getData(DATA_KEY_MOVED_LOCATION);
if (location != null) {
location = " - " + location; //$NON-NLS-1$
styledString = new StyledString(name, style);
styledString.append(location, StyledString.QUALIFIER_STYLER);
}
}
cell.setText(styledString.toString());
cell.setStyleRanges(styledString.getStyleRanges());
if (fTableViewer.getChecked(targetDef) && !targetDef.isResolved())
performResolve(targetDef);
cell.setImage(getImage(targetDef));
super.update(cell);
}
/**
* checks the resolution status of current target or any other previous
* target with the same handle
*/
private boolean isResolved(ITargetDefinition target) {
boolean isResolved = false;
if (target.equals(fActiveTarget) && target.isResolved()) {
isResolved = true;
} else {
// checked earlier status of earlier resolved targets
HashMap<ITargetHandle, List<TargetDefinition>> targetFlagMap = TargetPlatformHelper
.getTargetDefinitionMap();
for (Entry<ITargetHandle, List<TargetDefinition>> entry : targetFlagMap.entrySet()) {
if (entry.getKey().equals(target.getHandle())) {
if (!entry.getValue().isEmpty()) {
if (entry.getValue().get(0).isContentEquivalent(target)) {
isResolved = true;
break;
}
}
}
}
}
return isResolved;
}
private Image getImage(ITargetDefinition target) {
int flag = 0;
if (target.equals(fActiveTarget) && target.isResolved()) {
// If the user has resolved the target, display any errors
if (target.getStatus().getSeverity() == IStatus.WARNING) {
flag = SharedLabelProvider.F_WARNING;
} else if (target.getStatus().getSeverity() == IStatus.ERROR) {
flag = SharedLabelProvider.F_ERROR;
}
} else {
// checked earlier status of earlier resolved targets
boolean isResolved = false;
HashMap<ITargetHandle, List<TargetDefinition>> targetFlagMap = TargetPlatformHelper
.getTargetDefinitionMap();
for (Entry<ITargetHandle, List<TargetDefinition>> entry : targetFlagMap.entrySet()) {
if (entry.getKey().equals(target.getHandle())) {
List<TargetDefinition> targetList = entry.getValue();
if (!targetList.isEmpty()) {
if (targetList.get(0).isContentEquivalent(target)
&& targetList.get(0).getStatus() != null) {
int value = targetList.get(0).getStatus().getSeverity();
if (value == IStatus.WARNING) {
flag = SharedLabelProvider.F_WARNING;
} else if (value == IStatus.ERROR) {
flag = SharedLabelProvider.F_ERROR;
}
isResolved = true;
}
else
isResolved = false;
break;
}
}
}
if (isResolved == false)
flag = SharedLabelProvider.F_WARNING;
}
if (target.getTargetLocations() == null)
flag = 0;
if (fRunningHost != null && fRunningHost.isContentEquivalent(target)) {
return PDEPlugin.getDefault().getLabelProvider().get(PDEPluginImages.DESC_PRODUCT_BRANDING, flag);
}
return PDEPlugin.getDefault().getLabelProvider().get(PDEPluginImages.DESC_TARGET_DEFINITION, flag);
}
@Override
public void dispose() {
PDEPlugin.getDefault().getLabelProvider().disconnect(this);
if (fTextFont != null) {
fTextFont.dispose();
fTextFont = null;
}
super.dispose();
}
}
/**
* Runs the creation of the default target definition in a non-UI thread. Normally
* this operation is very fast, but in some cases loading vm arguments can take a while
* and interrupt the UI thread.
*/
private class LoadDefaultTargetJob extends Job {
public LoadDefaultTargetJob() {
super(PDEUIMessages.TargetPlatformPreferencePage_LoadDefaultTarget);
}
public TargetDefinition defaultTarget;
@Override
public IStatus run(IProgressMonitor monitor) {
SubMonitor subMon = SubMonitor.convert(monitor);
ITargetPlatformService service = getTargetService();
if (service != null) {
defaultTarget = (TargetDefinition) service.newDefaultTarget();
}
subMon.done();
if (monitor != null) {
monitor.done();
}
return Status.OK_STATUS;
}
}
/**
* Constant key value used to store data in table items if they are moved to a new location
*/
private final static String DATA_KEY_MOVED_LOCATION = "movedLocation"; //$NON-NLS-1$
// Table viewer
private CheckboxTableViewer fTableViewer;
// Buttons
private Button fReloadButton;
private Button fAddButton;
private Button fEditButton;
//private Button fDuplicateButton;
private Button fRemoveButton;
private Button fMoveButton;
// Text displaying additional information
private TreeViewer fDetails;
private TargetLabelProvider fLabelProvider;
/**
* Initial collection of targets (handles are realized into definitions as working copies)
*/
private List<ITargetDefinition> fTargets = new ArrayList<>();
/**
* Removed definitions (to be removed on apply)
*/
private List<ITargetDefinition> fRemoved = new ArrayList<>();
/**
* Moved definitions (to be moved on apply)
*/
private Map<Object, Object> fMoved = new HashMap<>(1);
/**
* The chosen active target (will be loaded on apply)
*/
private ITargetDefinition fActiveTarget;
/**
* Currently active target definition
*/
private ITargetDefinition fPrevious;
/**
* Stores whether the current target platform is out of synch with the file system and must be reloaded
*/
private boolean isOutOfSynch = false;
@Override
public Control createContents(Composite parent) {
Composite container = SWTFactory.createComposite(parent, 1, 1, GridData.FILL_BOTH, 0, 0);
createTargetProfilesGroup(container);
Dialog.applyDialogFont(container);
PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IHelpContextIds.TARGET_PLATFORM_PREFERENCE_PAGE);
return container;
}
/**
* Performs resolve of selected target in fTableViewer
*
*/
private void performResolve(Object element) {
if (!(element instanceof ITargetDefinition)) {
return;
}
final ITargetDefinition target = (ITargetDefinition) element;
if (target.isResolved())
return;
String name = target.getName();
if (name == null)
name = ""; //$NON-NLS-1$
Job resolveJob = new Job(NLS.bind(PDEUIMessages.TargetEditor_1, name)) {
@Override
protected IStatus run(IProgressMonitor monitor) {
target.resolve(monitor);
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
// Don't return any problems because we don't want an
// error dialog
return Status.OK_STATUS;
}
};
resolveJob.addJobChangeListener(new JobChangeAdapter() {
@Override
public void done(org.eclipse.core.runtime.jobs.IJobChangeEvent event) {
Display.getDefault().syncExec(() -> {
if (!fTableViewer.getControl().isDisposed())
fTableViewer.refresh(true);
if (!fDetails.getControl().isDisposed())
fDetails.refresh(true);
});
}
});
resolveJob.schedule();
}
private void createTargetProfilesGroup(Composite container) {
// Start loading the default target as it is often fast enough to finish before UI is done rendering
fLabelProvider = new TargetLabelProvider();
LoadDefaultTargetJob job = new LoadDefaultTargetJob();
job.addJobChangeListener(new JobChangeAdapter() {
@Override
public void done(final IJobChangeEvent event) {
UIJob job = new UIJob(Messages.UpdateTargetJob_UpdateJobName) {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
TargetDefinition target = ((LoadDefaultTargetJob) event.getJob()).defaultTarget;
if (target != null && fLabelProvider != null) {
fLabelProvider.setDefaultTarget(target);
if (fTableViewer != null && !fTableViewer.getTable().isDisposed()) {
fTableViewer.refresh(true);
}
}
return Status.OK_STATUS;
}
};
job.schedule();
}
});
job.setPriority(Job.SHORT);
job.schedule();
Composite comp = SWTFactory.createComposite(container, 1, 1, GridData.FILL_BOTH, 0, 0);
((GridData) comp.getLayoutData()).widthHint = 350;
SWTFactory.createWrapLabel(comp, PDEUIMessages.TargetPlatformPreferencePage2_0, 2);
SashForm sash = new SashForm(comp, SWT.VERTICAL);
sash.setLayout(new GridLayout());
sash.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
Composite tableComposite = SWTFactory.createComposite(sash, 2, 1, GridData.FILL_BOTH, 0, 0);
SWTFactory.createLabel(tableComposite, PDEUIMessages.TargetPlatformPreferencePage2_2, 2);
fTableViewer = CheckboxTableViewer.newCheckList(tableComposite, SWT.MULTI | SWT.BORDER);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.heightHint = 250;
fTableViewer.getControl().setLayoutData(gd);
fTableViewer.setLabelProvider(fLabelProvider);
fTableViewer.setContentProvider(ArrayContentProvider.getInstance());
fTableViewer.addCheckStateListener(event -> {
if (event.getChecked()) {
fTableViewer.setCheckedElements(new Object[] {event.getElement()});
handleActivate();
// resolve the target if not already resolved
performResolve(event.getElement());
} else {
handleActivate();
}
});
fTableViewer.addSelectionChangedListener(event -> {
updateButtons();
updateDetails();
});
fTableViewer.addDoubleClickListener(event -> handleEdit());
fTableViewer.getTable().addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.character == SWT.DEL) {
handleRemove();
}
}
});
ColumnViewerToolTipSupport.enableFor(fTableViewer, ToolTip.NO_RECREATE);
// add the targets
ITargetPlatformService service = getTargetService();
if (service != null) {
ITargetHandle[] targets = service.getTargets(null);
for (ITargetHandle target : targets) {
try {
fTargets.add(target.getTargetDefinition());
} catch (CoreException e) {
if (target instanceof WorkspaceFileTargetHandle) {
setErrorMessage(e.getMessage() + " " //$NON-NLS-1$
+ ((WorkspaceFileTargetHandle) target).getTargetFile().getFullPath());
}
else
setErrorMessage(e.getMessage());
}
}
fTableViewer.setInput(fTargets);
}
fTableViewer.setComparator(new ViewerComparator() {
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
String name1 = ((TargetDefinition) e1).getName();
String name2 = ((TargetDefinition) e2).getName();
if (name1 == null) {
return -1;
}
if (name2 == null) {
return 1;
}
return name1.compareToIgnoreCase(name2);
}
});
Composite buttonComposite = SWTFactory.createComposite(tableComposite, 1, 1, GridData.FILL_VERTICAL | GridData.VERTICAL_ALIGN_BEGINNING, 0, 0);
fReloadButton = SWTFactory.createPushButton(buttonComposite, PDEUIMessages.TargetPlatformPreferencePage2_16, null);
fReloadButton.addSelectionListener(widgetSelectedAdapter(e -> handleReload()));
SWTFactory.createVerticalSpacer(buttonComposite, 1);
fAddButton = SWTFactory.createPushButton(buttonComposite, PDEUIMessages.TargetPlatformPreferencePage2_3, null);
fAddButton.addSelectionListener(widgetSelectedAdapter(e -> handleAdd()));
fEditButton = SWTFactory.createPushButton(buttonComposite, PDEUIMessages.TargetPlatformPreferencePage2_5, null);
fEditButton.addSelectionListener(widgetSelectedAdapter(e -> handleEdit()));
fRemoveButton = SWTFactory.createPushButton(buttonComposite, PDEUIMessages.TargetPlatformPreferencePage2_7, null);
fRemoveButton.addSelectionListener(widgetSelectedAdapter(e -> handleRemove()));
fMoveButton = SWTFactory.createPushButton(buttonComposite, PDEUIMessages.TargetPlatformPreferencePage2_13, null);
fMoveButton.addSelectionListener(widgetSelectedAdapter(e -> handleMove()));
updateButtons();
Composite detailsComposite = SWTFactory.createComposite(sash, 1, 1, GridData.FILL_BOTH, 0, 0);
sash.setWeights(new int[] { 70, 30 });
SWTFactory.createLabel(detailsComposite, PDEUIMessages.TargetPlatformPreferencePage2_25, 1);
fDetails = new TreeViewer(detailsComposite);
fDetails.setLabelProvider(new StyledBundleLabelProvider(true, true));
fDetails.setContentProvider(new TargetLocationContentProvider());
gd = new GridData(GridData.FILL_BOTH);
gd.heightHint = 50;
fDetails.getControl().setLayoutData(gd);
if (service != null) {
try {
fPrevious = service.getWorkspaceTargetDefinition();
Iterator<ITargetDefinition> iterator = fTargets.iterator();
while (iterator.hasNext()) {
ITargetDefinition target = iterator.next();
if (target.getHandle().equals(fPrevious.getHandle())) {
fActiveTarget = target;
fTableViewer.setCheckedElements(new Object[] {fActiveTarget});
fTableViewer.refresh(target);
break;
}
}
} catch (CoreException e) {
PDEPlugin.log(e);
setErrorMessage(PDEUIMessages.TargetPlatformPreferencePage2_23);
}
if (getMessage() == null && fActiveTarget == null) {
setMessage(PDEUIMessages.TargetPlatformPreferencePage2_22, IMessageProvider.INFORMATION);
}
}
}
/**
* Validates the selected definition and sets it as the active platform
*/
private void handleActivate() {
Object[] checked = fTableViewer.getCheckedElements();
if (checked.length > 0) {
fActiveTarget = (ITargetDefinition) checked[0];
setMessage(null);
fTableViewer.refresh(true);
fTableViewer.setSelection(new StructuredSelection(fActiveTarget));
} else {
setMessage(PDEUIMessages.TargetPlatformPreferencePage2_22, IMessageProvider.INFORMATION);
fActiveTarget = null;
fTableViewer.refresh(true);
}
}
private void handleReload() {
IStructuredSelection selection = fTableViewer.getStructuredSelection();
if (!selection.isEmpty()) {
isOutOfSynch = false;
ProgressMonitorDialog dialog = new ProgressMonitorDialog(getShell()) {
@Override
protected void configureShell(Shell shell) {
super.configureShell(shell);
shell.setText(PDEUIMessages.TargetPlatformPreferencePage2_12);
}
};
try {
dialog.run(true, true, monitor -> {
if (monitor.isCanceled()) {
throw new InterruptedException();
}
// Resolve the target
fActiveTarget.resolve(monitor);
if (monitor.isCanceled()) {
throw new InterruptedException();
}
});
} catch (InvocationTargetException e) {
PDEPlugin.log(e);
setErrorMessage(e.getMessage());
} catch (InterruptedException e) {
// Do nothing, resolve will happen when user presses ok
}
if (fActiveTarget.isResolved()) {
// Check if the bundle resolution has errors
IStatus bundleStatus = fActiveTarget.getStatus();
if (bundleStatus.getSeverity() == IStatus.ERROR) {
ErrorDialog.openError(getShell(), PDEUIMessages.TargetPlatformPreferencePage2_14, PDEUIMessages.TargetPlatformPreferencePage2_15, bundleStatus, IStatus.ERROR);
}
// Compare the target to the existing platform
try {
if (fPrevious != null && bundleStatus.getSeverity() != IStatus.ERROR && fActiveTarget.getHandle().equals(fPrevious.getHandle()) && ((TargetDefinition) fPrevious).isContentEquivalent(fActiveTarget)) {
IStatus compare = getTargetService().compareWithTargetPlatform(fActiveTarget);
if (!compare.isOK()) {
MessageDialog.openInformation(getShell(), PDEUIMessages.TargetPlatformPreferencePage2_17, PDEUIMessages.TargetPlatformPreferencePage2_18);
isOutOfSynch = true;
}
}
} catch (CoreException e) {
PDEPlugin.log(e);
setErrorMessage(e.getMessage());
}
}
fTableViewer.refresh(true);
}
}
/**
* Open the new target platform wizard
*/
private void handleAdd() {
NewTargetDefinitionWizard2 wizard = new NewTargetDefinitionWizard2();
wizard.setWindowTitle(PDEUIMessages.TargetPlatformPreferencePage2_4);
WizardDialog dialog = new WizardDialog(fAddButton.getShell(), wizard);
if (dialog.open() == Window.OK) {
ITargetDefinition def = wizard.getTargetDefinition();
fTargets.add(def);
if (fTargets.size() == 1) {
fActiveTarget = def;
}
fTableViewer.refresh(true);
fTableViewer.setSelection(new StructuredSelection(def));
if (fTargets.size() == 1) {
fTableViewer.setCheckedElements(new Object[] { fActiveTarget });
handleActivate();
}
}
}
/**
* Opens the selected target for editing
*/
private void handleEdit() {
IStructuredSelection ssel = fTableViewer.getStructuredSelection();
if (!ssel.isEmpty()) {
ITargetDefinition original = (ITargetDefinition) ssel.getFirstElement();
EditTargetDefinitionWizard wizard = new EditTargetDefinitionWizard(original, true);
wizard.setWindowTitle(PDEUIMessages.TargetPlatformPreferencePage2_6);
WizardDialog dialog = new WizardDialog(fEditButton.getShell(), wizard);
if (dialog.open() == Window.OK) {
// Replace all references to the original with the new target
ITargetDefinition newTarget = wizard.getTargetDefinition();
int index = fTargets.indexOf(original);
fTargets.add(index, newTarget);
fTargets.remove(original);
if (fMoved.containsKey(original)) {
Object moveLocation = fMoved.remove(original);
fMoved.put(newTarget, moveLocation);
}
if (original == fActiveTarget) {
fActiveTarget = newTarget;
}
fTableViewer.refresh(true);
if (fActiveTarget == newTarget) {
fTableViewer.setCheckedElements(new Object[] {newTarget});
}
fTableViewer.setSelection(new StructuredSelection(newTarget));
}
}
}
/**
* Removes the selected targets
*/
private void handleRemove() {
IStructuredSelection selection = fTableViewer.getStructuredSelection();
if (!selection.isEmpty()) {
List<ITargetDefinition> selected = selection.toList();
// If we are going to remove a workspace file, prompt to ask the user first
boolean isWorkspace = false;
for (ITargetDefinition currentTarget : selected) {
if (currentTarget.getHandle() instanceof WorkspaceFileTargetHandle) {
isWorkspace = true;
break;
}
}
if (isWorkspace) {
PDEPreferencesManager preferences = new PDEPreferencesManager(IPDEUIConstants.PLUGIN_ID);
String choice = preferences.getString(IPreferenceConstants.PROP_PROMPT_REMOVE_TARGET);
if (!MessageDialogWithToggle.ALWAYS.equalsIgnoreCase(choice)) {
MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoQuestion(getShell(), PDEUIMessages.TargetPlatformPreferencePage2_19, PDEUIMessages.TargetPlatformPreferencePage2_20, PDEUIMessages.TargetPlatformPreferencePage2_21, false, PDEPlugin.getDefault().getPreferenceStore(), IPreferenceConstants.PROP_PROMPT_REMOVE_TARGET);
preferences.savePluginPreferences();
if (dialog.getReturnCode() != IDialogConstants.YES_ID) {
return;
}
}
}
if (fActiveTarget != null && selected.contains(fActiveTarget)) {
fActiveTarget = null;
setMessage(PDEUIMessages.TargetPlatformPreferencePage2_22, IMessageProvider.INFORMATION);
}
fRemoved.addAll(selected);
fTargets.removeAll(selected);
for (ITargetDefinition element : selected) {
TargetPlatformHelper.getTargetDefinitionMap().remove(element.getHandle());
}
// Quick hack because the first refresh loses the checkedState, which is being used to bold the active target
fTableViewer.refresh(false);
fTableViewer.refresh(true);
}
}
/**
* Move the selected target to a workspace location
*/
private void handleMove() {
MoveTargetDefinitionWizard wizard = new MoveTargetDefinitionWizard(fMoved.values());
WizardDialog dialog = new WizardDialog(getShell(), wizard);
dialog.create();
SWTUtil.setDialogSize(dialog, 400, 450);
if (dialog.open() == Window.OK) {
TableItem ti = fTableViewer.getTable().getItem(fTableViewer.getTable().getSelectionIndex());
IPath newTargetLoc = wizard.getTargetFileLocation();
IFile file = PDECore.getWorkspace().getRoot().getFile(newTargetLoc);
ti.setData(DATA_KEY_MOVED_LOCATION, file.getFullPath().toString());
IStructuredSelection selection = fTableViewer.getStructuredSelection();
fMoved.put(selection.getFirstElement(), wizard.getTargetFileLocation());
fTableViewer.refresh(true);
}
}
/**
* Update enabled state of buttons
*/
protected void updateButtons() {
IStructuredSelection selection = fTableViewer.getStructuredSelection();
int size = selection.size();
fEditButton.setEnabled(size == 1);
fRemoveButton.setEnabled(size > 0);
//fDuplicateButton.setEnabled(size == 1);
if (selection.getFirstElement() != null) {
fMoveButton.setEnabled(size == 1 && ((ITargetDefinition) selection.getFirstElement()).getHandle() instanceof LocalTargetHandle);
fReloadButton.setEnabled(((ITargetDefinition) selection.getFirstElement()) == fActiveTarget && fActiveTarget.getHandle().equals(fPrevious != null ? fPrevious.getHandle() : null) && fTableViewer.getChecked(fActiveTarget));
} else {
fMoveButton.setEnabled(false);
fReloadButton.setEnabled(false);
}
}
/**
* Updates the details text box with information about the currently selected target
*/
protected void updateDetails() {
IStructuredSelection selection = fTableViewer.getStructuredSelection();
if (selection.size() == 1) {
ITargetDefinition selected = (ITargetDefinition) selection.getFirstElement();
if (!selected.isResolved() && fPrevious != null && selected.getHandle().equals(fPrevious.getHandle()) && fPrevious.isResolved()) {
// Use the resolved workspace target if the user hasn't made any changes
fDetails.setInput(fPrevious);
} else {
fDetails.setInput(selected);
}
} else {
fDetails.setInput(null);
}
}
/**
* Returns the target platform service or <code>null</code> if the service could
* not be acquired.
*
* @return target platform service or <code>null</code>
*/
private ITargetPlatformService getTargetService() {
return PDECore.getDefault().acquireService(ITargetPlatformService.class);
}
@Override
public void init(IWorkbench workbench) {
// ensures default targets are created when page is opened (if not created yet)
PluginModelManager manager = PDECore.getDefault().getModelManager();
if (!manager.isInitialized()) {
manager.getExternalModelManager();
}
}
@Override
public void performDefaults() {
// add a default target platform and select it (or just select it if present)
ITargetPlatformService service = getTargetService();
if (service != null) {
ITargetDefinition deflt = service.newDefaultTarget();
Iterator<ITargetDefinition> iterator = fTargets.iterator();
ITargetDefinition reuse = null;
while (iterator.hasNext()) {
TargetDefinition existing = (TargetDefinition) iterator.next();
if (existing.isContentEquivalent(deflt)) {
reuse = existing;
break;
}
}
if (reuse != null) {
deflt = reuse;
} else {
fTargets.add(deflt);
fTableViewer.refresh(false);
}
fActiveTarget = deflt;
fTableViewer.setCheckedElements(new Object[] {fActiveTarget});
fTableViewer.refresh(true);
handleActivate();
}
super.performDefaults();
}
@Override
public boolean performOk() {
ITargetPlatformService service = getTargetService();
if (service == null) {
return false;
}
// determine if default target has changed
ITargetDefinition toLoad = null;
boolean load = false;
ITargetHandle activeHandle = null;
if (fActiveTarget != null) {
activeHandle = fActiveTarget.getHandle();
}
if (fPrevious == null) {
if (activeHandle != null) {
toLoad = fActiveTarget;
load = true;
}
} else {
if (activeHandle == null) {
// load empty
load = true;
} else if (!fPrevious.getHandle().equals(activeHandle) || isOutOfSynch) {
toLoad = fActiveTarget;
load = true;
} else {
if (((TargetDefinition) fPrevious).isContentEquivalent(fActiveTarget)) {
load = false;
} else {
load = true;
toLoad = fActiveTarget;
}
}
}
// Move the marked definitions to workspace
for (Entry<Object, Object> entry : fMoved.entrySet()) {
try {
ITargetDefinition target = (ITargetDefinition) entry.getKey();
// IPath path = Path.fromPortableString((String) fMoved.get(target));
IFile targetFile = PDECore.getWorkspace().getRoot().getFile((IPath) entry.getValue());
WorkspaceFileTargetHandle wrkspcTargetHandle = new WorkspaceFileTargetHandle(targetFile);
ITargetDefinition newTarget = service.newTarget();
service.copyTargetDefinition(target, newTarget);
wrkspcTargetHandle.save(newTarget);
fRemoved.add(target);
fTargets.remove(target);
ITargetDefinition workspaceTarget = wrkspcTargetHandle.getTargetDefinition();
fTargets.add(workspaceTarget);
fTableViewer.refresh(false);
if (target == fActiveTarget) {
load = true;
toLoad = workspaceTarget;
}
} catch (CoreException e) {
PDEPlugin.log(e);
}
}
// Remove any definitions that have been removed
Iterator<ITargetDefinition> iterator = fRemoved.iterator();
while (iterator.hasNext()) {
ITargetDefinition target = iterator.next();
try {
service.deleteTarget(target.getHandle());
} catch (CoreException e) {
ErrorDialog.openError(getShell(), PDEUIMessages.TargetPlatformPreferencePage2_8, PDEUIMessages.TargetPlatformPreferencePage2_11, e.getStatus());
return false;
}
}
// save others that are dirty
iterator = fTargets.iterator();
while (iterator.hasNext()) {
ITargetDefinition def = iterator.next();
boolean save = true;
if (def.getHandle().exists()) {
try {
ITargetDefinition original = def.getHandle().getTargetDefinition();
if (((TargetDefinition) original).isContentEqual(def)) {
save = false;
}
} catch (CoreException e) {
// failed to generate original
setErrorMessage(e.getMessage());
return false;
}
}
if (save) {
try {
service.saveTargetDefinition(def);
} catch (CoreException e) {
setErrorMessage(e.getMessage());
return false;
}
}
}
// set workspace target if required
if (load) {
// Warn about forward compatibility, synchronize java search
IJobChangeListener listener = new JobChangeAdapter() {
@Override
public void done(IJobChangeEvent event) {
Display.getDefault().syncExec(() -> {
// once resolve finishes, update the target tree
// viewer as well as location
if (!fTableViewer.getControl().isDisposed())
fTableViewer.refresh(true);
if (!fDetails.getControl().isDisposed())
fDetails.refresh(true);
});
if (event.getResult().isOK()) {
if (fActiveTarget != null) {
PDEPreferencesManager pref = new PDEPreferencesManager(PDEPlugin.getPluginId());
if (pref.getBoolean(IPreferenceConstants.ADD_TO_JAVA_SEARCH)) {
AddToJavaSearchJob.synchWithTarget(fActiveTarget);
}
// Ignore the qualifier when comparing (otherwise N builds always newer than I builds)
Version platformOsgiVersion = Platform.getBundle(ORG_ECLIPSE_OSGI).getVersion();
platformOsgiVersion = new Version(platformOsgiVersion.getMajor(), platformOsgiVersion.getMinor(), platformOsgiVersion.getMicro());
TargetBundle[] bundles;
bundles = fActiveTarget.getAllBundles();
if (bundles != null) {
for (TargetBundle bundle : bundles) {
BundleInfo bundleInfo = bundle.getBundleInfo();
if (ORG_ECLIPSE_OSGI.equalsIgnoreCase(bundleInfo.getSymbolicName())) {
// Ignore the qualifier when comparing (otherwise N builds always newer than I builds)
Version bundleVersion = Version.parseVersion(bundleInfo.getVersion());
bundleVersion = new Version(bundleVersion.getMajor(), bundleVersion.getMinor(), bundleVersion.getMicro());
if (platformOsgiVersion.compareTo(bundleVersion) < 0) {
Display.getDefault().syncExec(() -> MessageDialog.openWarning(PDEPlugin.getActiveWorkbenchShell(), PDEUIMessages.TargetPlatformPreferencePage2_28, PDEUIMessages.TargetPlatformPreferencePage2_10));
}
break;
}
}
}
}
}
}
};
LoadTargetDefinitionJob.load(toLoad, listener);
fPrevious = toLoad == null ? null : toLoad;
// Start a separate job to clean p2 bundle pool
runGC();
} else {
// Manually update the active target and status line to update name, resolve status, and errors
if (fActiveTarget != null) {
((TargetPlatformService) service).setWorkspaceTargetDefinition(fActiveTarget, false);
TargetStatus.refreshTargetStatusContent();
}
}
fMoved.clear();
fRemoved.clear();
if (toLoad != null) {
fActiveTarget = toLoad;
}
fTableViewer.refresh(true);
updateButtons();
return super.performOk();
}
private void runGC() {
Job job = new Job(PDEUIMessages.TargetPlatformPreferencePage2_26) {
@Override
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask(PDEUIMessages.TargetPlatformPreferencePage2_27, IProgressMonitor.UNKNOWN);
P2TargetUtils.garbageCollect();
monitor.done();
return Status.OK_STATUS;
}
};
job.schedule();
}
}