pub = null;
String name = mf.getMainAttributes().getValue(OSGiConstants.BUNDLE_SYMBOLIC_NAME);
if (name != null) {
return getIcon();
@@ -163,12 +159,85 @@ public Image getBadgeIcon(FileObject jarFile, Artifact art) {
publicCache.put(jarRoot, NOT_OSGIJAR);
}
}
- return null;
+ return null;
}
@NbBundle.Messages("Tooltip_manifest=Contains OSGi manifest headers")
private Image getIcon() {
- return ImageUtilities.addToolTipToImage(ImageUtilities.loadImage(BADGE), toolTip);
+ return ImageUtilities.addToolTipToImage(ImageUtilities.loadImage(BADGE), TOOLTIP);
}
+ /**
+ * OSGI-Specification declares:
+ *
+ *
+ * Export-Package ::= export ( ',' export)*
+ * export ::= package-names ( ';' parameter )*
+ * package-names ::= package-name // See 1.3.2
+ * ( ';' package-name )*
+ *
+ *
+ * @param exportPkg String formatted according to Export-Package
+ * @return list of package-name entries
+ */
+ // Same implementation is used in org.netbeans.core.netigso.Netigso and
+ // org.netbeans.modules.maven.osgi.OSGiJarAccessibilityQueryImpl copied to
+ // not introduce module dependencies. Tests are in Netigso, when updated,
+ // update both places!
+ static List splitExportPackages(String exportPkg) {
+ List exports = new ArrayList<>();
+ StringBuilder buffer = new StringBuilder();
+ boolean inQuotedString = false;
+ for (int i = 0; i < exportPkg.length(); i++) {
+ char nextChar = exportPkg.charAt(i);
+ switch(nextChar) {
+ case '"' -> {
+ inQuotedString = ! inQuotedString;
+ buffer.append(nextChar);
+ }
+ case ',' -> {
+ if (inQuotedString) {
+ buffer.append(nextChar);
+ } else {
+ exports.add(buffer.toString());
+ buffer.setLength(0);
+ }
+ }
+ case '\\' -> {
+ buffer.append(nextChar);
+ if (inQuotedString) {
+ if((i + 1) == exportPkg.length()) {
+ throw new IllegalStateException("Invalid escape sequence");
+ }
+ nextChar = exportPkg.charAt(i + 1);
+ i++;
+ if (nextChar == '"' || nextChar == '\\') {
+ buffer.append(nextChar);
+ } else {
+ throw new IllegalStateException("Invalid escape sequence");
+ }
+ }
+ }
+ default -> buffer.append(nextChar);
+ }
+ }
+ if(! buffer.isEmpty()){
+ exports.add(buffer.toString());
+ }
+ List packageNames = new ArrayList<>();
+ // Each export statement can hold multiple package names separated by
+ // semicolon, so split on semicolon. package-name and parameter are
+ // discerned based on the presence of a equals character. A package-name
+ // must not contain it, a parameter must.
+ for(String export: exports) {
+ for(String packageCandiate: export.split(";")) {
+ // package-name list ends with first parameter
+ if(packageCandiate.contains("=")) {
+ break;
+ }
+ packageNames.add(packageCandiate);
+ }
+ }
+ return packageNames;
+ }
}
diff --git a/java/maven.osgi/src/org/netbeans/modules/maven/osgi/customizer/FelixExportPersister.java b/java/maven.osgi/src/org/netbeans/modules/maven/osgi/customizer/FelixExportPersister.java
index 1678c4b1fa00..a31a6a2ae5a0 100644
--- a/java/maven.osgi/src/org/netbeans/modules/maven/osgi/customizer/FelixExportPersister.java
+++ b/java/maven.osgi/src/org/netbeans/modules/maven/osgi/customizer/FelixExportPersister.java
@@ -51,10 +51,10 @@ public class FelixExportPersister implements SelectedItemsTablePersister {
private final Project project;
private ModelOperation operation;
private ModelOperation defaultOperation;
-
+
private boolean isDefined = false;
- private SortedMap defaultValue;
+ private final SortedMap defaultValue;
public FelixExportPersister (Project project, ModelHandle2 handle) {
this.project = project;
@@ -79,17 +79,17 @@ public FelixExportPersister (Project project, ModelHandle2 handle) {
privateInstruction = privates[0];
}
- Map instructions = new HashMap(2);
+ Map instructions = new HashMap<>(2);
instructions.put(InstructionsConverter.EXPORT_PACKAGE, exportInstruction);
instructions.put(InstructionsConverter.PRIVATE_PACKAGE, privateInstruction);
defaultValue = InstructionsConverter.computeExportList(instructions, project);
}
-
+
public boolean isIsDefined() {
return isDefined;
}
-
+
@Override
public SortedMap read() {
@@ -101,9 +101,9 @@ public void write(SortedMap selItems) {
if (operation != null) {
handle.removePOMModification(operation);
}
-
+
final Map exportIns = InstructionsConverter.computeExportInstructions(selItems, project);
- operation = new ModelOperation() {
+ operation = new ModelOperation<>() {
@Override
public void performOperation(POMModel pomModel) {
@@ -143,7 +143,7 @@ public void performOperation(POMModel pomModel) {
createPOMExtensibilityElement(new QName(OSGiConstants.PARAM_INSTRUCTIONS));
config.addExtensibilityElement(instructionsEl);
}
-
+
POMExtensibilityElement exportEl = ModelUtils.getOrCreateChild(instructionsEl, OSGiConstants.EXPORT_PACKAGE, pomModel);
POMExtensibilityElement privateEl = ModelUtils.getOrCreateChild(instructionsEl, OSGiConstants.PRIVATE_PACKAGE, pomModel);
@@ -162,7 +162,7 @@ void setDefault(boolean def) {
}
if (defaultOperation == null) {
defaultOperation = new ModelOperation() {
-
+
@Override
public void performOperation(POMModel pomModel) {
Build build = pomModel.getProject().getBuild();
@@ -191,7 +191,7 @@ public void performOperation(POMModel pomModel) {
}
}
}
-
+
private POMExtensibilityElement findInstructions(PluginContainer cont) {
Plugin felixPlugin = cont.findPluginById(OSGiConstants.GROUPID_FELIX, OSGiConstants.ARTIFACTID_BUNDLE_PLUGIN);
if (felixPlugin != null) {
@@ -206,7 +206,7 @@ private POMExtensibilityElement findInstructions(PluginContainer cont) {
}
}
return null;
- }
+ }
private void removeExportPrivate(POMExtensibilityElement instructionsEl) {
if (instructionsEl != null) {
@@ -221,7 +221,7 @@ private void removeExportPrivate(POMExtensibilityElement instructionsEl) {
}
}
};
-
+
}
handle.addPOMModification(defaultOperation);
} else {
diff --git a/java/maven.osgi/src/org/netbeans/modules/maven/osgi/customizer/InstructionsConverter.java b/java/maven.osgi/src/org/netbeans/modules/maven/osgi/customizer/InstructionsConverter.java
index 7312fa3d7d1a..588ccb183595 100644
--- a/java/maven.osgi/src/org/netbeans/modules/maven/osgi/customizer/InstructionsConverter.java
+++ b/java/maven.osgi/src/org/netbeans/modules/maven/osgi/customizer/InstructionsConverter.java
@@ -44,7 +44,7 @@ public final class InstructionsConverter {
public static final Integer PRIVATE_PACKAGE = 2;
public static Map computeExportInstructions (Map items, Project project) {
- Map instructionsMap = new HashMap(2);
+ Map instructionsMap = new HashMap<>(2);
StringBuilder exportIns = new StringBuilder();
boolean isFirst = true;
for (Entry entry : items.entrySet()) {
@@ -78,7 +78,7 @@ public static Map computeExportInstructions (Map computeExportList (Map exportInstructions, Project project) {
- SortedMap pkgMap = new TreeMap();
+ SortedMap pkgMap = new TreeMap<>();
SortedSet pkgNames = FileUtilities.getPackageNames(project);
for (String name : pkgNames) {
pkgMap.put(name, Boolean.FALSE);
diff --git a/java/maven.osgi/src/org/netbeans/modules/maven/osgi/templates/ActivatorIterator.java b/java/maven.osgi/src/org/netbeans/modules/maven/osgi/templates/ActivatorIterator.java
index a04aee6eb1aa..49ab65db7f74 100644
--- a/java/maven.osgi/src/org/netbeans/modules/maven/osgi/templates/ActivatorIterator.java
+++ b/java/maven.osgi/src/org/netbeans/modules/maven/osgi/templates/ActivatorIterator.java
@@ -63,21 +63,22 @@
*
* @author mkleint
*/
-@TemplateRegistration(folder="OSGi", position=100, content="Activator.java.template", scriptEngine="freemarker", displayName="#template.activator", iconBase="org/netbeans/modules/maven/osgi/templates/new_OSGi_file_16.png", description="new_OSGi_activator.html", category="osgi")
+@TemplateRegistration(
+ folder="OSGi",
+ position=100,
+ content="Activator.java.template",
+ scriptEngine="freemarker",
+ displayName="#template.activator",
+ iconBase="org/netbeans/modules/maven/osgi/templates/new_OSGi_file_16.png",
+ description="new_OSGi_activator.html",
+ category="osgi"
+)
@Messages("template.activator=Bundle Activator")
public class ActivatorIterator implements TemplateWizard.AsynchronousInstantiatingIterator {
- private static final Logger LOG = Logger.getLogger(ActivatorIterator.class.getName());
-
+
// You should define what panels you want to use here:
protected List> createPanels (Project project, TemplateWizard wiz) {
Sources sources = ProjectUtils.getSources(project);
- DataFolder targetFolder=null;
- try {
- targetFolder = wiz.getTargetFolder();
- }
- catch (IOException ex) {
- targetFolder = DataFolder.findFolder(project.getProjectDirectory());
- }
return Collections.>singletonList(
JavaTemplates.createPackageChooser(project,
sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA))
@@ -94,13 +95,13 @@ public Set instantiate () throws IOException/*, IllegalStateExceptio
// More advanced wizards can create multiple objects from template
// (return them all in the result of this method), populate file
// contents on the fly, etc.
-
+
org.openide.filesystems.FileObject dir = Templates.getTargetFolder( wiz );
DataFolder df = DataFolder.findFolder( dir );
-
+
FileObject template = Templates.getTemplate( wiz );
-
- DataObject dTemplate = DataObject.find( template );
+
+ DataObject dTemplate = DataObject.find( template );
final DataObject dobj = dTemplate.createFromTemplate( df, Templates.getTargetName( wiz ) );
//this part might be turned pluggable once we have also ant based osgi projects. if..
@@ -110,15 +111,10 @@ public Set instantiate () throws IOException/*, IllegalStateExceptio
final NbMavenProject prj = project.getLookup().lookup(NbMavenProject.class);
if (prj != null) {
- Utilities.performPOMModelOperations(project.getProjectDirectory().getFileObject("pom.xml"),
- Collections.>singletonList(
- new ModelOperation() {
- @Override
- public void performOperation(POMModel model) {
- addActivator(prj, model, path);
- }
- }
- ));
+ Utilities.performPOMModelOperations(
+ project.getProjectDirectory().getFileObject("pom.xml"),
+ List.>of((model) -> addActivator(prj, model, path))
+ );
}
return Collections.singleton(dobj);
@@ -141,7 +137,7 @@ private void addActivator(NbMavenProject prj, POMModel mdl, String path) {
plugin = mdl.getFactory().createPlugin();
plugin.setGroupId(OSGiConstants.GROUPID_FELIX);
plugin.setArtifactId(OSGiConstants.ARTIFACTID_BUNDLE_PLUGIN);
- String ver = PluginPropertyUtils.getPluginVersion(prj.getMavenProject(),
+ String ver = PluginPropertyUtils.getPluginVersion(prj.getMavenProject(),
OSGiConstants.GROUPID_FELIX, OSGiConstants.ARTIFACTID_BUNDLE_PLUGIN);
if (ver == null) {
//not defined in resolved project, set version.
@@ -183,13 +179,14 @@ private void addActivator(NbMavenProject prj, POMModel mdl, String path) {
}
// --- The rest probably does not need to be touched. ---
-
+
private transient int index;
private transient List> panels;
private transient TemplateWizard wiz;
+ @SuppressWarnings("unused")
private static final long serialVersionUID = -7586964579556513549L;
-
+
// You can keep a reference to the TemplateWizard which can
// provide various kinds of useful information such as
// the currently selected target name.
@@ -200,15 +197,15 @@ public void initialize (WizardDescriptor wiz) {
index = 0;
Project project = Templates.getProject( wiz );
panels = createPanels (project,this.wiz);
-
+
// Creating steps.
Object prop = wiz.getProperty (WizardDescriptor.PROP_CONTENT_DATA); // NOI18N
String[] beforeSteps = null;
- if (prop instanceof String[]) {
- beforeSteps = (String[])prop;
+ if (prop instanceof String[] strings) {
+ beforeSteps = strings;
}
String[] steps = createSteps (beforeSteps, panels);
-
+
for (int i = 0; i < panels.size(); i++) {
Component c = panels.get(i).getComponent ();
if (steps[i] == null) {
@@ -217,10 +214,9 @@ public void initialize (WizardDescriptor wiz) {
// chooser to appear in the list of steps.
steps[i] = c.getName ();
}
- if (c instanceof JComponent) { // assume Swing components
- JComponent jc = (JComponent) c;
+ if (c instanceof JComponent jc) { // assume Swing components
// Step #.
- jc.putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, Integer.valueOf(i));
+ jc.putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, i);
// Step name (actually the whole list for reference).
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DATA, steps);
}
@@ -242,7 +238,7 @@ public void uninitialize (WizardDescriptor wiz) {
public String name () {
return TITLE_x_of_y(index + 1, panels.size());
}
-
+
@Override
public boolean hasNext () {
return index < panels.size() - 1;
@@ -269,7 +265,7 @@ public void previousPanel () {
public WizardDescriptor.Panel current () {
return panels.get(index);
}
-
+
// If nothing unusual changes in the middle of the wizard, simply:
@Override
public final void addChangeListener (ChangeListener l) {}
diff --git a/java/maven.osgi/src/org/netbeans/modules/maven/osgi/templates/BundleWizard.java b/java/maven.osgi/src/org/netbeans/modules/maven/osgi/templates/BundleWizard.java
index d6d99785b3ae..de5b70f32a50 100644
--- a/java/maven.osgi/src/org/netbeans/modules/maven/osgi/templates/BundleWizard.java
+++ b/java/maven.osgi/src/org/netbeans/modules/maven/osgi/templates/BundleWizard.java
@@ -26,8 +26,14 @@
import static org.netbeans.modules.maven.osgi.templates.Bundle.*;
public class BundleWizard {
-
- @TemplateRegistration(folder=ArchetypeWizards.TEMPLATE_FOLDER, position=290, displayName="#template.project.OSGi", iconBase="org/netbeans/modules/maven/osgi/maven_osgi_16.png", description="OSGiDescription.html")
+
+ @TemplateRegistration(
+ folder=ArchetypeWizards.TEMPLATE_FOLDER,
+ position=290,
+ displayName="#template.project.OSGi",
+ iconBase="org/netbeans/modules/maven/osgi/maven_osgi_16.png",
+ description="OSGiDescription.html"
+ )
@Messages("template.project.OSGi=OSGi Bundle")
public static WizardDescriptor.InstantiatingIterator> create() {
return ArchetypeWizards.definedArchetype("org.codehaus.mojo.archetypes", "osgi-archetype", "1.4", null, template_project_OSGi());
diff --git a/platform/core.netigso/src/org/netbeans/core/netigso/Netigso.java b/platform/core.netigso/src/org/netbeans/core/netigso/Netigso.java
index 61e6de2d4249..25d5220e8923 100644
--- a/platform/core.netigso/src/org/netbeans/core/netigso/Netigso.java
+++ b/platform/core.netigso/src/org/netbeans/core/netigso/Netigso.java
@@ -293,7 +293,7 @@ protected Set createLoader(ModuleInfo m, ProxyClassLoader pcl, File jar)
}
if (exported instanceof String) {
for (String p : splitExportPackages(exported.toString())) {
- pkgs.add(extractBundleName(p));
+ pkgs.add(p);
}
}
} finally {
@@ -802,8 +802,25 @@ public final byte[] patchBC(ClassLoader l, String className, ProtectionDomain pd
return patchByteCode(l, className, pd, arr);
}
+ /**
+ * OSGI-Specification declares:
+ *
+ *
+ * Export-Package ::= export ( ',' export)*
+ * export ::= package-names ( ';' parameter )*
+ * package-names ::= package-name // See 1.3.2
+ * ( ';' package-name )*
+ *
+ *
+ * @param exportPkg String formatted according to Export-Package
+ * @return list of package-name entries
+ */
+ // Same implementation is used in org.netbeans.core.netigso.Netigso and
+ // org.netbeans.modules.maven.osgi.OSGiJarAccessibilityQueryImpl copied to
+ // not introduce module dependencies. Tests are in Netigso, when updated,
+ // update both places!
static List splitExportPackages(String exportPkg) {
- List elements = new ArrayList<>();
+ List exports = new ArrayList<>();
StringBuilder buffer = new StringBuilder();
boolean inQuotedString = false;
for (int i = 0; i < exportPkg.length(); i++) {
@@ -817,7 +834,7 @@ static List splitExportPackages(String exportPkg) {
if (inQuotedString) {
buffer.append(nextChar);
} else {
- elements.add(buffer.toString());
+ exports.add(buffer.toString());
buffer.setLength(0);
}
}
@@ -840,9 +857,23 @@ static List splitExportPackages(String exportPkg) {
}
}
if(! buffer.isEmpty()){
- elements.add(buffer.toString());
+ exports.add(buffer.toString());
+ }
+ List packageNames = new ArrayList<>();
+ // Each export statement can hold multiple package names separated by
+ // semicolon, so split on semicolon. package-name and parameter are
+ // discerned based on the presence of a equals character. A package-name
+ // must not contain it, a parameter must.
+ for(String export: exports) {
+ for(String packageCandiate: export.split(";")) {
+ // package-name list ends with first parameter
+ if(packageCandiate.contains("=")) {
+ break;
+ }
+ packageNames.add(packageCandiate);
+ }
}
- return elements;
+ return packageNames;
}
}
diff --git a/platform/core.netigso/test/unit/src/org/netbeans/core/netigso/NetigsoTest.java b/platform/core.netigso/test/unit/src/org/netbeans/core/netigso/NetigsoTest.java
index c440c9a9482a..e0ffe14d713d 100644
--- a/platform/core.netigso/test/unit/src/org/netbeans/core/netigso/NetigsoTest.java
+++ b/platform/core.netigso/test/unit/src/org/netbeans/core/netigso/NetigsoTest.java
@@ -223,17 +223,24 @@ public void testSplitExportPackages() {
List result = Netigso.splitExportPackages(exportPkgs);
assertEquals(4, result.size());
assertEquals("a.b", result.get(0));
- assertEquals("a.b.c;version=\"1.0.0\";uses:=\"x.y.z,x.y.z.k\"", result.get(1));
- assertEquals("a.b.c.d;version=\"1.0.0\"", result.get(2));
- assertEquals("a.b.c.e;version=\"1.0.0\";uses:=\"x.y.z\"", result.get(3));
+ assertEquals("a.b.c", result.get(1));
+ assertEquals("a.b.c.d", result.get(2));
+ assertEquals("a.b.c.e", result.get(3));
// Test that the \" are ignored.
exportPkgs = "x.y.z,a.b.c;a=\"\\\"\",d.e.f";
result = Netigso.splitExportPackages(exportPkgs);
assertEquals(3, result.size());
assertEquals("x.y.z", result.get(0));
- assertEquals("a.b.c;a=\"\\\"\"", result.get(1));
+ assertEquals("a.b.c", result.get(1));
assertEquals("d.e.f", result.get(2));
}
+ public void testSplitExportMultiPackagePackages() {
+ String exportPkgs = "com.acme.foo;com.acme.bar;version=1.23";
+ List result = Netigso.splitExportPackages(exportPkgs);
+ assertEquals(2, result.size());
+ assertEquals("com.acme.foo", result.get(0));
+ assertEquals("com.acme.bar", result.get(1));
+ }
}