Fix FELIX-4106
Defensive service registration and update
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1489947 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
index 862eb9a..99a2ebe 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
@@ -22,6 +22,7 @@
import org.apache.felix.ipojo.architecture.PropertyDescription;
import org.apache.felix.ipojo.extender.internal.Extender;
import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Log;
import org.apache.felix.ipojo.util.Logger;
import org.apache.felix.ipojo.util.SecurityHelper;
import org.osgi.framework.BundleContext;
@@ -586,7 +587,7 @@
* Destroys the factory.
* The factory cannot be restarted. Only the {@link Extender} can call this method.
*/
- synchronized void dispose() {
+ public synchronized void dispose() {
stop(); // Does not hold the lock.
m_requiredHandlers.clear();
m_listeners = null;
@@ -628,13 +629,17 @@
}
BundleContext bc = SecurityHelper.selectContextToRegisterServices(m_componentDesc.getFactoryInterfacesToPublish(),
m_context, getIPOJOBundleContext());
- m_sr =
- bc.registerService(m_componentDesc.getFactoryInterfacesToPublish(), this, m_componentDesc
- .getPropertiesToPublish());
+ if (SecurityHelper.canRegisterService(bc)) {
+ m_sr =
+ bc.registerService(m_componentDesc.getFactoryInterfacesToPublish(), this, m_componentDesc
+ .getPropertiesToPublish());
+ m_logger.log(Logger.INFO, "Factory " + m_factoryName + " started");
+ } else {
+ m_logger.log(Log.ERROR, "Cannot register the Factory service with the bundle context of the bundle "
+ + bc.getBundle().getBundleId() + " - the bundle is in the state " + bc.getBundle().getState()
+ );
+ }
}
-
- m_logger.log(Logger.INFO, "Factory " + m_factoryName + " started");
-
}
/**
@@ -777,7 +782,9 @@
m_state = VALID;
if (m_sr != null) {
- m_sr.setProperties(m_componentDesc.getPropertiesToPublish());
+ if (SecurityHelper.canUpdateService(m_sr)) {
+ m_sr.setProperties(m_componentDesc.getPropertiesToPublish());
+ }
}
// Register the factory on the ConfigurationTracker
@@ -812,7 +819,8 @@
m_componentInstances.clear();
- if (m_sr != null) {
+ if (SecurityHelper.canUpdateService(m_sr)) {
+ // No null check required as the security helper is checking this too.
m_sr.setProperties(m_componentDesc.getPropertiesToPublish());
}
}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/AbstractService.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/AbstractService.java
index 1fa48f0..e4f201a 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/AbstractService.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/AbstractService.java
@@ -33,12 +33,10 @@
* The bundle context.
*/
private final BundleContext m_bundleContext;
-
/**
* The service specification.
*/
private final Class<?> m_type;
-
/**
* The service registration.
*/
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
index e8cce04..4078b87 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
@@ -25,6 +25,7 @@
import org.apache.felix.ipojo.architecture.Architecture;
import org.apache.felix.ipojo.architecture.InstanceDescription;
import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.SecurityHelper;
import org.osgi.framework.ServiceRegistration;
import java.util.Dictionary;
@@ -58,12 +59,16 @@
Dictionary<String, String> dict = new Hashtable<String, String>();
dict.put(ARCHITECTURE_INSTANCE, m_name);
- debug("Registering architecture service for " + m_name);
- m_serviceRegistration = getInstanceManager().getContext().registerService(Architecture.class.getName(), this, dict);
-
- // We can't use the regular handler stateChanged method as this method is not called when the instance is
- // disposed. This handler stays actives until the instance disposal.
- getInstanceManager().addInstanceStateListener(this);
+ if (SecurityHelper.canRegisterService(getInstanceManager().getContext())) {
+ debug("Registering architecture service for " + m_name);
+ m_serviceRegistration = getInstanceManager().getContext().registerService(Architecture.class.getName(), this, dict);
+ // We can't use the regular handler stateChanged method as this method is not called when the instance is
+ // disposed. This handler stays actives until the instance disposal.
+ getInstanceManager().addInstanceStateListener(this);
+ } else {
+ error("Cannot register the architecture service, bundle " + getInstanceManager().getContext().getBundle()
+ .getBundleId() + " is not in a valid state" );
+ }
}
/**
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
index 609bcfc..0dead11 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -358,7 +358,8 @@
// Security Check
if (SecurityHelper.hasPermissionToRegisterService(ManagedService.class.getName(),
- getInstanceManager().getContext())) {
+ getInstanceManager().getContext()) && SecurityHelper.canRegisterService
+ (getInstanceManager().getContext())) {
m_sr = getInstanceManager().getContext().registerService(ManagedService.class.getName(), this, props);
} else {
error("Cannot register the ManagedService - The bundle "
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
index 62d53b2..88e5e84 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
@@ -351,7 +351,7 @@
BundleContext bc = m_handler.getInstanceManager().getContext();
// Security check
if (SecurityHelper.hasPermissionToRegisterServices(
- m_serviceSpecifications, bc)) {
+ m_serviceSpecifications, bc) && SecurityHelper.canRegisterService(bc)) {
serviceProperties = getServiceProperties();
m_strategy.onPublication(getInstanceManager(),
getServiceSpecificationsToRegister(),
@@ -373,7 +373,8 @@
// An update may happen during the registration, re-check and apply.
// This must be call outside the synchronized block.
- if (reg != null && m_wasUpdated) {
+ // If the registration is null, the security helper returns false.
+ if (m_wasUpdated && SecurityHelper.canUpdateService(reg)) {
Properties updated = getServiceProperties();
reg.setProperties((Dictionary) updated);
m_publishedProperties = updated;
@@ -497,22 +498,27 @@
// First check, are the size equals
if (oldProps.size() != newProps.size()) {
- m_handler.info("Updating Registration : " + oldProps.size() + " / " + newProps.size());
- m_publishedProperties = updated;
- m_serviceRegistration.setProperties((Dictionary) updated);
+ if (SecurityHelper.canUpdateService(m_serviceRegistration)) {
+ m_handler.info("Updating Registration : " + oldProps.size() + " / " + newProps.size());
+ m_publishedProperties = updated;
+ m_serviceRegistration.setProperties(updated);
+ }
} else {
// Check changes
Enumeration keys = oldProps.keys();
- while (keys.hasMoreElements()) {
+ boolean hasChanged = false;
+ while (! hasChanged && keys.hasMoreElements()) {
String k = (String) keys.nextElement();
Object val = oldProps.get(k);
if (! val.equals(updated.get(k))) {
- m_handler.info("Updating Registration : " + k);
- m_publishedProperties = updated;
- m_serviceRegistration.setProperties((Dictionary) updated);
- return;
+ hasChanged = true;
}
}
+ if (hasChanged && SecurityHelper.canUpdateService(m_serviceRegistration)) {
+ m_handler.info("Updating Registration : " + updated);
+ m_publishedProperties = updated;
+ m_serviceRegistration.setProperties(updated);
+ }
}
} else {
// Need to be updated later.
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
index ddea97b..a0131d8 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
@@ -19,11 +19,7 @@
package org.apache.felix.ipojo.handlers.providedservice;
import java.lang.reflect.Field;
-import java.util.Dictionary;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
import org.apache.felix.ipojo.ConfigurationException;
import org.apache.felix.ipojo.HandlerFactory;
@@ -59,7 +55,7 @@
/**
* The list of the provided service.
*/
- private ProvidedService[] m_providedServices = new ProvidedService[0];
+ private Set<ProvidedService> m_providedServices = new LinkedHashSet<ProvidedService>();
/**
* The handler description.
@@ -67,32 +63,11 @@
private ProvidedServiceHandlerDescription m_description;
/**
- * Add a provided service to the list .
- *
- * @param svc : the provided service to add
- */
- private void addProvidedService(ProvidedService svc) {
- // Verify that the provided service is not already in the array.
- for (int i = 0; i < m_providedServices.length; i++) {
- if (m_providedServices[i] == svc) { return; }
- }
-
- if (m_providedServices.length > 0) {
- ProvidedService[] newPS = new ProvidedService[m_providedServices.length + 1];
- System.arraycopy(m_providedServices, 0, newPS, 0, m_providedServices.length);
- newPS[m_providedServices.length] = svc;
- m_providedServices = newPS;
- } else {
- m_providedServices = new ProvidedService[] { svc };
- }
- }
-
- /**
* Get the array of provided service.
* @return the list of the provided service.
*/
public ProvidedService[] getProvidedServices() {
- return m_providedServices;
+ return m_providedServices.toArray(new ProvidedService[m_providedServices.size()]);
}
/**
@@ -100,21 +75,21 @@
* @param componentMetadata : the component type metadata
* @param configuration : the instance configuration
* @throws ConfigurationException : the metadata are not correct.
- * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+ * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
*/
public void configure(Element componentMetadata, Dictionary configuration) throws ConfigurationException {
- m_providedServices = new ProvidedService[0];
+ m_providedServices.clear();
// Create the dependency according to the component metadata
Element[] providedServices = componentMetadata.getElements("Provides");
- for (int i = 0; i < providedServices.length; i++) {
- String[] serviceSpecifications = ParseUtils.parseArrays(providedServices[i].getAttribute("specifications")); // Set by the initialize component factory.
+ for (Element providedService : providedServices) {
+ String[] serviceSpecifications = ParseUtils.parseArrays(providedService.getAttribute("specifications")); // Set by the initialize component factory.
// Get the factory policy
int factory = ProvidedService.SINGLETON_STRATEGY;
Class custom = null;
- String strategy = providedServices[i].getAttribute("strategy");
+ String strategy = providedService.getAttribute("strategy");
if (strategy == null) {
- strategy = providedServices[i].getAttribute("factory");
+ strategy = providedService.getAttribute("factory");
}
if (strategy != null) {
if ("singleton".equalsIgnoreCase(strategy)) {
@@ -129,7 +104,7 @@
// Customized policy
try {
custom = getInstanceManager().getContext().getBundle().loadClass(strategy);
- if (! CreationStrategy.class.isAssignableFrom(custom)) {
+ if (!CreationStrategy.class.isAssignableFrom(custom)) {
throw new ConfigurationException("The custom creation policy class " + custom.getName() + " does not implement " + CreationStrategy.class.getName());
}
} catch (ClassNotFoundException e) {
@@ -145,20 +120,20 @@
ProvidedService svc = new ProvidedService(this, serviceSpecifications, factory, custom, configuration);
// Post-Registration callback
- String post = providedServices[i].getAttribute("post-registration");
+ String post = providedService.getAttribute("post-registration");
if (post != null) {
- Callback cb = new Callback(post, new Class[] {ServiceReference.class}, false, getInstanceManager());
+ Callback cb = new Callback(post, new Class[]{ServiceReference.class}, false, getInstanceManager());
svc.setPostRegistrationCallback(cb);
}
- post = providedServices[i].getAttribute("post-unregistration");
+ post = providedService.getAttribute("post-unregistration");
if (post != null) {
// TODO Can we really send the service reference here ?
- Callback cb = new Callback(post, new Class[] {ServiceReference.class}, false, getInstanceManager());
+ Callback cb = new Callback(post, new Class[]{ServiceReference.class}, false, getInstanceManager());
svc.setPostUnregistrationCallback(cb);
}
- Element[] props = providedServices[i].getElements("Property");
+ Element[] props = providedService.getElements("Property");
if (props != null) {
//Property[] properties = new Property[props.length];
Property[] properties = new Property[props.length];
@@ -188,19 +163,19 @@
svc.setProperties(properties);
}
- Element[] controllers = providedServices[i].getElements("Controller");
+ Element[] controllers = providedService.getElements("Controller");
if (controllers != null) {
- for (int k = 0; k < controllers.length; k++) {
- String field = controllers[k].getAttribute("field");
+ for (Element controller : controllers) {
+ String field = controller.getAttribute("field");
if (field == null) {
throw new ConfigurationException("The field attribute of a controller is mandatory");
}
- String v = controllers[k].getAttribute("value");
- boolean value = ! (v != null && v.equalsIgnoreCase("false"));
- String s = controllers[k].getAttribute("specification");
+ String v = controller.getAttribute("value");
+ boolean value = !(v != null && v.equalsIgnoreCase("false"));
+ String s = controller.getAttribute("specification");
if (s == null) {
- s ="ALL";
+ s = "ALL";
}
svc.setController(field, value, s);
@@ -209,18 +184,18 @@
}
if (checkProvidedService(svc)) {
- addProvidedService(svc);
+ m_providedServices.add(svc);
} else {
- StringBuffer itfs = new StringBuffer();
- for (int j = 0; j < serviceSpecifications.length; j++) {
+ StringBuilder itfs = new StringBuilder();
+ for (String serviceSpecification : serviceSpecifications) {
itfs.append(' ');
- itfs.append(serviceSpecifications[j]);
+ itfs.append(serviceSpecification);
}
throw new ConfigurationException("The provided service" + itfs + " is not valid");
}
// Initialize the description.
- m_description = new ProvidedServiceHandlerDescription(this, m_providedServices);
+ m_description = new ProvidedServiceHandlerDescription(this, getProvidedServices());
}
}
@@ -234,12 +209,14 @@
* @param classes : the set of extended classes
* @throws ClassNotFoundException : occurs when an interface cannot be loaded.
*/
- private void computeInterfacesAndSuperClasses(String[] specs, String parent, Bundle bundle, Set interfaces, Set classes) throws ClassNotFoundException {
+ private void computeInterfacesAndSuperClasses(String[] specs, String parent, Bundle bundle,
+ Set<String> interfaces,
+ Set<String> classes) throws ClassNotFoundException {
// First iterate on found specification in manipulation metadata
- for (int i = 0; i < specs.length; i++) {
- interfaces.add(specs[i]);
+ for (String spec : specs) {
+ interfaces.add(spec);
// Iterate on interfaces implemented by the current interface
- Class clazz = bundle.loadClass(specs[i]);
+ Class clazz = bundle.loadClass(spec);
collectInterfaces(clazz, interfaces, bundle);
}
@@ -259,11 +236,11 @@
* @param bundle : bundle
* @throws ClassNotFoundException : occurs when an interface cannot be loaded.
*/
- private void collectInterfaces(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+ private void collectInterfaces(Class clazz, Set<String> acc, Bundle bundle) throws ClassNotFoundException {
Class[] clazzes = clazz.getInterfaces();
- for (int i = 0; i < clazzes.length; i++) {
- acc.add(clazzes[i].getName());
- collectInterfaces(clazzes[i], acc, bundle);
+ for (Class clazze : clazzes) {
+ acc.add(clazze.getName());
+ collectInterfaces(clazze, acc, bundle);
}
}
@@ -275,11 +252,12 @@
* @param bundle : bundle.
* @throws ClassNotFoundException : occurs if an interface cannot be load.
*/
- private void collectInterfacesFromClass(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+ private void collectInterfacesFromClass(Class clazz, Set<String> acc,
+ Bundle bundle) throws ClassNotFoundException {
Class[] clazzes = clazz.getInterfaces();
- for (int i = 0; i < clazzes.length; i++) {
- acc.add(clazzes[i].getName());
- collectInterfaces(clazzes[i], acc, bundle);
+ for (Class clazze : clazzes) {
+ acc.add(clazze.getName());
+ collectInterfaces(clazze, acc, bundle);
}
// Iterate on parent classes
Class sup = clazz.getSuperclass();
@@ -295,7 +273,8 @@
* @param bundle : bundle.
* @throws ClassNotFoundException : occurs if an interface cannot be load.
*/
- private void collectParentClassesFromClass(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+ private void collectParentClassesFromClass(Class clazz, Set<String> acc,
+ Bundle bundle) throws ClassNotFoundException {
Class parent = clazz.getSuperclass();
if (parent != null) {
acc.add(parent.getName());
@@ -427,17 +406,15 @@
* @param pojo : the pojo object on which the field is accessed
* @param fieldName : field name
* @param value : new value
- * @see org.apache.felix.ipojo.Handler#onSet(Object,
- * java.lang.String, java.lang.Object)
+ * @see org.apache.felix.ipojo.FieldInterceptor#onSet(Object, String, Object)
*/
public void onSet(Object pojo, String fieldName, Object value) {
// Verify that the field name correspond to a dependency
- for (int i = 0; i < m_providedServices.length; i++) {
- ProvidedService svc = m_providedServices[i];
+ for (ProvidedService svc : m_providedServices) {
boolean update = false;
for (int j = 0; j < svc.getProperties().length; j++) {
Property prop = svc.getProperties()[j];
- if (fieldName.equals(prop.getField()) && ! prop.getValue().equals(value)) {
+ if (fieldName.equals(prop.getField()) && !prop.getValue().equals(value)) {
// it is the associated property
prop.setValue(value);
update = true;
@@ -451,7 +428,7 @@
if (value instanceof Boolean) {
ctrl.setValue((Boolean) value);
} else {
- warn("Boolean value expected for the service controler " + fieldName);
+ warn("Boolean value expected for the service controller " + fieldName);
}
}
}
@@ -465,12 +442,10 @@
* @param fieldName : field name
* @param value : value pushed by the previous handler
* @return the stored value or the previous value.
- * @see org.apache.felix.ipojo.Handler#onGet(Object,
- * java.lang.String, java.lang.Object)
+ * @see org.apache.felix.ipojo.FieldInterceptor#onGet(Object, String, Object)
*/
public Object onGet(Object pojo, String fieldName, Object value) {
- for (int i = 0; i < m_providedServices.length; i++) {
- ProvidedService svc = m_providedServices[i];
+ for (ProvidedService svc : m_providedServices) {
for (int j = 0; j < svc.getProperties().length; j++) {
Property prop = svc.getProperties()[j];
if (fieldName.equals(prop.getField())) {
@@ -480,7 +455,7 @@
}
ServiceController ctrl = svc.getController(fieldName);
if (ctrl != null) {
- return new Boolean(ctrl.getValue());
+ return ctrl.getValue();
}
}
// Else it is not a property
@@ -488,27 +463,26 @@
}
/**
- * Register the services if the new state is VALID. Unregister the services
+ * Register the services if the new state is VALID. Un-register the services
* if the new state is UNRESOLVED.
*
* @param state : the new instance state.
* @see org.apache.felix.ipojo.Handler#stateChanged(int)
*/
public void stateChanged(int state) {
- // If the new state is INVALID => unregister all the services
+ // If the new state is INVALID => un-register all the services
if (state == InstanceManager.INVALID) {
- for (int i = 0; i < m_providedServices.length; i++) {
- m_providedServices[i].unregisterService();
+ for (ProvidedService m_providedService : m_providedServices) {
+ m_providedService.unregisterService();
}
return;
}
// If the new state is VALID => register all the services
if (state == InstanceManager.VALID) {
- for (int i = 0; i < m_providedServices.length; i++) {
- m_providedServices[i].registerService();
+ for (ProvidedService ps : m_providedServices) {
+ ps.registerService();
}
- return;
}
}
@@ -517,9 +491,9 @@
* @param dict : dictionary of properties to add
*/
public void addProperties(Dictionary dict) {
- for (int i = 0; i < m_providedServices.length; i++) {
- m_providedServices[i].addProperties(dict);
- m_providedServices[i].update();
+ for (ProvidedService ps : m_providedServices) {
+ ps.addProperties(dict);
+ ps.update();
}
}
@@ -529,9 +503,9 @@
* @param dict : dictionary of properties to delete.
*/
public void removeProperties(Dictionary dict) {
- for (int i = 0; i < m_providedServices.length; i++) {
- m_providedServices[i].deleteProperties(dict);
- m_providedServices[i].update();
+ for (ProvidedService ps : m_providedServices) {
+ ps.deleteProperties(dict);
+ ps.update();
}
}
@@ -554,10 +528,10 @@
ProvidedService svc = getProvidedServices()[j];
Property[] props = svc.getProperties();
boolean update = false;
- for (int k = 0; k < props.length; k++) {
- if (dict.get(props[k].getName()) != null) {
+ for (Property prop : props) {
+ if (dict.get(prop.getName()) != null) {
update = true;
- props[k].setValue(dict.get(props[k].getName()));
+ prop.setValue(dict.get(prop.getName()));
}
}
if (update) {
@@ -578,12 +552,12 @@
Element[] provides = metadata.getElements("provides");
PojoMetadata manipulation = getFactory().getPojoMetadata();
- for (int i = 0; i < provides.length; i++) {
+ for (Element provide : provides) {
// First : create the serviceSpecification list
String[] serviceSpecification = manipulation.getInterfaces();
String parent = manipulation.getSuperClass();
- Set interfaces = new HashSet();
- Set parentClasses = new HashSet();
+ Set<String> interfaces = new HashSet<String>();
+ Set<String> parentClasses = new HashSet<String>();
try {
computeInterfacesAndSuperClasses(serviceSpecification, parent, desc.getBundleContext().getBundle(), interfaces, parentClasses);
getLogger().log(Logger.INFO, "Collected interfaces from " + metadata.getAttribute("classname") + " : " + interfaces);
@@ -592,24 +566,24 @@
throw new ConfigurationException("An interface or parent class cannot be loaded", e);
}
- String serviceSpecificationStr = provides[i].getAttribute("specifications");
+ String serviceSpecificationStr = provide.getAttribute("specifications");
if (serviceSpecificationStr == null) {
- serviceSpecificationStr = provides[i].getAttribute("interface");
+ serviceSpecificationStr = provide.getAttribute("interface");
if (serviceSpecificationStr != null) {
warn("The 'interface' attribute is deprecated, use the 'specifications' attribute instead of 'interface'");
}
}
if (serviceSpecificationStr != null) {
- List itfs = ParseUtils.parseArraysAsList(serviceSpecificationStr);
- for (int j = 0; j < itfs.size(); j++) {
- if (! interfaces.contains(itfs.get(j))
- && ! parentClasses.contains(itfs.get(j))
- && ! desc.getFactory().getClassName().equals(itfs.get(j))) {
- desc.getFactory().getLogger().log(Logger.ERROR, "The specification " + itfs.get(j) + " is not implemented by " + metadata.getAttribute("classname"));
+ List<String> itfs = ParseUtils.parseArraysAsList(serviceSpecificationStr);
+ for (String itf : itfs)
+ if (!interfaces.contains(itf)
+ && !parentClasses.contains(itf)
+ && !desc.getFactory().getClassName().equals(itf)) {
+ desc.getFactory().getLogger().log(Logger.ERROR, "The specification " + itf + " is not implemented by " + metadata.getAttribute("classname"));
}
- }
- interfaces = new HashSet(itfs);
+ interfaces.clear();
+ interfaces.addAll(itfs);
}
if (interfaces.isEmpty()) {
@@ -618,11 +592,9 @@
}
StringBuffer specs = null;
- Set set = new HashSet(interfaces);
+ Set<String> set = new HashSet<String>(interfaces);
set.remove(Pojo.class.getName()); // Remove POJO.
- Iterator iterator = set.iterator();
- while (iterator.hasNext()) {
- String spec = (String) iterator.next();
+ for (String spec : set) {
desc.addProvidedServiceSpecification(spec);
if (specs == null) {
specs = new StringBuffer("{");
@@ -634,9 +606,9 @@
}
specs.append('}');
- provides[i].addAttribute(new Attribute("specifications", specs.toString())); // Add interface attribute to avoid checking in the configure method
+ provide.addAttribute(new Attribute("specifications", specs.toString())); // Add interface attribute to avoid checking in the configure method
- Element[] props = provides[i].getElements("property");
+ Element[] props = provide.getElements("property");
for (int j = 0; props != null && j < props.length; j++) {
String name = props[j].getAttribute("name");
String value = props[j].getAttribute("value");
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/SecurityHelper.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/SecurityHelper.java
index 04d576f..32d4d36 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/SecurityHelper.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/SecurityHelper.java
@@ -20,8 +20,10 @@
import java.security.Permission;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServicePermission;
+import org.osgi.framework.ServiceRegistration;
/**
@@ -45,8 +47,8 @@
public static BundleContext selectContextToRegisterServices(String[] itfs,
BundleContext comp, BundleContext ipojo) {
if (System.getSecurityManager() != null) {
- for (int i = 0; i < itfs.length; i++) {
- final Permission perm = new ServicePermission(itfs[i],
+ for (String itf : itfs) {
+ final Permission perm = new ServicePermission(itf,
ServicePermission.REGISTER);
if (!comp.getBundle().hasPermission(perm)) {
return ipojo;
@@ -132,8 +134,8 @@
public static boolean hasPermissionToGetServices(String[] itfs,
BundleContext comp) {
if (System.getSecurityManager() != null) {
- for (int i = 0; i < itfs.length; i++) {
- final Permission perm = new ServicePermission(itfs[i],
+ for (String itf : itfs) {
+ final Permission perm = new ServicePermission(itf,
ServicePermission.GET);
if (!comp.getBundle().hasPermission(perm)) {
return false;
@@ -172,8 +174,8 @@
public static boolean hasPermissionToRegisterServices(String[] itfs,
BundleContext comp) {
if (System.getSecurityManager() != null) {
- for (int i = 0; i < itfs.length; i++) {
- final Permission perm = new ServicePermission(itfs[i],
+ for (String itf : itfs) {
+ final Permission perm = new ServicePermission(itf,
ServicePermission.REGISTER);
if (!comp.getBundle().hasPermission(perm)) {
return false;
@@ -183,4 +185,34 @@
return true;
}
+ /**
+ * Checks that the given bundle context is in a state where it is possible to register services.
+ * This methods ensures that the bundle associated to the given context, is starting or active.
+ * @param context the bundle context
+ * @return {@literal true} if the context can register a service, {@literal false} otherwise.
+ */
+ public static boolean canRegisterService(BundleContext context) {
+ return context.getBundle().getState() == Bundle.ACTIVE
+ || context.getBundle().getState() == Bundle.STARTING;
+ }
+
+ /**
+ * Checks that the given service registration can be updated.
+ * This methods ensures that the bundle associated to the given service, is starting or active.
+ * @param registration the service registration
+ * @return {@literal true} if the service can be updated, {@literal false} otherwise.
+ */
+ public static boolean canUpdateService(ServiceRegistration registration) {
+ if (registration == null) {
+ return false;
+ }
+ try {
+ BundleContext context = registration.getReference().getBundle().getBundleContext();
+ return context.getBundle().getState() == Bundle.ACTIVE
+ || context.getBundle().getState() == Bundle.STARTING;
+ } catch (IllegalStateException e) {
+ return false;
+ }
+ }
+
}