Skip to content

Commit

Permalink
Support selection of Bndtools Template in PDE Project Wizards
Browse files Browse the repository at this point in the history
PDE already offers a templating mechanism based on extension points,
BndTools has one as well that is based on services.

This is an attempt to make BndTools based items available for the new
automatic manifest generation that currently lacks any wizards.

Fix #704
  • Loading branch information
laeubi committed Jan 22, 2024
1 parent 25a06e7 commit d8cc7b5
Show file tree
Hide file tree
Showing 17 changed files with 552 additions and 48 deletions.
4 changes: 4 additions & 0 deletions features/org.eclipse.pde-feature/feature.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,8 @@
id="org.eclipse.pde.bnd.ui"
version="0.0.0"/>

<plugin
id="org.bndtools.templates.template"
version="0.0.0"/>

</feature>
8 changes: 6 additions & 2 deletions ui/org.eclipse.pde.bnd.ui/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ Bundle-Name: Generic UI components related to BND
Bundle-SymbolicName: org.eclipse.pde.bnd.ui;singleton:=true
Bundle-Vendor: Eclipse.org
Bundle-Version: 1.0.0.qualifier
Export-Package: org.eclipse.pde.bnd.ui;version="1.0.0";x-friends:="org.eclipse.pde.ui"
Export-Package: org.eclipse.pde.bnd.ui;version="1.0.0";x-friends:="org.eclipse.pde.ui",
org.eclipse.pde.bnd.ui.preferences;version="1.0.0";x-friends:="org.eclipse.pde.ui",
org.eclipse.pde.bnd.ui.templating;version="1.0.0";x-friends:="org.eclipse.pde.ui",
org.eclipse.pde.bnd.ui.wizards;version="1.0.0";x-friends:="org.eclipse.pde.ui"
Import-Package: aQute.bnd.build;version="4.5.0",
aQute.bnd.build.model;version="4.3.0",
aQute.bnd.build.model.clauses;version="2.5.0",
Expand Down Expand Up @@ -37,5 +40,6 @@ Automatic-Module-Name: org.eclipse.pde.bnd.ui
Bundle-Activator: org.eclipse.pde.bnd.ui.Resources
Bundle-RequiredExecutionEnvironment: JavaSE-17
Service-Component: OSGI-INF/org.bndtools.templating.repos.xml,
OSGI-INF/org.eclipse.pde.bnd.ui.internal.Auxiliary.xml
OSGI-INF/org.eclipse.pde.bnd.ui.internal.Auxiliary.xml,
OSGI-INF/org.eclipse.pde.bnd.ui.internal.TemplateAdapter.xml
Bundle-ActivationPolicy: lazy
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright (c) 2023 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.bnd.ui.internal;

import java.net.MalformedURLException;
import java.net.URI;

import org.bndtools.templating.Template;
import org.eclipse.core.runtime.AdapterTypes;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.pde.bnd.ui.templating.RepoTemplateLabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;

@Component
@AdapterTypes(adaptableClass = Template.class, adapterNames = { ILabelProvider.class, Image.class })
public class TemplateAdapter implements IAdapterFactory {

private RepoTemplateLabelProvider labelProvider = new RepoTemplateLabelProvider();
private ImageRegistry imageRegistry;

@Override
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
if (adaptableObject instanceof Template template) {
if (adapterType == ILabelProvider.class) {
return adapterType.cast(labelProvider);
}
if (adapterType == Image.class) {
URI icon = template.getIcon();
ImageRegistry registry = getImageRegistry();
String key = icon.toASCIIString();
ImageDescriptor descriptor = registry.getDescriptor(key);
if (descriptor == null) {
try {
registry.put(key, ImageDescriptor.createFromURL(icon.toURL()));
} catch (MalformedURLException e) {
return null;
}
}
return adapterType.cast(registry.get(key));
}
}
return null;
}

@Deactivate
void dispose() {
labelProvider.dispose();
synchronized (this) {
if (imageRegistry != null) {
imageRegistry.dispose();
}
}
}

