Applied patch (FELIX-32) to implement getAllServiceReferences() method.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@501123 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index 35baeca..93357a6 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -356,59 +356,8 @@
{
checkValidity();
- // TODO: Implement BundleContext.getAllServiceReferences()
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ServiceReference[] refs = null;
-
- if (refs == null)
- {
- return refs;
- }
-
- List result = new ArrayList();
-
- for (int i = 0;i < refs.length;i++)
- {
- String[] objectClass = (String[]) refs[i].getProperty(
- Constants.OBJECTCLASS);
-
- if (objectClass == null)
- {
- continue;
- }
-
- for (int j = 0;j < objectClass.length;j++)
- {
- try
- {
- ((SecurityManager) sm).checkPermission(new ServicePermission(
- objectClass[j], ServicePermission.GET));
-
- result.add(refs[i]);
-
- break;
- }
- catch (Exception e)
- {
-
- }
- }
- }
-
- if (result.isEmpty())
- {
- return null;
- }
-
- return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
- }
- else
- {
- return null;
- }
+ return m_felix.getAllowedServiceReferences(m_bundle, clazz, filter, false);
+
}
public ServiceReference[] getServiceReferences(String clazz, String filter)
@@ -416,58 +365,8 @@
{
checkValidity();
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ServiceReference[] refs = m_felix.getServiceReferences(m_bundle, clazz, filter);
-
- if (refs == null)
- {
- return refs;
- }
-
- List result = new ArrayList();
-
- for (int i = 0;i < refs.length;i++)
- {
- String[] objectClass = (String[]) refs[i].getProperty(
- Constants.OBJECTCLASS);
-
- if (objectClass == null)
- {
- continue;
- }
-
- for (int j = 0;j < objectClass.length;j++)
- {
- try
- {
- ((SecurityManager) sm).checkPermission(new ServicePermission(
- objectClass[j], ServicePermission.GET));
-
- result.add(refs[i]);
-
- break;
- }
- catch (Exception e)
- {
-
- }
- }
- }
-
- if (result.isEmpty())
- {
- return null;
- }
-
- return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
- }
- else
- {
- return m_felix.getServiceReferences(m_bundle, clazz, filter);
- }
+ return m_felix.getAllowedServiceReferences(m_bundle, clazz, filter, true);
+
}
public Object getService(ServiceReference ref)
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 063a815..104a7ae 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -504,7 +504,7 @@
{
StartLevel sl = (StartLevel) getService(
getBundle(0),
- getServiceReferences((BundleImpl) getBundle(0), StartLevel.class.getName(), null)[0]);
+ getServiceReferences((BundleImpl) getBundle(0), StartLevel.class.getName(), null, true)[0]);
if (sl instanceof StartLevelImpl)
{
((StartLevelImpl) sl).setStartLevelAndWait(startLevel);
@@ -586,7 +586,7 @@
{
StartLevelImpl sl = (StartLevelImpl) getService(
getBundle(0),
- getServiceReferences((BundleImpl) getBundle(0), StartLevel.class.getName(), null)[0]);
+ getServiceReferences((BundleImpl) getBundle(0), StartLevel.class.getName(), null, true)[0]);
sl.setStartLevelAndWait(0);
}
catch (InvalidSyntaxException ex)
@@ -2263,8 +2263,18 @@
return reg;
}
+ /**
+ * Retrieves an array of {@link ServiceReference} objects based on calling bundle,
+ * service class name, and filter expression. Optionally checks for isAssignable to
+ * make sure that the service can be cast to the
+ * @param bundle Calling Bundle
+ * @param className Service Classname or <code>null</code> for all
+ * @param expr Filter Criteria or <code>null</code>
+ * @return Array of ServiceReference objects that meet the criteria
+ * @throws InvalidSyntaxException
+ */
protected ServiceReference[] getServiceReferences(
- BundleImpl bundle, String className, String expr)
+ BundleImpl bundle, String className, String expr, boolean checkAssignable)
throws InvalidSyntaxException
{
// Define filter if expression is not null.
@@ -2277,23 +2287,20 @@
// Ask the service registry for all matching service references.
List refList = m_registry.getServiceReferences(className, filter);
- // The returned reference list must be filtered for two cases:
- // 1) The requesting bundle may not be wired to the same class
- // as the providing bundle (i.e, different versions), so filter
- // any services for which the requesting bundle might get a
- // class cast exception.
- // 2) Security is enabled and the requesting bundle does not have
- // permission access the service.
- for (int refIdx = 0; (refList != null) && (refIdx < refList.size()); refIdx++)
+ // Filter on assignable references
+ if (checkAssignable)
{
- // Get the current service reference.
- ServiceReference ref = (ServiceReference) refList.get(refIdx);
-
- // Now check for castability.
- if (!Felix.isServiceAssignable(bundle, ref))
+ for (int refIdx = 0; (refList != null) && (refIdx < refList.size()); refIdx++)
{
- refList.remove(refIdx);
- refIdx--;
+ // Get the current service reference.
+ ServiceReference ref = (ServiceReference) refList.get(refIdx);
+
+ // Now check for castability.
+ if (!Felix.isServiceAssignable(bundle, ref))
+ {
+ refList.remove(refIdx);
+ refIdx--;
+ }
}
}
@@ -2306,6 +2313,67 @@
}
/**
+ * Retrieves Array of {@link ServiceReference} objects based on calling bundle, service class name,
+ * optional filter expression, and optionally filters further on the version.
+ * If running under a {@link SecurityManager}, checks that the calling bundle has permissions to
+ * see the service references and removes references that aren't.
+ * @param bundle Calling Bundle
+ * @param className Service Classname or <code>null</code> for all
+ * @param expr Filter Criteria or <code>null</code>
+ * @param checkAssignable <code>true</code> to check for isAssignable, <code>false</code> to return all versions
+ * @return Array of ServiceReference objects that meet the criteria
+ * @throws InvalidSyntaxException
+ */
+ protected ServiceReference[] getAllowedServiceReferences(
+ BundleImpl bundle, String className, String expr, boolean checkAssignable)
+ throws InvalidSyntaxException
+ {
+ ServiceReference[] refs = getServiceReferences(bundle, className, expr, checkAssignable);
+
+ Object sm = System.getSecurityManager();
+
+ if (sm == null)
+ {
+ return refs;
+ }
+
+ List result = new ArrayList();
+
+ for (int i = 0;i < refs.length;i++)
+ {
+ String[] objectClass = (String[]) refs[i].getProperty(Constants.OBJECTCLASS);
+
+ if (objectClass == null)
+ {
+ continue;
+ }
+
+ for (int j = 0; j < objectClass.length; j++)
+ {
+ try
+ {
+ ((SecurityManager) sm).checkPermission(new ServicePermission(
+ objectClass[j], ServicePermission.GET));
+ result.add(refs[i]);
+ break;
+ }
+ catch (Exception ex)
+ {
+ // Ignore, since we are just testing permission.
+ }
+ }
+ }
+
+ if (result.isEmpty())
+ {
+ return null;
+ }
+
+ return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
+
+ }
+
+ /**
* This method determines if the requesting bundle is able to cast
* the specified service reference based on class visibility rules
* of the underlying modules.