This is an automated email from the ASF dual-hosted git repository.

amichai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/aries-rsa.git

commit 6d3d2cda69206e44dec7fa4ca0d1b19bb3400b10
Author: Amichai Rothman <[email protected]>
AuthorDate: Mon Jun 3 14:04:11 2024 +0300

    ARIES-2157 Replace deprecated PackageAdmin usage with BundleWiring
---
 .../rsa/core/DistributionProviderTracker.java      |  4 +-
 .../org/apache/aries/rsa/core/PackageUtil.java     | 70 +++++++++-------------
 .../aries/rsa/core/RemoteServiceAdminCore.java     |  8 +--
 .../aries/rsa/core/RemoteServiceAdminCoreTest.java | 33 +++++++---
 4 files changed, 57 insertions(+), 58 deletions(-)

diff --git 
a/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java 
b/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java
index e1c948e5..12505e02 100644
--- 
a/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java
+++ 
b/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java
@@ -54,13 +54,11 @@ public class DistributionProviderTracker extends 
ServiceTracker<DistributionProv
         }
         LOG.debug("RemoteServiceAdmin Implementation is starting up");
         BundleContext apiContext = getAPIContext();
-        PackageUtil packageUtil = new PackageUtil(context);
         EventProducer eventProducer = new EventProducer(context);
         RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(context,
                                                                     apiContext,
                                                                     
eventProducer,
-                                                                    provider,
-                                                                    
packageUtil);
+                                                                    provider);
         RemoteServiceAdminFactory rsaf = new 