private ImageRegistry getImageRegistry() {
synchronized (this) {
if (imageRegistry == null) {
imageRegistry = new ImageRegistry(Display.getCurrent());
}
return imageRegistry;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,38 @@
*******************************************************************************/
package org.eclipse.pde.bnd.ui.templating;

import java.util.Map;

import org.bndtools.templating.Category;
import org.bndtools.templating.Template;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.pde.bnd.ui.BoldStyler;
import org.eclipse.pde.bnd.ui.Resources;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.osgi.framework.Version;

public class RepoTemplateLabelProvider extends StyledCellLabelProvider {

private static final Image IMG_FOLDER = PlatformUI.getWorkbench()
.getSharedImages()
.getImage(ISharedImages.IMG_OBJ_FOLDER);
public class RepoTemplateLabelProvider extends StyledCellLabelProvider implements ILabelProvider {

private final Map<Template, Image> loadedImages;
private final Image defaultIcon;

public RepoTemplateLabelProvider(Map<Template, Image> loadedImages, Image defaultIcon) {
this.loadedImages = loadedImages;
this.defaultIcon = defaultIcon;
}
private static final Image IMG_FOLDER = PlatformUI.getWorkbench().getSharedImages()
.getImage(ISharedImages.IMG_OBJ_FOLDER);

@Override
public void update(ViewerCell cell) {
Object element = cell.getElement();

if (element instanceof Category) {
Category cat = (Category) element;
Category cat = Adapters.adapt(element, Category.class);
if (cat != null) {
cell.setText(cat.getName());
cell.setImage(IMG_FOLDER);
} else if (element instanceof Template) {
Template template = (Template) element;

cell.setStyleRanges(new StyleRange[0]);
return;
}
Template template = Adapters.adapt(element, Template.class);
if (template != null) {
// Name
StyledString label = new StyledString(template.getName(), BoldStyler.INSTANCE_DEFAULT);

Expand All @@ -61,7 +55,7 @@ public void update(ViewerCell cell) {
if (version != null) {
label.append(" ");
label.append(String.format("%d.%d.%d", version.getMajor(), version.getMinor(), version.getMicro()),
BoldStyler.INSTANCE_COUNTER);
BoldStyler.INSTANCE_COUNTER);
String q = version.getQualifier();
if (q != null && !q.isEmpty())
label.append("." + q, StyledString.COUNTER_STYLER);
Expand All @@ -70,19 +64,33 @@ public void update(ViewerCell cell) {
String description = template.getShortDescription();
if (description != null) {
label.append(" \u2014 [", StyledString.QUALIFIER_STYLER)
.append(template.getShortDescription(), StyledString.QUALIFIER_STYLER)
.append("]", StyledString.QUALIFIER_STYLER);
.append(template.getShortDescription(), StyledString.QUALIFIER_STYLER)
.append("]", StyledString.QUALIFIER_STYLER);
}

cell.setText(label.toString());
cell.setStyleRanges(label.getStyleRanges());

Image image = loadedImages.get(template);
Image image = Adapters.adapt(template, Image.class);
if (image == null)
cell.setImage(defaultIcon);
cell.setImage(Resources.getImage("/icons/template.gif"));
else
cell.setImage(image);
return;
}
cell.setStyleRanges(new StyleRange[0]);
cell.setText(getText(element));
cell.setImage(getImage(element));
}

@Override
public Image getImage(Object element) {
return null;
}

@Override
public String getText(Object element) {
return null;
}

}
}
8 changes: 8 additions & 0 deletions ui/org.eclipse.pde.ui/.settings/.api_filters
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.pde.ui" version="2">
<resource path="src/org/eclipse/pde/internal/ui/editor/IContextPart.java" type="org.eclipse.pde.internal.ui.editor.IContextPart">
<filter comment="only internal API" id="571473929">
<message_arguments>
<message_argument value="IModelChangedListener"/>
<message_argument value="IContextPart"/>
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/pde/internal/ui/editor/category/SiteBundleAdapter.java" type="org.eclipse.pde.internal.ui.editor.category.SiteBundleAdapter">
<filter comment="PDE UI may use restricted code from PDE Core" id="574619656">
<message_arguments>
Expand Down
2 changes: 2 additions & 0 deletions ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ Import-Package: aQute.bnd.build;version="4.5.0",
aQute.bnd.properties;version="[2.0.0,3.0.0)",
aQute.bnd.service;version="[4.8.0,5.0.0)",
aQute.bnd.version;version="[2.2.0,3.0.0)",
aQute.service.reporter;version="1.2.0",
biz.aQute.resolve;version="[9.0.0,10.0.0)",
org.bndtools.templating;version="[2.0.0,3.0.0)",
org.eclipse.jdt.debug.ui.console,
org.eclipse.ui.internal.genericeditor,
org.osgi.service.event;version="[1.4,2.0.0)",
Expand Down
1 change: 1 addition & 0 deletions ui/org.eclipse.pde.ui/plugin.properties
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ preferences.main.name= Plug-in Development
preferences.target.name = Target Platform
preferences.compilers.name = Compilers
preferences.editor.name = Editors
preferences.bnd.templaterepo.name = Bnd Template Repositories

preferenceKeywords.PDE=Plug-in plugin Development PDE
preferenceKeywords.MainPreferencePage=java search target source dependencies JUnit launch workspace configuration plug-in fragment bundle
Expand Down
6 changes: 6 additions & 0 deletions ui/org.eclipse.pde.ui/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@
id="org.eclipse.pde.ui.TargetPlatformPreferencePage">
</keywordReference>
</page>
<page
name="%preferences.bnd.templaterepo.name"
category="org.eclipse.pde.ui.MainPreferencePage"
class="org.eclipse.pde.bnd.ui.preferences.ReposPreferencePage"
id="org.eclipse.pde.bnd.ui.preferences.ReposPreferencePage">
</page>
</extension>
<extension
point="org.eclipse.ui.keywords">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,8 @@ public class PDEUIMessages extends NLS {

public static String BaseWizardSelectionPage_noDesc;

public static String BaseWizardSelectionPage_loadingDesc;

public static String ChooseClassXMLResolution_label;

public static String ChooseManifestClassResolution_label;
Expand Down Expand Up @@ -1194,6 +1196,8 @@ public class PDEUIMessages extends NLS {

public static String NewPluginProjectFromTemplateWizard_1;

public static String NewPluginProjectWizard_0;

public static String NewProjectWizard_MainPage_ftitle;
public static String NewProductFileWizard_windowTitle;
public static String NewProjectWizard_MainPage_fdesc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.swt.widgets.Display;

import aQute.bnd.help.Syntax;

Expand All @@ -52,8 +53,8 @@ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int
ICompletionProposal[] found = proposals(prefix, offset);
if (found.length == 1) {
found[0].apply(document);
viewer.setSelectedRange(offset + (found[0].getDisplayString().length() - prefix.length() + 2),
0);
Display.getDefault().execute(() -> viewer.setSelectedRange(
offset + (found[0].getDisplayString().length() - prefix.length() + 2), 0));
return new ICompletionProposal[0];
}
return found;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@ SourceBlock_remove = &Remove
NewFragmentProjectWizard_title = New Fragment Project
NewPluginProjectFromTemplateWizard_0=Could not load the template {0}
NewPluginProjectFromTemplateWizard_1=Problem loading plug-in template
NewPluginProjectWizard_0=Loading Templates...
NewProjectWizard_MainPage_ftitle = Fragment Project
NewProductFileWizard_windowTitle=New Product Configuration
NewProjectWizard_MainPage_fdesc = Create a new fragment project
Expand Down Expand Up @@ -1003,6 +1004,7 @@ BaseExtensionPoint_pluginId = &Plug-in ID:
BaseExtensionPoint_id = &Extension Point ID:
BaseExtensionPoint_name = Extension Point &Name:
BaseWizardSelectionPage_noDesc=No Description available.
BaseWizardSelectionPage_loadingDesc=Loading Description...
BaseExtensionPoint_schema = Extension Point &Schema:
BaseExtensionPoint_schemaLocation = C&ontainer:
BaseExtensionPoint_edit = E&dit extension point schema when done
Expand Down
Loading

0 comments on commit d8cc7b5

Please sign in to comment.