You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2025/01/30 13:15:57 UTC
(camel-karaf) branch camel-karaf-4.8.x updated: Ref #590 Add Bundle-Name and Bundle-SymbolicName to wrapped bundles (#591)
This is an automated email from the ASF dual-hosted git repository.
nfilotto pushed a commit to branch camel-karaf-4.8.x
in repository https://gitbox.apache.org/repos/asf/camel-karaf.git
The following commit(s) were added to refs/heads/camel-karaf-4.8.x by this push:
new 3e8a241bb Ref #590 Add Bundle-Name and Bundle-SymbolicName to wrapped bundles (#591)
3e8a241bb is described below
commit 3e8a241bbb60c64b26b6110bc327bc03d7a3cb19
Author: François de Parscau <11...@users.noreply.github.com>
AuthorDate: Thu Jan 30 14:15:52 2025 +0100
Ref #590 Add Bundle-Name and Bundle-SymbolicName to wrapped bundles (#591)
Motivation
Very long names in karaf console when listing bundles by names or symbolic names
Modifications:
Add Bundle-Name= and Bundle-SymbolicName= to the wrapped bundles
---
features/pom.xml | 1 +
features/src/main/feature/camel-features.xml | 2 +-
.../feature/maven/EnsureWrapBundleNameMojo.java | 142 +++++++++++++++++++++
.../maven/EnsureWrapBundleNameMojoTest.java | 77 +++++++++++
4 files changed, 221 insertions(+), 1 deletion(-)
diff --git a/features/pom.xml b/features/pom.xml
index c1a926148..0d947d994 100644
--- a/features/pom.xml
+++ b/features/pom.xml
@@ -76,6 +76,7 @@
<goals>
<goal>auto-detect-version</goal>
<goal>ensure-wrap-bundle-version</goal>
+ <goal>ensure-wrap-bundle-name</goal>
<goal>configure-wrap-spi-provider</goal>
</goals>
<configuration>
diff --git a/features/src/main/feature/camel-features.xml b/features/src/main/feature/camel-features.xml
index 362aa0117..b05258290 100644
--- a/features/src/main/feature/camel-features.xml
+++ b/features/src/main/feature/camel-features.xml
@@ -1128,7 +1128,7 @@
<feature version='${camel-osgi-version-range}'>camel-core</feature>
<bundle dependency='true'>wrap:mvn:com.alibaba/fastjson/${fastjson-version}</bundle>
<bundle dependency='true'>wrap:mvn:com.alibaba.fastjson2/fastjson2/${auto-detect-version}</bundle>
- <bundle dependency='true'>wrap:mvn:com.alibaba.fastjson2/fastjson2-extension/${auto-detect-version}</bundle>
+ <bundle dependency='true'>wrap:mvn:com.alibaba.fastjson2/fastjson2-extension/${auto-detect-version}$Fragment-Host=wrap_com.alibaba.fastjson2.fastjson2</bundle>
<bundle>mvn:org.apache.camel.karaf/camel-fastjson/${project.version}</bundle>
</feature>
<feature name='camel-fhir' version='${project.version}' start-level='50'>
diff --git a/tooling/camel-karaf-feature-maven-plugin/src/main/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleNameMojo.java b/tooling/camel-karaf-feature-maven-plugin/src/main/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleNameMojo.java
new file mode 100644
index 000000000..714e42d21
--- /dev/null
+++ b/tooling/camel-karaf-feature-maven-plugin/src/main/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleNameMojo.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.karaf.feature.maven;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.karaf.features.internal.model.Bundle;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+
+@Mojo(name = "ensure-wrap-bundle-name", defaultPhase = LifecyclePhase.PROCESS_RESOURCES)
+public class EnsureWrapBundleNameMojo extends AbstractWrapBundleMojo {
+
+ private static final List<String> HEADERS_AFTER_BUNDLE_NAME = Arrays.asList(
+ "Bundle-Version",
+ "DynamicImport-Package",
+ "Export-Package",
+ "Export-Service",
+ "Fragment-Host",
+ "Import-Package",
+ "Import-Service",
+ "Provide-Capability",
+ "Require-Bundle",
+ "Require-Capability");
+
+ private static final String BUNDLE_NAME = "Bundle-Name";
+ private static final String BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
+
+ private static String toPascalCase(String kebabCase) {
+ // Handle null or empty string
+ if (kebabCase == null || kebabCase.isEmpty()) {
+ return kebabCase;
+ }
+
+ // Split by hyphen
+ String[] words = kebabCase.split("-");
+ StringBuilder result = new StringBuilder();
+
+ // Capitalize first letter of each word
+ for (int i = 0; i < words.length; i++) {
+ String word = words[i];
+ if (word.isEmpty()) {
+ continue;
+ }
+ result.append(Character.toUpperCase(word.charAt(0)));
+ if (word.length() > 1) {
+ result.append(word.substring(1).toLowerCase());
+ }
+ // Only add %20 if it's not the last word
+ if (i < words.length - 1) {
+ result.append("%20");
+ }
+ }
+ return result.toString();
+ }
+
+ @Override
+ protected boolean processWrappedBundle(WrappedBundle wrappedBundle) {
+ Bundle bundle = wrappedBundle.getBundle();
+ String location = bundle.getLocation();
+ try {
+ bundle.setLocation(processLocation(wrappedBundle));
+ } catch (Exception e) {
+ getLog().error("Could not process the Bundle location '%s': %s".formatted(location, e.getMessage()), e);
+ }
+ return false;
+ }
+
+ String processLocation(WrappedBundle wrappedBundle) throws Exception {
+ String location = wrappedBundle.getBundle().getLocation();
+ String instructions = wrappedBundle.getInstructions();
+ boolean dollarNeeded = instructions == null || !instructions.contains("$");
+
+ String bundleNameHeader = "%s=Wrap%%20of%%20%s".formatted(BUNDLE_NAME, toPascalCase(wrappedBundle.getArtifactId()));
+ String bundleSymbolicNameHeader = "%s=wrap_%s.%s".formatted(BUNDLE_SYMBOLIC_NAME, wrappedBundle.getGroupId(), wrappedBundle.getArtifactId());
+ Map<String, String> headers = new TreeMap<>(); //sorted by key
+ headers.put(BUNDLE_NAME, bundleNameHeader);
+ headers.put(BUNDLE_SYMBOLIC_NAME, bundleSymbolicNameHeader);
+
+ return insertHeaderIfNeeded(dollarNeeded, location, headers);
+ }
+
+
+ private String insertHeaderIfNeeded(boolean dollarNeeded, String location, Map<String, String> headers) {
+
+ StringBuilder sb = new StringBuilder(location);
+ for (Map.Entry<String, String> entry : headers.entrySet()) {
+ if (location.contains(entry.getKey())) {
+ continue;
+ }
+ boolean hasChanged = false;
+ // insert before existing headers header
+ for (String header : HEADERS_AFTER_BUNDLE_NAME) {
+ // add Bundle-Version before
+ if (location.contains(header)) {
+ int versionHeaderStartIndex = location.indexOf(header);
+ if (dollarNeeded) {
+ // "amp;" is automatically added
+ dollarNeeded = false;
+ location = sb.insert(versionHeaderStartIndex, "$%s&".formatted(entry.getValue())).toString();
+ } else {
+ // "amp;" is automatically added
+ location = sb.insert(versionHeaderStartIndex, "%s&".formatted(entry.getValue())).toString();
+ }
+ hasChanged = true;
+ break;
+ }
+ }
+ if (hasChanged) {
+ //header already handled, go to next
+ continue;
+ }
+
+ // insert at the end
+ if (dollarNeeded) {
+ dollarNeeded = false;
+ location = sb.insert(location.length(), "$%s".formatted(entry.getValue())).toString();
+ } else {
+ // "amp;" is automatically added
+ location = sb.insert(location.length(), "&%s".formatted(entry.getValue())).toString();
+ }
+ }
+ return location;
+ }
+}
\ No newline at end of file
diff --git a/tooling/camel-karaf-feature-maven-plugin/src/test/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleNameMojoTest.java b/tooling/camel-karaf-feature-maven-plugin/src/test/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleNameMojoTest.java
new file mode 100644
index 000000000..2e9730af3
--- /dev/null
+++ b/tooling/camel-karaf-feature-maven-plugin/src/test/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleNameMojoTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.karaf.feature.maven;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.apache.karaf.features.internal.model.Bundle;
+import org.junit.jupiter.api.Test;
+
+public class EnsureWrapBundleNameMojoTest {
+
+ private final EnsureWrapBundleNameMojo ensureNameMojo = new EnsureWrapBundleNameMojo();
+
+ @Test
+ void modifyLocationTest() throws Exception {
+ Bundle bundle = new Bundle();
+ // add bundle name at the end as first wrap protocol option
+ bundle.setLocation("wrap:mvn:org.apache.olingo/odata-server-core/5.0.0");
+ String expected = "wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-Name=Wrap%20of%20Odata%20Server%20Core&Bundle-SymbolicName=wrap_org.apache.olingo.odata-server-core";
+ WrappedBundle wrappedBundle = WrappedBundle.fromBundle(bundle);
+ assertNotNull(wrappedBundle);
+ assertEquals(expected, ensureNameMojo.processLocation(wrappedBundle));
+
+ // add bundle name at the end but not as first wrap protocol option
+ bundle.setLocation("wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge");
+ expected = "wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge&Bundle-Name=Wrap%20of%20Odata%20Server%20Core&Bundle-SymbolicName=wrap_org.apache.olingo.odata-server-core";
+ wrappedBundle = WrappedBundle.fromBundle(bundle);
+ assertNotNull(wrappedBundle);
+ assertEquals(expected, ensureNameMojo.processLocation(wrappedBundle));
+
+ // add bundle name before existing wrap protocol header that should be declared after
+ bundle.setLocation("wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge&Export-Package=org.apache.olingo.*;version=5.0.0");
+ expected = "wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge&Bundle-Name=Wrap%20of%20Odata%20Server%20Core&Bundle-SymbolicName=wrap_org.apache.olingo.odata-server-core&Export-Package=org.apache.olingo.*;version=5.0.0";
+ wrappedBundle = WrappedBundle.fromBundle(bundle);
+ assertNotNull(wrappedBundle);
+ assertEquals(expected, ensureNameMojo.processLocation(wrappedBundle));
+
+ // add bundle name before existing wrap protocol header that should be declared after
+ bundle.setLocation("wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge&Bundle-Version=5.0.0&Export-Package=org.apache.olingo.*;version=5.0.0");
+ expected = "wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge&Bundle-Name=Wrap%20of%20Odata%20Server%20Core&Bundle-SymbolicName=wrap_org.apache.olingo.odata-server-core&Bundle-Version=5.0.0&Export-Package=org.apache.olingo.*;version=5.0.0";
+ wrappedBundle = WrappedBundle.fromBundle(bundle);
+ assertNotNull(wrappedBundle);
+ assertEquals(expected, ensureNameMojo.processLocation(wrappedBundle));
+
+ // don't override the Bundle-Name if present
+ bundle.setLocation("wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-Name=MyName");
+ expected = "wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-Name=MyName&Bundle-SymbolicName=wrap_org.apache.olingo.odata-server-core";
+ wrappedBundle = WrappedBundle.fromBundle(bundle);
+ assertNotNull(wrappedBundle);
+ assertEquals(expected, ensureNameMojo.processLocation(wrappedBundle));
+
+ // don't override the Bundle-SymbolicName if present
+ bundle.setLocation("wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-SymbolicName=MyName");
+ expected = "wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-SymbolicName=MyName&Bundle-Name=Wrap%20of%20Odata%20Server%20Core";
+ wrappedBundle = WrappedBundle.fromBundle(bundle);
+ assertNotNull(wrappedBundle);
+ assertEquals(expected, ensureNameMojo.processLocation(wrappedBundle));
+
+ }
+
+
+}
\ No newline at end of file