RemoteServiceAdminFactory(rsaCore);
         Dictionary<String, Object> props = new Hashtable<>();
         props.put(REMOTE_INTENTS_SUPPORTED, getPropertyNullSafe(reference, 
REMOTE_INTENTS_SUPPORTED));
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java 
b/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java
index 1b03825a..f83278e1 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java
@@ -18,65 +18,51 @@
  */
 package org.apache.aries.rsa.core;
 
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.packageadmin.ExportedPackage;
-import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.framework.*;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleWiring;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings("deprecation")
+import java.util.List;
+import java.util.function.Function;
+
+/**
+ * Utility methods for obtaining package metadata.
+ */
 public class PackageUtil {
 
     public static final Logger LOG = 
LoggerFactory.getLogger(PackageUtil.class);
-    private BundleContext bc;
 
-    public PackageUtil(BundleContext bc) {
-        this.bc = bc;
-    }
+    protected static Function<Class<?>, Bundle> BUNDLE_FINDER = 
FrameworkUtil::getBundle;
 
     /**
-     * Tries to retrieve the version of iClass via the PackageAdmin.
+     * Tries to retrieve the version of iClass via its bundle exported 
packages metadata.
      *
      * @param iClass tThe interface for which the version should be found
      * @return the version of the interface or "0.0.0" if no version 
information could be found or an error
      *         occurred during the retrieval
      */
-    public String getVersion(Class<?> iClass) {
-        ServiceReference<PackageAdmin> paRef = 
bc.getServiceReference(PackageAdmin.class);
-        if (paRef != null) {
-            PackageAdmin pa = bc.getService(paRef);
-            try {
-                Bundle b = pa.getBundle(iClass);
-                if (b == null) {
-                    LOG.info("Unable to find interface version for interface 
{}. Falling back to 0.0.0",
-                        iClass.getName());
-                    return "0.0.0";
-                }
-                LOG.debug("Interface source bundle: {}", b.getSymbolicName());
-
-                ExportedPackage[] ep = pa.getExportedPackages(b);
-                LOG.debug("Exported Packages of the source bundle: {}", 
(Object)ep);
-
-                String pack = iClass.getPackage().getName();
-                LOG.debug("Looking for Package: {}", pack);
-                if (ep != null) {
-                    for (ExportedPackage p : ep) {
-                        if (p != null
-                            && pack.equals(p.getName())) {
-                            LOG.debug("found package -> Version: {}", 
p.getVersion());
-                            return p.getVersion().toString();
-                        }
+    public static String getVersion(Class<?> iClass) {
+        Bundle bundle = BUNDLE_FINDER.apply(iClass);
+        if (bundle != null) {
+            BundleWiring wiring = bundle.adapt(BundleWiring.class);
+            List<BundleCapability> capabilities = 
wiring.getCapabilities(PackageNamespace.PACKAGE_NAMESPACE);
+            LOG.debug("Interface {} found in bundle {} with exports {}", 
iClass.getName(), bundle.getSymbolicName(), capabilities);
+            if (capabilities != null) {
+                String iPackage = iClass.getPackage().getName();
+                LOG.debug("Looking for exported package: {}", iPackage);
+                for (BundleCapability cap : capabilities) {
+                    String capPackage = 
(String)cap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
+                    if (iPackage.equals(capPackage)) {
+                        Version version = 
(Version)cap.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+                        LOG.debug("found package {} version {}", iPackage, 
version);
+                        if (version != null)
+                            return version.toString();
                     }
                 }
-            } finally {
-                if (pa != null) {
-                    bc.ungetService(paRef);
-                }
             }
-        } else {
-            LOG.error("Was unable to obtain the package admin service -> can't 
resolve interface versions");
         }
 
         LOG.info("Unable to find interface version for interface {}. Falling 
back to 0.0.0", iClass.getName());
diff --git 
a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java 
b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
index de1953c4..9fd7d86d 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
@@ -71,19 +71,16 @@ public class RemoteServiceAdminCore implements 
RemoteServiceAdmin {
     private ServiceListener exportedServiceListener;
     private DistributionProvider provider;
     private BundleContext apictx;
-    private PackageUtil packageUtil;
     private CloseHandler closeHandler;
 
     public RemoteServiceAdminCore(BundleContext context,
             BundleContext apiContext,
             EventProducer eventProducer,
-            DistributionProvider provider,
-            PackageUtil packageUtil) {
+            DistributionProvider provider) {
         this.bctx = context;
         this.apictx = apiContext;
         this.eventProducer = eventProducer;
         this.provider = provider;
-        this.packageUtil = packageUtil;
         this.closeHandler = new CloseHandler() {
             public void onClose(ExportRegistration exportReg) {
                 removeExportRegistration(exportReg);
@@ -682,7 +679,8 @@ public class RemoteServiceAdminCore implements 
RemoteServiceAdmin {
         props.put(RemoteConstants.ENDPOINT_FRAMEWORK_UUID, frameworkUUID);
         for (Class<?> iface : ifaces) {
             String pkg = iface.getPackage().getName();
-            props.put(RemoteConstants.ENDPOINT_PACKAGE_VERSION_ + pkg, 
packageUtil.getVersion(iface));
+            String version = PackageUtil.getVersion(iface);
+            props.put(RemoteConstants.ENDPOINT_PACKAGE_VERSION_ + pkg, 
version);
         }
         return props;
     }
diff --git 
a/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java 
b/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
index 45fe9a0b..aff96b8a 100644
--- 
a/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
+++ 
b/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
@@ -55,6 +55,9 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.Version;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.service.remoteserviceadmin.EndpointDescription;
 import org.osgi.service.remoteserviceadmin.ExportReference;
 import org.osgi.service.remoteserviceadmin.ExportRegistration;
@@ -80,24 +83,38 @@ public class RemoteServiceAdminCoreTest {
         
expect(rsaContext.getProperty(Constants.FRAMEWORK_UUID)).andReturn("some_uuid1").anyTimes();
 
         expect(rsaContext.getBundle()).andReturn(b).anyTimes();
+
+        mockExportingBundle(c, "mybundle", String.class, "1.2.3");
+
         apiContext = c.createMock(BundleContext.class);
         provider = new DummyProvider();
-        PackageUtil packageUtil = new PackageUtil(rsaContext) {
-            @Override
-            public String getVersion(Class<?> iClass) {
-                return "1.0.0";
-            }
-        };
         EventProducer eventProducer = new EventProducer(rsaContext) {
             protected void 
notifyListeners(org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent 
rsae) {
                 // skip
             }
         };
-        rsaCore = new RemoteServiceAdminCore(rsaContext, apiContext, 
eventProducer, provider, packageUtil) {
+        rsaCore = new RemoteServiceAdminCore(rsaContext, apiContext, 
eventProducer, provider) {
             protected void createServiceListener() {}
         };
     }
 
+    private void mockExportingBundle(IMocksControl c, String symbolicName, 
Class<String> iClass, String version) {
+        Map<String, Object> capAttributes = new HashMap<>();
+        capAttributes.put(PackageNamespace.PACKAGE_NAMESPACE, 
iClass.getPackage().getName());
+        capAttributes.put(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, new 
Version(version));
+
+        BundleCapability cap = c.createMock(BundleCapability.class);
+        expect(cap.getAttributes()).andStubReturn(capAttributes);
+
+        BundleWiring wiring = c.createMock(BundleWiring.class);
+        
expect(wiring.getCapabilities(PackageNamespace.PACKAGE_NAMESPACE)).andStubReturn(Arrays.asList(cap));
+
+        Bundle b = c.createMock(Bundle.class);
+        expect(b.getSymbolicName()).andStubReturn(symbolicName);
+        expect(b.adapt(BundleWiring.class)).andStubReturn(wiring);
+        PackageUtil.BUNDLE_FINDER = cls -> b;
+    }
+
     @Test
     public void testDontExportOwnServiceProxies() throws 
InvalidSyntaxException {
         Map<String, Object> sProps = new HashMap<>();
@@ -318,7 +335,7 @@ public class RemoteServiceAdminCoreTest {
         assertEquals("some_uuid1", 
props.get(RemoteConstants.ENDPOINT_FRAMEWORK_UUID));
         assertEquals(Arrays.asList("java.lang.String"),
             Arrays.asList((Object[]) 
props.get(org.osgi.framework.Constants.OBJECTCLASS)));
-        assertEquals("1.0.0", props.get("endpoint.package.version.java.lang"));
+        assertEquals("1.2.3", props.get("endpoint.package.version.java.lang"));
         c.verify();
     }
 

Reply via email to