workspaceDescription = new WritableValue<>();
@Override
public void createPartControl(final Composite parent) {
@@ -224,27 +211,6 @@ public void createPartControl(final Composite parent) {
fill.marginHeight = 5;
fill.marginWidth = 5;
defaultParent.setLayout(fill);
-
- if (!Central.hasWorkspaceDirectory()) {
- FormText form = toolkit.createFormText(defaultParent, true);
- form.setText("",
- true, false);
- form.addHyperlinkListener(new HyperlinkAdapter() {
- @Override
- public void linkActivated(HyperlinkEvent e) {
- IWorkbench workbench = PlatformUI.getWorkbench();
- IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
-
- WorkspaceSetupWizard wizard = new WorkspaceSetupWizard();
- wizard.init(workbench, StructuredSelection.EMPTY);
- WizardDialog dialog = new WizardDialog(window.getShell(), wizard);
- dialog.open();
- }
- });
- } else {
- toolkit.createLabel(defaultParent, "Repositories are loading, please wait...");
- }
-
stackLayout.topControl = defaultParent;
parent.layout();
@@ -272,9 +238,7 @@ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
advancedSearchAction.setEnabled(true);
refreshAction.setEnabled(true);
collapseAllAction.setEnabled(true);
-
- configureOfflineAction();
-
+ setPrefrences(getPreferences());
parent.layout();
}
}
@@ -284,7 +248,7 @@ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
viewer.setLabelProvider(new RepositoryTreeLabelProvider(false));
getViewSite().setSelectionProvider(viewer);
- Central.addRepositoriesViewer(viewer, RepositoriesView.this);
+ RepositoriesViewRefresher.addViewer(viewer, RepositoriesView.this);
// LISTENERS
filterPart.addPropertyChangeListener(event -> {
@@ -364,7 +328,7 @@ public boolean performDrop(Object data) {
File tmp = File.createTempFile("dwnl", ".jar");
try (HttpClient client = new HttpClient()) {
- IO.copy(client.connect(url), tmp);
+ Files.copy(client.connect(url), tmp.toPath());
}
if (isJarFile(tmp)) {
@@ -478,52 +442,96 @@ protected IStatus run(IProgressMonitor monitor) {
createActions();
fillToolBar(getViewSite().getActionBars()
.getToolBarManager());
+ IActionBars actionBars = getViewSite().getActionBars();
+ actionBars.setGlobalActionHandler(ActionFactory.REFRESH.getId(), refreshAction);
+
+ // Event subscription
+ eventBroker.subscribe(ViewEventTopics.REPOSITORIESVIEW_OPEN_ADVANCED_SEARCH.topic(),
+ event -> handleOpenAdvancedSearch(event));
+ ISelectionService selectionService = getSite().getWorkbenchWindow().getSelectionService();
- prefs.addPropertyChangeListener(workspaceOfflineListener);
+ selectionService.addSelectionListener(new ISelectionListener() {
- // synthenic call to "refresh" so that we can get the repositories to
- // show up in the UI
- new WorkspaceJob("Load repositories") {
@Override
- public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
- try {
- Central.refreshPlugins();
- } catch (Exception e) {
- // ignore errors there may be no workspace yet
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ if (getSite().getPart() == part) {
+ return;
}
- return Status.OK_STATUS;
+ updateSelection(selection);
}
- }.schedule();
+ });
+ updateSelection(selectionService.getSelection());
+ }
- IActionBars actionBars = getViewSite().getActionBars();
- actionBars.setGlobalActionHandler(ActionFactory.REFRESH.getId(), refreshAction);
+ private void updateSelection(ISelection selection) {
+ IProject project = getProject(selection);
+ Workspace ws = Workspaces.getWorkspace(project).or(() -> Workspaces.getGlobalWorkspace()).orElse(null);
+ if (this.workspace != ws) {
+ this.workspace = ws;
+ RepositoriesViewRefresher.refreshViewer(viewer, this);
+ workspaceName.setValue(Workspaces.getName(ws));
+ workspaceDescription.setValue(Workspaces.getDescription(ws));
+ }
+ BndPreferences pref = Adapters.adapt(project, BndPreferences.class);
+ setPrefrences(pref);
+ }
- // Event subscription
- eventBroker.subscribe(ViewEventTopics.REPOSITORIESVIEW_OPEN_ADVANCED_SEARCH.topic(),
- event -> handleOpenAdvancedSearch(event));
+ protected IProject getProject(ISelection selection) {
+ if (selection instanceof IStructuredSelection structured) {
+ Object firstElement = structured.getFirstElement();
+ IProject project = Adapters.adapt(firstElement, IProject.class);
+ if (project != null) {
+ return project;
+ }
+ IResource resource = Adapters.adapt(firstElement, IResource.class);
+ if (resource != null) {
+ return resource.getProject();
+ }
+ return null;
+ }
+ if (selection instanceof ITextSelection) {
+ IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+ if (editor != null) {
+ IEditorInput editorInput = editor.getEditorInput();
+ if (editorInput instanceof IFileEditorInput fileInput) {
+ return fileInput.getFile().getProject();
+ }
+ }
+ }
+ return null;
}
- private void configureOfflineAction() {
- Workspace workspace = Central.getWorkspaceIfPresent();
- if (workspace == null) {
+ private void setPrefrences(BndPreferences preferences) {
+ if (Objects.equals(this.preferences, preferences)) {
+ return;
+ }
+ if (this.preferences!=null) {
+ this.preferences.removePropertyChangeListener(workspaceOfflineListener);
+ }
+ this.preferences = preferences;
+ if (preferences == null) {
offlineAction.setChecked(false);
offlineAction.setToolTipText("Go Offline");
- offlineAction.setImageDescriptor(Icons.desc("connected"));
- offlineAction.setDisabledImageDescriptor(Icons.desc("connected.disabled"));
+ offlineAction.setImageDescriptor(Resources.getImageDescriptor("connect.png"));
+ offlineAction.setDisabledImageDescriptor(Resources.getImageDescriptor("connect_d.png"));
offlineAction.setEnabled(false);
return;
}
+ preferences.addPropertyChangeListener(workspaceOfflineListener);
+ updateOfflineAction(preferences.isWorkspaceOffline());
+ }
- if (prefs.isWorkspaceOffline()) {
+ protected void updateOfflineAction(boolean offline) {
+ if (offline) {
offlineAction.setChecked(true);
offlineAction.setToolTipText("Go Online");
- offlineAction.setImageDescriptor(Icons.desc("disconnected"));
- offlineAction.setDisabledImageDescriptor(Icons.desc("disconnected.disabled"));
+ offlineAction.setImageDescriptor(Resources.getImageDescriptor("disconnect.png"));
+ offlineAction.setDisabledImageDescriptor(Resources.getImageDescriptor("disconnect_d.png"));
} else {
offlineAction.setChecked(false);
offlineAction.setToolTipText("Go Offline");
- offlineAction.setImageDescriptor(Icons.desc("connected"));
- offlineAction.setDisabledImageDescriptor(Icons.desc("connected.disabled"));
+ offlineAction.setImageDescriptor(Resources.getImageDescriptor("connect.png"));
+ offlineAction.setDisabledImageDescriptor(Resources.getImageDescriptor("connect_d.png"));
}
offlineAction.setEnabled(true);
}
@@ -535,7 +543,7 @@ protected void openURI(URI uri) {
.getStore(uri);
IDE.openEditorOnFileStore(page, fileStore);
} catch (PartInitException e) {
- logger.logError("Error opening editor for " + uri, e);
+ ILog.get().error("Error opening editor for " + uri, e);
}
}
@@ -580,13 +588,16 @@ public void dispose() {
.getActiveWorkbenchWindow()
.getPartService()
.removePartListener(dndgaviPageListener);
- Central.removeRepositoriesViewer(viewer);
- prefs.removePropertyChangeListener(workspaceOfflineListener);
+ RepositoriesViewRefresher.removeViewer(viewer);
+ BndPreferences preferences = getPreferences();
+ if (preferences != null) {
+ preferences.removePropertyChangeListener(workspaceOfflineListener);
+ }
super.dispose();
}
boolean addFilesToRepository(RepositoryPlugin repo, File[] files) {
- AddFilesToRepositoryWizard wizard = new AddFilesToRepositoryWizard(repo, files);
+ AddFilesToRepositoryWizard wizard = new AddFilesToRepositoryWizard(getWorkspace(), repo, files);
WizardDialog dialog = new WizardDialog(getViewSite().getShell(), wizard);
dialog.open();
viewer.refresh(repo);
@@ -610,8 +621,8 @@ public void run() {
collapseAllAction.setEnabled(false);
collapseAllAction.setText("Collapse All");
collapseAllAction.setToolTipText("Collapse All");
- collapseAllAction.setImageDescriptor(Icons.desc("collapse"));
- collapseAllAction.setDisabledImageDescriptor(Icons.desc("collapse.disabled"));
+ collapseAllAction.setImageDescriptor(Resources.getImageDescriptor("collapseall.png"));
+ collapseAllAction.setDisabledImageDescriptor(Resources.getImageDescriptor("collapseall_d.png"));
refreshAction = new Action() {
@Override
@@ -627,13 +638,13 @@ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
try {
refreshAction.setEnabled(false);
- Central.refreshPlugins();
+ Central.refreshPlugins(getWorkspace());
} catch (Exception e) {
Throwable t = Exceptions.unrollCause(e, InvocationTargetException.class);
- logger.logError("Unexpected error in refreshing plugns", t);
+ ILog.get().error("Unexpected error in refreshing plugns", t);
- return new Status(IStatus.ERROR, Plugin.PLUGIN_ID, "Failed to refresh plugins", t);
+ return Status.error("Failed to refresh plugins", t);
} finally {
refreshAction.setEnabled(true);
}
@@ -645,8 +656,8 @@ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
refreshAction.setEnabled(false);
refreshAction.setText("Refresh");
refreshAction.setToolTipText("Refresh Repositories Tree");
- refreshAction.setImageDescriptor(Icons.desc("refresh"));
- refreshAction.setDisabledImageDescriptor(Icons.desc("refresh.disabled"));
+ refreshAction.setImageDescriptor(Resources.getImageDescriptor("arrow_refresh.png"));
+ refreshAction.setDisabledImageDescriptor(Resources.getImageDescriptor("arrow_refresh_d.png"));
addBundlesAction = new Action() {
@Override
@@ -656,7 +667,8 @@ public void run() {
if (element != null && element instanceof RepositoryPlugin) {
RepositoryPlugin repo = (RepositoryPlugin) element;
if (repo.canWrite()) {
- AddFilesToRepositoryWizard wizard = new AddFilesToRepositoryWizard(repo, new File[0]);
+ AddFilesToRepositoryWizard wizard = new AddFilesToRepositoryWizard(getWorkspace(), repo,
+ new File[0]);
WizardDialog dialog = new WizardDialog(getViewSite().getShell(), wizard);
dialog.open();
@@ -668,8 +680,8 @@ public void run() {
addBundlesAction.setEnabled(false);
addBundlesAction.setText("Add");
addBundlesAction.setToolTipText("Add Bundles to Repository");
- addBundlesAction.setImageDescriptor(Icons.desc("add"));
- addBundlesAction.setDisabledImageDescriptor(Icons.desc("add.disabled"));
+ addBundlesAction.setImageDescriptor(Resources.getImageDescriptor("add_obj.png"));
+ addBundlesAction.setDisabledImageDescriptor(Resources.getImageDescriptor("add_obj_d.png"));
advancedSearchAction = new Action("Advanced Search", IAction.AS_CHECK_BOX) {
@Override
@@ -681,7 +693,7 @@ public void run() {
XMLMemento memento = XMLMemento.createReadRoot(new StringReader(advancedSearchState));
dialog.restoreState(memento);
} catch (Exception e) {
- logger.logError("Failed to load dialog state", e);
+ ILog.get().error("Failed to load dialog state", e);
}
}
@@ -703,7 +715,7 @@ public void run() {
memento.save(writer);
advancedSearchState = writer.toString();
} catch (Exception e) {
- logger.logError("Failed to save dialog state", e);
+ ILog.get().error("Failed to save dialog state", e);
}
} else {
contentProvider.setRequirementFilter(null);
@@ -715,8 +727,8 @@ public void run() {
advancedSearchAction.setEnabled(false);
advancedSearchAction.setText("Advanced Search");
advancedSearchAction.setToolTipText("Toggle Advanced Search");
- advancedSearchAction.setImageDescriptor(Icons.desc("search"));
- advancedSearchAction.setDisabledImageDescriptor(Icons.desc("search.disabled"));
+ advancedSearchAction.setImageDescriptor(Resources.getImageDescriptor("search.png"));
+ advancedSearchAction.setDisabledImageDescriptor(Resources.getImageDescriptor("search_d.png"));
downloadAction = new Action() {
@Override
@@ -766,22 +778,22 @@ private List selectionByType(IStructuredSelection selection, Class typ
};
downloadAction.setEnabled(false);
downloadAction.setText("Download Repository Content");
- downloadAction.setImageDescriptor(Icons.desc("download"));
- downloadAction.setDisabledImageDescriptor(Icons.desc("download.disabled"));
+ downloadAction.setImageDescriptor(Resources.getImageDescriptor("download.png"));
+ downloadAction.setDisabledImageDescriptor(Resources.getImageDescriptor("download_d.png"));
offlineAction = new Action("Online/Offline Mode", IAction.AS_CHECK_BOX) {
@Override
public void run() {
- Workspace workspace = Central.getWorkspaceIfPresent();
- if (workspace != null) {
- prefs.setWorkspaceOffline(offlineAction.isChecked());
+ BndPreferences preferences = getPreferences();
+ if (preferences != null) {
+ preferences.setWorkspaceOffline(offlineAction.isChecked());
}
}
};
offlineAction.setEnabled(false);
offlineAction.setToolTipText("Go Offline");
- offlineAction.setImageDescriptor(Icons.desc("connected"));
- offlineAction.setDisabledImageDescriptor(Icons.desc("connected.disabled"));
+ offlineAction.setImageDescriptor(Resources.getImageDescriptor("connect.png"));
+ offlineAction.setDisabledImageDescriptor(Resources.getImageDescriptor("connect_d.png"));
viewer.addSelectionChangedListener(event -> {
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
@@ -865,6 +877,50 @@ void createContextMenu() {
}
private void fillToolBar(IToolBarManager toolBar) {
+ toolBar.add(new ControlContribution("label") {
+
+ @Override
+ protected Control createControl(Composite parent) {
+ final Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new FillLayout());
+ // TODO maybe make this a combo so the user can choose other namespaces eg:
+ // - active selection
+ // - any of the ones registered at OSGi
+ CLabel label = new CLabel(composite, SWT.CENTER);
+
+ IChangeListener labelListener = e -> {
+ String text = label.getText();
+ String newText = getLabelText();
+ if (Objects.equals(text, newText)) {
+ return;
+ }
+ label.setText(newText);
+ label.setToolTipText(workspaceDescription.getValue());
+ toolBar.update(true);
+ };
+ IChangeListener tooltipListener = e -> {
+ String text = label.getToolTipText();
+ String newText = workspaceDescription.getValue();
+ if (Objects.equals(text, newText)) {
+ return;
+ }
+ label.setToolTipText(newText);
+ };
+ label.addDisposeListener(e -> {
+ workspaceDescription.removeChangeListener(tooltipListener);
+ workspaceName.removeChangeListener(labelListener);
+ });
+ workspaceName.addChangeListener(labelListener);
+ workspaceDescription.addChangeListener(tooltipListener);
+ label.setText(getLabelText());
+ label.setToolTipText(workspaceDescription.getValue());
+ return composite;
+ }
+
+ private String getLabelText() {
+ return Objects.requireNonNullElse(workspaceName.getValue(), "");
+ }
+ });
toolBar.add(advancedSearchAction);
toolBar.add(downloadAction);
toolBar.add(new Separator());
@@ -929,7 +985,7 @@ boolean performDrop(Object target, TransferData data, Object dropped) {
RepositoryPlugin repositoryPlugin = getRepositoryPlugin(target);
if (repositoryPlugin != null && repositoryPlugin instanceof Refreshable)
- Central.refreshPlugin((Refreshable) repositoryPlugin);
+ Central.refreshPlugin(getWorkspace(), (Refreshable) repositoryPlugin);
return true;
} catch (Exception e) {
e.printStackTrace();
@@ -942,8 +998,8 @@ private Object toJava(Object dropped) {
IStructuredSelection selection = (IStructuredSelection) dropped;
if (!selection.isEmpty()) {
Object firstElement = selection.getFirstElement();
- if (firstElement instanceof Resource) {
- Resource resource = (Resource) firstElement;
+ if (firstElement instanceof IResource) {
+ IResource resource = (IResource) firstElement;
IPath path = resource.getRawLocation();
if (path != null) {
File file = path.toFile();
@@ -1032,13 +1088,18 @@ Object toJava(TransferData data) throws Exception {
}
}
if (URLTransfer.getInstance()
- .isSupportedType(data))
- return Converter.cnv(URI.class, URLTransfer.getInstance()
- .nativeToJava(data));
- else if (FileTransfer.getInstance()
.isSupportedType(data)) {
- return Converter.cnv(File[].class, FileTransfer.getInstance()
- .nativeToJava(data));
+ Object nativeUrl = URLTransfer.getInstance().nativeToJava(data);
+ if (nativeUrl instanceof String s) {
+ return new URI(s);
+ }
+ } else if (FileTransfer.getInstance()
+ .isSupportedType(data)) {
+ Object nativeFiles = FileTransfer.getInstance()
+ .nativeToJava(data);
+ if (nativeFiles instanceof String[] str) {
+ return Arrays.stream(str).map(File::new).toArray(File[]::new);
+ }
} else if (TextTransfer.getInstance()
.isSupportedType(data)) {
return TextTransfer.getInstance()
@@ -1066,7 +1127,7 @@ else if (element instanceof RepositoryBundleVersion)
@Override
public List getRepositories() {
- return RepositoryUtils.listRepositories(true);
+ return RepositoryUtils.listRepositories(getWorkspace(), true);
}
private static boolean isJarFile(File candidate) {
@@ -1090,13 +1151,9 @@ protected IStatus run(IProgressMonitor monitor) {
try {
r.run();
if (rp != null && rp instanceof Refreshable)
- Central.refreshPlugin((Refreshable) rp, true);
+ Central.refreshPlugin(getWorkspace(), (Refreshable) rp, true);
} catch (final Exception e) {
- IStatus status = new Status(IStatus.ERROR, Plugin.PLUGIN_ID,
- "Error executing: " + getName(), e);
- Plugin.getDefault()
- .getLog()
- .log(status);
+ ILog.get().error("Error executing: " + getName(), e);
}
monitor.done();
return Status.OK_STATUS;
@@ -1130,7 +1187,7 @@ public void done(IJobChangeEvent event) {
private void addCopyToClipboardSubMenueEntries(Actionable act, final RepositoryPlugin rp, HierarchicalMenu hmenu) {
- final Registry registry = Central.getWorkspaceIfPresent();
+ final Registry registry = getWorkspace();
if (registry == null) {
return;
}
@@ -1273,4 +1330,13 @@ private void handleOpenAdvancedSearch(Event event) {
}
}
+ @Override
+ public Workspace getWorkspace() {
+ return this.workspace;
+ }
+
+ private BndPreferences getPreferences() {
+ return this.preferences;
+ }
+
}
diff --git a/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/views/repository/SearchPanel.java b/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/views/repository/SearchPanel.java
index 07584e768d..1ade7b2120 100644
--- a/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/views/repository/SearchPanel.java
+++ b/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/views/repository/SearchPanel.java
@@ -12,7 +12,7 @@
* Neil Bartlett - initial API and implementation
* BJ Hargrave - ongoing enhancements
*******************************************************************************/
-package bndtools.views.repository;
+package org.eclipse.pde.bnd.ui.views.repository;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
@@ -75,7 +75,7 @@ protected void setRequirement(Requirement requirement) {
propSupport.firePropertyChange(PROP_VALUE, oldRequiremenmt, requirement);
}
- public Image createImage(@SuppressWarnings("unused") Device device) {
+ public Image createImage(Device device) {
return null;
}
diff --git a/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/views/repository/ServiceSearchPanel.java b/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/views/repository/ServiceSearchPanel.java
index 41ec20be3c..98e309d32e 100644
--- a/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/views/repository/ServiceSearchPanel.java
+++ b/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/views/repository/ServiceSearchPanel.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015, 2021 bndtools project and others.
+ * Copyright (c) 2015, 2024 bndtools project and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -12,10 +12,11 @@
* Neil Bartlett - initial API and implementation
* BJ Hargrave - ongoing enhancements
* Peter Kriens - ongoing enhancements
+ * Christoph Läubrich - adapt to pde code base
*******************************************************************************/
-package bndtools.views.repository;
+package org.eclipse.pde.bnd.ui.views.repository;
-import org.bndtools.core.ui.icons.Icons;
+import org.eclipse.pde.bnd.ui.Resources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
@@ -82,7 +83,7 @@ public void setFocus() {
@Override
public Image createImage(Device device) {
- return Icons.image("service");
+ return Resources.getImage("service");
}
@Override
diff --git a/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/AddFilesToRepositoryWizard.java b/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/AddFilesToRepositoryWizard.java
index 141894f1e2..83b4d9f939 100644
--- a/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/AddFilesToRepositoryWizard.java
+++ b/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/AddFilesToRepositoryWizard.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2021 bndtools project and others.
+ * Copyright (c) 2010, 2024 bndtools project and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -14,18 +14,22 @@
* PK Søreide - ongoing enhancements
* Gregory Amerson - ongoing enhancements
* BJ Hargrave - ongoing enhancements
+ * Christoph Läubrich - Adapt to PDE codebase
*******************************************************************************/
-package bndtools.wizards.workspace;
+package org.eclipse.pde.bnd.ui.wizards;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
+import java.nio.file.Files;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
@@ -35,30 +39,30 @@
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.pde.bnd.ui.Central;
+import org.eclipse.pde.bnd.ui.RefreshFileJob;
+import aQute.bnd.build.Workspace;
import aQute.bnd.osgi.Jar;
import aQute.bnd.service.Refreshable;
import aQute.bnd.service.RepositoryPlugin;
-import aQute.lib.io.IO;
-import bndtools.Plugin;
-import bndtools.central.Central;
-import bndtools.central.RefreshFileJob;
-import bndtools.types.Pair;
public class AddFilesToRepositoryWizard extends Wizard {
private RepositoryPlugin repository;
private final File[] files;
- private List> selectedBundles;
+ private List> selectedBundles;
private final LocalRepositorySelectionPage repoSelectionPage;
private final AddFilesToRepositoryWizardPage fileSelectionPage;
+ private Workspace workspace;
- public AddFilesToRepositoryWizard(RepositoryPlugin repository, File[] initialFiles) {
+ public AddFilesToRepositoryWizard(Workspace workspace, RepositoryPlugin repository, File[] initialFiles) {
+ this.workspace = workspace;
this.repository = repository;
this.files = initialFiles;
- repoSelectionPage = new LocalRepositorySelectionPage("repoSelectionPage", repository);
+ repoSelectionPage = new LocalRepositorySelectionPage(workspace, "repoSelectionPage", repository);
fileSelectionPage = new AddFilesToRepositoryWizardPage("fileSelectionPage");
fileSelectionPage.setFiles(files);
@@ -79,7 +83,8 @@ public boolean performFinish() {
WorkspaceJob job = new WorkspaceJob("Adding files to repository") {
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
- MultiStatus status = new MultiStatus(Plugin.PLUGIN_ID, 0, "Failed to install one or more bundles",
+ MultiStatus status = new MultiStatus(AddFilesToRepositoryWizard.class, 0,
+ "Failed to install one or more bundles",
null);
List files = fileSelectionPage.getFiles();
List refresh = new ArrayList<>();
@@ -89,15 +94,14 @@ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
try (Jar jar = new Jar(file)) {
String bsn = jar.getBsn();
String version = jar.getVersion();
- selectedBundles.add(Pair.newInstance(bsn, (version != null) ? version : "0"));
+ selectedBundles.add(Map.entry(bsn, (version != null) ? version : "0"));
} catch (Exception e) {
- status.add(new Status(IStatus.ERROR, Plugin.PLUGIN_ID, 0,
- MessageFormat.format("Failed to analyse JAR: {0}", file.getPath()), e));
+ status.add(Status.error(MessageFormat.format("Failed to analyze JAR: {0}", file.getPath()), e));
progress.worked(1);
continue;
}
- try (InputStream in = new BufferedInputStream(IO.stream(file))) {
+ try (InputStream in = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
RepositoryPlugin.PutResult result = repository.put(in, new RepositoryPlugin.PutOptions());
URI artifact = result.artifact;
if ((artifact != null) && artifact.getScheme()
@@ -105,11 +109,11 @@ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
refresh.add(new File(artifact));
}
if (repository instanceof Refreshable) {
- Central.refreshPlugin((Refreshable) repository, true);
+ Central.refreshPlugin(workspace, (Refreshable) repository, true);
}
} catch (Exception e) {
- status.add(new Status(IStatus.ERROR, Plugin.PLUGIN_ID, 0,
- MessageFormat.format("Failed to add JAR to repository: {0}", file.getPath()), e));
+ status.add(Status.error(
+ MessageFormat.format("Failed to add JAR to repository: {0}", file.getPath()), e));
progress.worked(1);
continue;
}
@@ -126,7 +130,7 @@ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
return true;
}
- public List> getSelectedBundles() {
+ public List> getSelectedBundles() {
return Collections.unmodifiableList(selectedBundles);
}
}
diff --git a/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/AddFilesToRepositoryWizardPage.java b/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/AddFilesToRepositoryWizardPage.java
index 03aefe1c6e..42f968c586 100644
--- a/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/AddFilesToRepositoryWizardPage.java
+++ b/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/AddFilesToRepositoryWizardPage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2021 bndtools project and others.
+ * Copyright (c) 2010, 2024 bndtools project and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -13,8 +13,9 @@
* Ferry Huberts - ongoing enhancements
* BJ Hargrave - ongoing enhancements
* Peter Kriens - ongoing enhancements
+ * Christoph Läubrich - Adapt to PDE codebase
*******************************************************************************/
-package bndtools.wizards.workspace;
+package org.eclipse.pde.bnd.ui.wizards;
import java.io.File;
import java.util.ArrayList;
@@ -22,15 +23,14 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.jar.Attributes;
import org.bndtools.api.ILogger;
import org.bndtools.api.Logger;
-import org.bndtools.core.ui.icons.Icons;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ArrayContentProvider;
@@ -41,6 +41,8 @@
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.pde.bnd.ui.FileExtensionFilter;
+import org.eclipse.pde.bnd.ui.Resources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
@@ -59,20 +61,17 @@
import org.osgi.framework.Constants;
import aQute.bnd.osgi.Jar;
-import bndtools.Plugin;
-import bndtools.types.Pair;
-import bndtools.utils.FileExtensionFilter;
public class AddFilesToRepositoryWizardPage extends WizardPage {
private static final ILogger logger = Logger
.getLogger(AddFilesToRepositoryWizardPage.class);
- private final static Image jarImg = Icons.image("jar");
- private final static Image warnImg = Icons.image("/icons/warning_obj.gif");
- private final static Image errorImg = Icons.image("/icons/error.gif");
- private final static Image okayImg = Icons.image("/icons/tick.png");
+ private final static Image jarImg = Resources.getImage("jar.gif");
+ private final static Image warnImg = Resources.getImage("warning_obj.gif");
+ private final static Image errorImg = Resources.getImage("error.gif");
+ private final static Image okayImg = Resources.getImage("tick.png");
- private final Map> bsnMap = new HashMap<>();
+ private final Map> bsnMap = new HashMap<>();
private final List files = new ArrayList<>(1);
private TableViewer viewer;
@@ -106,14 +105,13 @@ void analyseFile(File file) {
String bsn = attribs.getValue(Constants.BUNDLE_SYMBOLICNAME);
String version = attribs.getValue(Constants.BUNDLE_VERSION);
- bsnMap.put(file, Pair.newInstance(bsn, version));
+ bsnMap.put(file, Map.entry(bsn, version));
} catch (Exception e) {
logger.logError("Error reading JAR file content", e);
}
}
@Override
- @SuppressWarnings("unused")
public void createControl(Composite parent) {
setTitle("Add Files to Repository");
@@ -139,7 +137,7 @@ public void createControl(Composite parent) {
@Override
public void update(ViewerCell cell) {
File file = (File) cell.getElement();
- Pair bundleId = bsnMap.get(file);
+ Entry bundleId = bsnMap.get(file);
int index = cell.getColumnIndex();
if (index == 0) {
@@ -160,8 +158,8 @@ public void update(ViewerCell cell) {
cell.setImage(errorImg);
cell.setText("Not a JAR file");
} else {
- String bsn = bundleId.getFirst();
- String version = bundleId.getSecond();
+ String bsn = bundleId.getKey();
+ String version = bundleId.getValue();
if (bsn == null) {
cell.setImage(warnImg);
cell.setText("Not a Bundle JAR");
@@ -227,9 +225,9 @@ void doAdd() {
new WorkbenchContentProvider());
dialog.setValidator(selection -> {
if (selection.length > 0 && selection[0] instanceof IFile) {
- return new Status(IStatus.OK, Plugin.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$
+ return Status.OK_STATUS;
}
- return new Status(IStatus.ERROR, Plugin.PLUGIN_ID, IStatus.ERROR, "", null); //$NON-NLS-1$
+ return Status.error(""); //$NON-NLS-1$
});
dialog.setAllowMultiple(true);
dialog.setTitle("JAR File Selection");
@@ -298,11 +296,11 @@ void validate() {
String warning = null;
for (File file : files) {
- Pair pair = bsnMap.get(file);
+ Entry pair = bsnMap.get(file);
if (pair == null) {
error = "One or more selected files is not a JAR.";
} else {
- String bsn = pair.getFirst();
+ String bsn = pair.getKey();
if (bsn == null) {
warning = "One or more selected files is not a Bundle JAR";
}
diff --git a/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/LocalRepositorySelectionPage.java b/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/LocalRepositorySelectionPage.java
index 8ee91001cf..f6acb07e51 100644
--- a/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/LocalRepositorySelectionPage.java
+++ b/ui/org.eclipse.pde.bnd.ui/src/org/eclipse/pde/bnd/ui/wizards/LocalRepositorySelectionPage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2020 bndtools project and others.
+ * Copyright (c) 2010, 2024 bndtools project and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -12,8 +12,9 @@
* Neil Bartlett - initial API and implementation
* Ferry Huberts - ongoing enhancements
* BJ Hargrave - ongoing enhancements
+ * Christoph Läubrich - Adapt to PDE codebase
*******************************************************************************/
-package bndtools.wizards.workspace;
+package org.eclipse.pde.bnd.ui.wizards;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
@@ -28,15 +29,14 @@
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.pde.bnd.ui.model.repo.RepositoryTreeContentProvider;
+import org.eclipse.pde.bnd.ui.model.repo.RepositoryTreeLabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import aQute.bnd.build.Workspace;
import aQute.bnd.service.RepositoryPlugin;
-import bndtools.central.Central;
-import bndtools.model.repo.RepositoryTreeContentProvider;
-import bndtools.model.repo.RepositoryTreeLabelProvider;
class LocalRepositorySelectionPage extends WizardPage {
private static final ILogger logger = Logger.getLogger(LocalRepositorySelectionPage.class);
@@ -46,12 +46,15 @@ class LocalRepositorySelectionPage extends WizardPage {
private final PropertyChangeSupport propSupport = new PropertyChangeSupport(this);
private RepositoryPlugin selectedRepository = null;
- LocalRepositorySelectionPage(String pageName) {
- this(pageName, null);
+ private Workspace workspace;
+
+ LocalRepositorySelectionPage(Workspace workspace, String pageName) {
+ this(workspace, pageName, null);
}
- LocalRepositorySelectionPage(String pageName, RepositoryPlugin selectedRepository) {
+ LocalRepositorySelectionPage(Workspace workspace, String pageName, RepositoryPlugin selectedRepository) {
super(pageName);
+ this.workspace = workspace;
this.selectedRepository = selectedRepository;
}
@@ -73,7 +76,6 @@ public boolean select(Viewer viewer, Object parentElement, Object element) {
});
try {
- Workspace workspace = Central.getWorkspace();
viewer.setInput(workspace);
if (selectedRepository != null)
viewer.setSelection(new StructuredSelection(selectedRepository));
diff --git a/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
index 8b137beabd..34b4361af1 100644
--- a/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
@@ -87,8 +87,11 @@ Import-Package: aQute.bnd.build;version="[4.4.0,5.0.0)",
aQute.bnd.osgi.resource;version="[4.3.0,6.0.0)",
aQute.bnd.properties;version="[2.0.0,3.0.0)",
aQute.bnd.service;version="[4.7.0,5.0.0)",
+ aQute.bnd.service.clipboard;version="[1.0.0,2.0.0]",
+ aQute.bnd.service.progress;version="[1.3.0,2.0.0]",
aQute.bnd.version;version="[2.2.0,3.0.0)",
aQute.service.reporter;version="[1.2.0,2.0.0)",
+ org.bndtools.versioncontrol.ignores.manager.api;version="[1.0.0,2.0.0]",
org.eclipse.equinox.internal.p2.publisher.eclipse,
org.eclipse.equinox.p2.publisher,
org.eclipse.equinox.p2.publisher.eclipse,
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECore.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECore.java
index 5b02694e50..9fe9dc2dc2 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECore.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECore.java
@@ -57,6 +57,8 @@
import org.osgi.util.tracker.ServiceTracker;
import aQute.bnd.build.Workspace;
+import aQute.bnd.service.RepositoryListenerPlugin;
+import aQute.bnd.service.clipboard.Clipboard;
public class PDECore extends Plugin implements DebugOptionsListener {
public static final String PLUGIN_ID = "org.eclipse.pde.core"; //$NON-NLS-1$
@@ -201,6 +203,10 @@ public static void logException(Throwable e, String message) {
private ServiceTracker classpathContributorServiceTracker;
+ private ServiceTracker clipBoardsServiceTracker;
+
+ private ServiceTracker repositoryListenerServiceTracker;
+
public PDECore() {
inst = this;
}
@@ -463,4 +469,28 @@ public synchronized Stream getClasspathContributors() {
}
return classpathContributorServiceTracker.getTracked().values().stream();
}
+
+ public synchronized Clipboard getClipboardPlugin() {
+ if (fBundleContext == null) {
+ return null;
+ }
+ if (clipBoardsServiceTracker == null) {
+ clipBoardsServiceTracker = new ServiceTracker<>(fBundleContext, Clipboard.class, null);
+ clipBoardsServiceTracker.open();
+ }
+ return clipBoardsServiceTracker.getService();
+ }
+
+ public synchronized Stream getRepositoryListenerPlugins() {
+ if (fBundleContext == null) {
+ return Stream.empty();
+ }
+ if (repositoryListenerServiceTracker == null) {
+ repositoryListenerServiceTracker = new ServiceTracker<>(fBundleContext, RepositoryListenerPlugin.class,
+ null);
+ repositoryListenerServiceTracker.open();
+ }
+ return repositoryListenerServiceTracker.getTracked().values().stream();
+
+ }
}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/BndProjectManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/BndProjectManager.java
index c9b448053f..7b28d5aeac 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/BndProjectManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/BndProjectManager.java
@@ -97,7 +97,13 @@ static synchronized Workspace getWorkspace() throws Exception {
run.setProperty(Constants.STANDALONE, TRUE);
IPath path = PDECore.getDefault().getStateLocation().append(Project.BNDCNF);
workspace = Workspace.createStandaloneWorkspace(run, path.toFile().toURI());
+ workspace.set("workspaceName", Messages.BndProjectManager_WorkspaceName); //$NON-NLS-1$
+ workspace.set("workspaceDescription", Messages.BndProjectManager_WorkspaceDescription); //$NON-NLS-1$
workspace.addBasicPlugin(TargetRepository.getTargetRepository());
+ workspace.addBasicPlugin(new JobProgress());
+ workspace.addBasicPlugin(new SupplierClipboard(() -> PDECore.getDefault().getClipboardPlugin()));
+ workspace.addBasicPlugin(
+ new DelegateRepositoryListener(() -> PDECore.getDefault().getRepositoryListenerPlugins()));
workspace.refresh();
}
}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/DelegateRepositoryListener.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/DelegateRepositoryListener.java
new file mode 100644
index 0000000000..98f057a120
--- /dev/null
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/DelegateRepositoryListener.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Christoph Läubrich 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:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.internal.core.bnd;
+
+import java.io.File;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+
+import aQute.bnd.osgi.Jar;
+import aQute.bnd.service.RepositoryListenerPlugin;
+import aQute.bnd.service.RepositoryPlugin;
+
+public class DelegateRepositoryListener implements RepositoryListenerPlugin {
+
+ private Supplier> delegateSupplier;
+
+ public DelegateRepositoryListener(Supplier> delegateSupplier) {
+ this.delegateSupplier = delegateSupplier;
+ }
+
+ @Override
+ public void bundleAdded(RepositoryPlugin repository, Jar jar, File file) {
+ delegateSupplier.get().forEach(listener -> listener.bundleAdded(repository, jar, file));
+
+ }
+
+ @Override
+ public void bundleRemoved(RepositoryPlugin repository, Jar jar, File file) {
+ delegateSupplier.get().forEach(listener -> listener.bundleRemoved(repository, jar, file));
+ }
+
+ @Override
+ public void repositoryRefreshed(RepositoryPlugin repository) {
+ delegateSupplier.get().forEach(listener -> listener.repositoryRefreshed(repository));
+
+ }
+
+ @Override
+ public void repositoriesRefreshed() {
+ delegateSupplier.get().forEach(listener -> listener.repositoriesRefreshed());
+ }
+
+}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/JobProgress.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/JobProgress.java
index e0fe4dfacf..be576e63b1 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/JobProgress.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/JobProgress.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016, 2019 bndtools project and others.
+ * Copyright (c) 2016, 2024 bndtools project and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -11,23 +11,20 @@
* Contributors:
* Gregory Amerson - initial API and implementation
* BJ Hargrave - ongoing enhancements
+ * Christoph Läubrich - adapt to pde codebase
*******************************************************************************/
-package bndtools.central;
+package org.eclipse.pde.internal.core.bnd;
import java.util.concurrent.atomic.AtomicReference;
-import org.bndtools.api.ILogger;
-import org.bndtools.api.Logger;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import aQute.bnd.service.progress.ProgressPlugin;
-import bndtools.Plugin;
public class JobProgress implements ProgressPlugin {
- static final ILogger logger = Logger.getLogger(JobProgress.class);
@Override
public Task startTask(String name, int size) {
@@ -46,7 +43,6 @@ private static class TaskJob extends Job implements Task {
super(name);
this.name = name;
this.size = size;
- logger.logInfo(name, null);
}
@Override
@@ -60,8 +56,7 @@ protected IStatus run(IProgressMonitor monitor) {
Thread.sleep(100);
} catch (InterruptedException e) {
monitor.setCanceled(true);
- status.compareAndSet(null,
- new Status(IStatus.CANCEL, Plugin.PLUGIN_ID, "InterruptedException", e));
+ status.compareAndSet(null, Status.CANCEL_STATUS);
Thread.currentThread()
.interrupt();
}
@@ -78,7 +73,7 @@ protected IStatus run(IProgressMonitor monitor) {
private boolean isCanceled(IProgressMonitor m) {
boolean canceled = m.isCanceled();
if (canceled) {
- status.compareAndSet(null, new Status(IStatus.CANCEL, Plugin.PLUGIN_ID, "Canceled"));
+ status.compareAndSet(null, Status.CANCEL_STATUS);
}
return canceled;
}
@@ -94,8 +89,11 @@ public void worked(int units) {
@Override
public void done(String message, Throwable error) {
- status.compareAndSet(null,
- new Status(error == null ? IStatus.OK : IStatus.ERROR, Plugin.PLUGIN_ID, message, error));
+ if (error == null) {
+ status.compareAndSet(null, Status.OK_STATUS);
+ } else {
+ status.compareAndSet(null, Status.error(message, error));
+ }
}
@Override
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/Messages.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/Messages.java
new file mode 100644
index 0000000000..aa9cc220af
--- /dev/null
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/Messages.java
@@ -0,0 +1,16 @@
+package org.eclipse.pde.internal.core.bnd;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = Messages.class.getPackageName() + ".messages"; //$NON-NLS-1$
+ public static String BndProjectManager_WorkspaceDescription;
+ public static String BndProjectManager_WorkspaceName;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/PdeBndAdapter.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/PdeBndAdapter.java
index 444c1c360b..b7730d2041 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/PdeBndAdapter.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/PdeBndAdapter.java
@@ -13,17 +13,24 @@
*******************************************************************************/
package org.eclipse.pde.internal.core.bnd;
+import org.bndtools.versioncontrol.ignores.manager.api.VersionControlIgnoresManager;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.AdapterTypes;
import org.eclipse.core.runtime.IAdapterFactory;
import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
import aQute.bnd.build.Project;
-@Component(service = IAdapterFactory.class, property = {
- IAdapterFactory.SERVICE_PROPERTY_ADAPTABLE_CLASS + "=org.eclipse.core.resources.IProject",
- IAdapterFactory.SERVICE_PROPERTY_ADAPTER_NAMES + "=aQute.bnd.build.Project" })
+@Component(service = IAdapterFactory.class)
+@AdapterTypes(adaptableClass = IProject.class, adapterNames = { Project.class, VersionControlIgnoresManager.class })
public class PdeBndAdapter implements IAdapterFactory {
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
+ private volatile VersionControlIgnoresManager versionControlIgnoresManager;
+
@Override
public T getAdapter(Object adaptableObject, Class adapterType) {
if (adapterType == Project.class) {
@@ -36,12 +43,10 @@ public T getAdapter(Object adaptableObject, Class adapterType) {
}
}
}
+ if (adapterType == VersionControlIgnoresManager.class) {
+ return adapterType.cast(versionControlIgnoresManager);
+ }
return null;
}
- @Override
- public Class>[] getAdapterList() {
- return new Class>[] { Project.class };
- }
-
}
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/SupplierClipboard.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/SupplierClipboard.java
new file mode 100644
index 0000000000..07c4354fdf
--- /dev/null
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/SupplierClipboard.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Christoph Läubrich 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:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.internal.core.bnd;
+
+import java.util.Optional;
+import java.util.function.Supplier;
+
+import aQute.bnd.service.clipboard.Clipboard;
+
+public class SupplierClipboard implements Clipboard {
+
+ private Supplier supplier;
+
+ public SupplierClipboard(Supplier supplier) {
+ this.supplier = supplier;
+ }
+
+ @Override
+ public boolean copy(T content) {
+ Clipboard clipboard = supplier.get();
+ if (clipboard != null) {
+ return clipboard.copy(content);
+ }
+ return false;
+ }
+
+ @Override
+ public Optional paste(Class type) {
+ return Optional.ofNullable(supplier.get()).flatMap(clipboard -> clipboard.paste(type));
+ }
+
+}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/messages.properties b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/messages.properties
new file mode 100644
index 0000000000..e8505c0ca4
--- /dev/null
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/messages.properties
@@ -0,0 +1,2 @@
+BndProjectManager_WorkspaceDescription=The PDE Automatic Manifest Workspace
+BndProjectManager_WorkspaceName=PDE
diff --git a/ui/org.eclipse.pde.ui/.project b/ui/org.eclipse.pde.ui/.project
index dedc0515a2..b6a6ee4543 100644
--- a/ui/org.eclipse.pde.ui/.project
+++ b/ui/org.eclipse.pde.ui/.project
@@ -25,6 +25,11 @@
+
+ org.eclipse.pde.ds.core.builder
+
+
+
org.eclipse.jdt.core.javanature
diff --git a/ui/org.eclipse.pde.ui/.settings/org.eclipse.pde.ds.annotations.prefs b/ui/org.eclipse.pde.ui/.settings/org.eclipse.pde.ds.annotations.prefs
new file mode 100644
index 0000000000..5faf08b7d5
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/.settings/org.eclipse.pde.ds.annotations.prefs
@@ -0,0 +1,7 @@
+dsVersion=V1_4
+eclipse.preferences.version=1
+enabled=true
+generateBundleActivationPolicyLazy=true
+path=OSGI-INF
+validationErrorLevel=error
+validationErrorLevel.missingImplicitUnbindMethod=error
diff --git a/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
index 94edf9a43f..654ad2bd39 100644
--- a/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
@@ -120,6 +120,7 @@ Require-Bundle:
org.eclipse.equinox.security;bundle-version="[1.4.100,2.0.0)",
org.eclipse.pde.bnd.ui;bundle-version="1.0.0",
org.eclipse.pde.ds.core;bundle-version="1.3.300"
+Service-Component: OSGI-INF/org.eclipse.pde.internal.ui.BndPreferencesAdapter.xml
Import-Package: aQute.bnd.build;version="4.5.0",
aQute.bnd.build.model;version="[4.2.0,5.0.0)",
aQute.bnd.build.model.clauses;version="2.5.0",
@@ -142,3 +143,4 @@ Import-Package: aQute.bnd.build;version="4.5.0",
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Automatic-Module-Name: org.eclipse.pde.ui
+
diff --git a/ui/org.eclipse.pde.ui/OSGI-INF/.gitignore b/ui/org.eclipse.pde.ui/OSGI-INF/.gitignore
new file mode 100644
index 0000000000..b878e882ac
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/OSGI-INF/.gitignore
@@ -0,0 +1 @@
+/*.xml
diff --git a/ui/org.eclipse.pde.ui/build.properties b/ui/org.eclipse.pde.ui/build.properties
index cf3100634e..50ecc9c392 100644
--- a/ui/org.eclipse.pde.ui/build.properties
+++ b/ui/org.eclipse.pde.ui/build.properties
@@ -17,7 +17,8 @@ bin.includes = plugin.properties,\
plugin.xml,\
about.html,\
META-INF/,\
- css/
+ css/,\
+ OSGI-INF/
src.includes = about.html,\
schema/
source.. = src/,\
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/BndPreferencesAdapter.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/BndPreferencesAdapter.java
new file mode 100644
index 0000000000..e6db037c5c
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/BndPreferencesAdapter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Christoph Läubrich 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:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.internal.ui;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.AdapterTypes;
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.pde.bnd.ui.preferences.BndPreferences;
+import org.eclipse.pde.internal.core.natures.BndProject;
+import org.osgi.service.component.annotations.Component;
+
+@Component(service = IAdapterFactory.class)
+@AdapterTypes(adaptableClass = IProject.class, adapterNames = BndPreferences.class)
+public class BndPreferencesAdapter implements IAdapterFactory {
+
+ @Override
+ public T getAdapter(Object adaptableObject, Class adapterType) {
+ if (adaptableObject instanceof IProject project) {
+ if (adapterType == BndPreferences.class) {
+ if (BndProject.isBndProject(project)) {
+ return adapterType.cast(new BndPreferences(project, PDEPlugin.getDefault().getPreferenceStore()));
+ }
+ }
+ }
+ return null;
+ }
+
+}