You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:25:32 UTC
[sling-org-apache-sling-commons-osgi] 06/19: SLING-5379 - support
renaming of bundles in maven-slingstart-plugin. Contributed by David
Bosschaert, thanks!
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.commons.osgi-2.4.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-osgi.git
commit 63162f5e1c383d93e099cce6b4d0a4845c852913
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Mon Dec 21 15:11:26 2015 +0000
SLING-5379 - support renaming of bundles in maven-slingstart-plugin. Contributed by David Bosschaert, thanks!
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/osgi@1721185 13f79535-47bb-0310-9956-ffa450edef68
---
pom.xml | 3 +-
.../org/apache/sling/commons/osgi/BundleUtil.java | 103 ++++++++++++++++
.../apache/sling/commons/osgi/package-info.java | 2 +-
.../apache/sling/commons/osgi/BundleUtilTest.java | 133 +++++++++++++++++++++
4 files changed, 239 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index 9d92362..35beb9d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
</parent>
<artifactId>org.apache.sling.commons.osgi</artifactId>
- <version>2.3.1-SNAPSHOT</version>
+ <version>2.3.1-SNAPSHOT</version> <!-- next release version should be 2.4 given new BundleUtil -->
<packaging>bundle</packaging>
<name>Apache Sling Commons OSGi support</name>
@@ -41,6 +41,7 @@
</scm>
<properties>
+ <sling.java.version>7</sling.java.version>
<test.jars.folder>${project.build.directory}/testjars</test.jars.folder>
</properties>
diff --git a/src/main/java/org/apache/sling/commons/osgi/BundleUtil.java b/src/main/java/org/apache/sling/commons/osgi/BundleUtil.java
new file mode 100644
index 0000000..a1bcd95
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/osgi/BundleUtil.java
@@ -0,0 +1,103 @@
+/*
+ * 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.sling.commons.osgi;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+/**
+ * The <code>BundleUtil</code> is a utility class providing some
+ * useful utility methods for bundle handling.
+ * @since 2.4
+ */
+public class BundleUtil {
+ /**
+ * Creates a new OSGi Bundle from a given bundle with the only difference that the
+ * symbolic name is changed. The original symbolic name is recorded in the Manifest
+ * using the {@code X-Original-Bundle-SymbolicName} header.
+ * @param bundleFile The original bundle file. This file will not be modified.
+ * @param newBSN The new Bundle-SymbolicName
+ * @param tempDir The temporary directory to use. This is where the new bundle will be
+ * written. This directory must exist.
+ * @return The new bundle with the altered Symbolic Name.
+ * @throws IOException If something goes wrong reading or writing.
+ */
+ public static File renameBSN(File bundleFile, String newBSN, File tempDir) throws IOException {
+ try (JarInputStream jis = new JarInputStream(new FileInputStream(bundleFile))) {
+ Manifest inputMF = jis.getManifest();
+
+ Attributes inputAttrs = inputMF.getMainAttributes();
+ String bver = inputAttrs.getValue("Bundle-Version");
+ String orgBSN = inputAttrs.getValue("Bundle-SymbolicName");
+ if (bver == null)
+ bver = "0.0.0";
+
+ File newBundle = new File(tempDir, newBSN + "-" + bver + ".jar");
+
+ Manifest newMF = new Manifest(inputMF);
+ Attributes outputAttrs = newMF.getMainAttributes();
+ outputAttrs.putValue("Bundle-SymbolicName", newBSN);
+ outputAttrs.putValue("X-Original-Bundle-SymbolicName", orgBSN);
+
+ try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(newBundle), newMF)) {
+ JarEntry je = null;
+ while ((je = jis.getNextJarEntry()) != null) {
+ try {
+ jos.putNextEntry(je);
+ if (!je.isDirectory())
+ pumpStream(jis, jos);
+ } finally {
+ jos.closeEntry();
+ jis.closeEntry();;
+ }
+ }
+ }
+
+ return newBundle;
+ }
+ }
+
+ static void pumpStream(InputStream is, OutputStream os) throws IOException {
+ byte[] bytes = new byte[65536];
+
+ int length = 0;
+ int offset = 0;
+
+ while ((length = is.read(bytes, offset, bytes.length - offset)) != -1) {
+ offset += length;
+
+ if (offset == bytes.length) {
+ os.write(bytes, 0, bytes.length);
+ offset = 0;
+ }
+ }
+ if (offset != 0) {
+ os.write(bytes, 0, offset);
+ }
+ }
+}
diff --git a/src/main/java/org/apache/sling/commons/osgi/package-info.java b/src/main/java/org/apache/sling/commons/osgi/package-info.java
index 243300d..1d589bd 100644
--- a/src/main/java/org/apache/sling/commons/osgi/package-info.java
+++ b/src/main/java/org/apache/sling/commons/osgi/package-info.java
@@ -16,5 +16,5 @@
* specific language governing permissions and limitations
* under the License.
*/
-@aQute.bnd.annotation.Version("2.3")
+@aQute.bnd.annotation.Version("2.4")
package org.apache.sling.commons.osgi;
diff --git a/src/test/java/org/apache/sling/commons/osgi/BundleUtilTest.java b/src/test/java/org/apache/sling/commons/osgi/BundleUtilTest.java
new file mode 100644
index 0000000..9e0fa5c
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/osgi/BundleUtilTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.sling.commons.osgi;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class BundleUtilTest {
+ @Test
+ public void testBSNRenaming() throws IOException {
+ File tempDir = new File(System.getProperty("java.io.tmpdir"));
+
+ // Just take any bundle from the maven deps as an example...
+ File originalFile = getMavenArtifactFile(getMavenRepoRoot(), "com.google.guava", "guava", "15.0");
+
+ File generatedFile = BundleUtil.renameBSN(originalFile, "org.acme.baklava.guava", tempDir);
+
+ try {
+ compareJarContents(originalFile, generatedFile);
+
+ try (JarFile jfOrg = new JarFile(originalFile);
+ JarFile jfNew = new JarFile(generatedFile)) {
+ Manifest mfOrg = jfOrg.getManifest();
+ Manifest mfNew = jfNew.getManifest();
+
+ Attributes orgAttrs = mfOrg.getMainAttributes();
+ Attributes newAttrs = mfNew.getMainAttributes();
+ for (Object key : orgAttrs.keySet()) {
+ String orgVal = orgAttrs.getValue(key.toString());
+ String newVal = newAttrs.getValue(key.toString());
+
+ if ("Bundle-SymbolicName".equals(key.toString())) {
+ assertEquals("Should have recorded the original Bundle-SymbolicName",
+ orgVal, newAttrs.getValue("X-Original-Bundle-SymbolicName"));
+
+ assertEquals("org.acme.baklava.guava", newVal);
+ } else {
+ assertEquals("Different keys: " + key, orgVal, newVal);
+ }
+ }
+ }
+
+ } finally {
+ assertTrue("Unable to delete temporary file", generatedFile.delete());
+ }
+ }
+
+ private static void compareJarContents(File orgJar, File actualJar) throws IOException {
+ try (JarInputStream jis1 = new JarInputStream(new FileInputStream(orgJar));
+ JarInputStream jis2 = new JarInputStream(new FileInputStream(actualJar))) {
+ JarEntry je1 = null;
+ while ((je1 = jis1.getNextJarEntry()) != null) {
+ if (je1.isDirectory())
+ continue;
+
+ JarEntry je2 = null;
+ while((je2 = jis2.getNextJarEntry()) != null) {
+ if (!je2.isDirectory())
+ break;
+ }
+
+ assertEquals(je1.getName(), je2.getName());
+ assertEquals(je1.getSize(), je2.getSize());
+
+ try {
+ byte[] buf1 = streamToByteArray(jis1);
+ byte[] buf2 = streamToByteArray(jis2);
+
+ assertArrayEquals("Contents not equal: " + je1.getName(), buf1, buf2);
+ } finally {
+ jis1.closeEntry();
+ jis2.closeEntry();
+ }
+ }
+ }
+ }
+
+ private static byte [] streamToByteArray(InputStream is) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ BundleUtil.pumpStream(is, baos);
+ return baos.toByteArray();
+ }
+
+ private static File getMavenArtifactFile(File repoRoot, String gid, String aid, String ver) {
+ return new File(repoRoot, gid.replace('.', '/') + '/' + aid + '/' + ver + '/' + aid + '-' + ver + ".jar");
+ }
+
+ private static File getMavenRepoRoot() throws IOException {
+ URL res = BundleUtilTest.class.getClassLoader().getResource(
+ Test.class.getName().replace('.', '/') + ".class");
+
+ String u = res.toExternalForm();
+ if (u.startsWith("jar:"))
+ u = u.substring(4);
+
+ int idx = u.indexOf("junit");
+ if (idx < 0)
+ throw new IllegalStateException("Cannot infer maven repo root: " + res);
+
+ return new File(new URL(u.substring(0, idx)).getFile());
+ }
+}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.