You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2013/04/29 14:59:53 UTC
svn commit: r1477027 [3/3] - in /felix/trunk/ipojo/runtime:
core-it/src/it/ipojo-core-configuration-admin-test/
core-it/src/it/ipojo-core-configuration-admin-test/src/
core-it/src/it/ipojo-core-configuration-admin-test/src/main/
core-it/src/it/ipojo-co...
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java?rev=1477027&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java Mon Apr 29 12:59:52 2013
@@ -0,0 +1,332 @@
+/*
+ * 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.felix.ipojo;
+
+import org.apache.felix.ipojo.extender.internal.Extender;
+import org.apache.felix.ipojo.util.Log;
+import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.ServiceLocator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.*;
+import org.osgi.service.cm.ConfigurationException;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * An object tracking configuration from the configuration admin. It delegates to the underlying factories or
+ * component instance the action.
+ * <p/>
+ * This class implements a Configuration Listener, so events are received asynchronously.
+ */
+public class ConfigurationTracker implements ConfigurationListener {
+
+ /**
+ * The tracker instance.
+ */
+ private static ConfigurationTracker m_singleton;
+ private final ServiceRegistration<ConfigurationListener> m_registration;
+ private final BundleContext m_context;
+ private final Logger m_logger;
+ private Map<String, IPojoFactory> m_factories = new HashMap<String, IPojoFactory>();
+
+ public ConfigurationTracker() {
+ m_context = Extender.getIPOJOBundleContext();
+ m_logger = new Logger(m_context, "iPOJO Configuration Admin listener", Log.INFO);
+ // register as listener for configurations
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(Constants.SERVICE_DESCRIPTION, "iPOJO Configuration Admin Listener");
+ props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+ m_registration = m_context.registerService(ConfigurationListener.class, this, props);
+ }
+
+ public static void initialize() {
+ synchronized (ConfigurationTracker.class) {
+ if (m_singleton == null) {
+ m_singleton = new ConfigurationTracker();
+ }
+ }
+ }
+
+ public static void shutdown() {
+ m_singleton.dispose();
+ }
+
+ public static ConfigurationTracker get() {
+ return m_singleton;
+ }
+
+ /**
+ * This method must be called by the iPOJO System itself, and only once.
+ */
+ public synchronized void dispose() {
+ if (m_registration != null) {
+ m_registration.unregister();
+ }
+ m_factories.clear();
+ }
+
+ public synchronized void registerFactory(IPojoFactory factory) {
+ m_factories.put(factory.getFactoryName(), factory);
+
+ ServiceLocator<ConfigurationAdmin> locator = new ServiceLocator<ConfigurationAdmin>(ConfigurationAdmin
+ .class, m_context);
+ final ConfigurationAdmin admin = locator.get();
+ if (admin == null) {
+ return;
+ }
+
+ List<Configuration> configurations = findFactoryConfiguration(admin, factory);
+ for (Configuration configuration : configurations) {
+ try {
+ factory.updated(configuration.getPid(), configuration.getProperties());
+ } catch (ConfigurationException e) {
+ m_logger.log(Log.ERROR, "Cannot reconfigure instance " + configuration.getPid() + " from " +
+ configuration.getFactoryPid() + " with the configuration : " + configuration.getProperties(),
+ e);
+ }
+ }
+ }
+
+ public synchronized void instanceCreated(IPojoFactory factory, ComponentInstance instance) {
+ ServiceLocator<ConfigurationAdmin> locator = new ServiceLocator<ConfigurationAdmin>(ConfigurationAdmin
+ .class, m_context);
+ final ConfigurationAdmin admin = locator.get();
+ if (admin == null) {
+ return;
+ }
+
+ Configuration configuration = findSingletonConfiguration(admin, instance.getInstanceName());
+ if (configuration != null) {
+ Hashtable<String, Object> conf = copyConfiguration(configuration);
+ if (!conf.containsKey(Factory.INSTANCE_NAME_PROPERTY)) {
+ conf.put(Factory.INSTANCE_NAME_PROPERTY, configuration.getPid());
+ }
+ try {
+ instance.getFactory().reconfigure(conf);
+ } catch (UnacceptableConfiguration unacceptableConfiguration) {
+ m_logger.log(Log.ERROR, "Cannot reconfigure the instance " + configuration.getPid() + " - the " +
+ "configuration is unacceptable", unacceptableConfiguration);
+ } catch (MissingHandlerException e) {
+ m_logger.log(Log.ERROR, "Cannot reconfigure the instance " + configuration.getPid() + " - factory is " +
+ "invalid", e);
+ }
+ }
+ }
+
+ public synchronized void unregisterFactory(IPojoFactory factory) {
+ m_factories.remove(factory.getFactoryName());
+ }
+
+ public void configurationEvent(ConfigurationEvent event) {
+ String pid = event.getPid();
+ String factoryPid = event.getFactoryPid();
+
+ if (factoryPid == null) {
+ ComponentInstance instance = retrieveInstance(pid);
+ if (instance != null) {
+ manageConfigurationEventForSingleton(instance, event);
+ }
+ } else {
+ IPojoFactory factory = retrieveFactory(factoryPid);
+ if (factory != null) {
+ manageConfigurationEventForFactory(factory, event);
+ }
+ // Else the factory is unknown, do nothing.
+ }
+
+ }
+
+ private void manageConfigurationEventForFactory(final IPojoFactory factory, final ConfigurationEvent event) {
+ ServiceLocator<ConfigurationAdmin> locator = new ServiceLocator<ConfigurationAdmin>(ConfigurationAdmin
+ .class, m_context);
+
+ switch (event.getType()) {
+ case ConfigurationEvent.CM_DELETED:
+ factory.deleted(event.getPid());
+ break;
+ case ConfigurationEvent.CM_UPDATED:
+ final ConfigurationAdmin admin = locator.get();
+ if (admin == null) {
+ break;
+ }
+ final Configuration config = getConfiguration(admin, event.getPid(),
+ factory.getBundleContext().getBundle().getLocation());
+ if (config != null) {
+ try {
+ factory.updated(event.getPid(), config.getProperties());
+ } catch (org.osgi.service.cm.ConfigurationException e) {
+ m_logger.log(Log.ERROR, "Cannot reconfigure instance " + event.getPid() + " with the new " +
+ "configuration " + config.getProperties(), e);
+ }
+ }
+ default:
+ // To nothing.
+ }
+
+ locator.unget();
+ }
+
+ private void manageConfigurationEventForSingleton(final ComponentInstance instance,
+ final ConfigurationEvent event) {
+ ServiceLocator<ConfigurationAdmin> locator = new ServiceLocator<ConfigurationAdmin>(ConfigurationAdmin
+ .class, m_context);
+
+ switch (event.getType()) {
+ case ConfigurationEvent.CM_DELETED:
+ instance.dispose();
+ break;
+ case ConfigurationEvent.CM_UPDATED:
+ final ConfigurationAdmin admin = locator.get();
+ if (admin == null) {
+ break;
+ }
+ final Configuration config = getConfiguration(admin, event.getPid(),
+ instance.getFactory().getBundleContext().getBundle().getLocation());
+ if (config != null) {
+ Hashtable<String, Object> conf = copyConfiguration(config);
+ if (!conf.containsKey(Factory.INSTANCE_NAME_PROPERTY)) {
+ conf.put(Factory.INSTANCE_NAME_PROPERTY, event.getPid());
+ }
+ try {
+ instance.getFactory().reconfigure(conf);
+ } catch (UnacceptableConfiguration unacceptableConfiguration) {
+ m_logger.log(Log.ERROR, "Cannot reconfigure the instance " + event.getPid() + " - the " +
+ "configuration is unacceptable", unacceptableConfiguration);
+ } catch (MissingHandlerException e) {
+ m_logger.log(Log.ERROR, "Cannot reconfigure the instance " + event.getPid() + " - factory is " +
+ "invalid", e);
+ }
+ }
+ default:
+ // To nothing.
+ }
+
+ locator.unget();
+ }
+
+ private Hashtable<String, Object> copyConfiguration(Configuration config) {
+ Hashtable<String, Object> conf = new Hashtable<String, Object>();
+ // Copy configuration
+ Enumeration keys = config.getProperties().keys();
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ conf.put(key, config.getProperties().get(key));
+ }
+ return conf;
+ }
+
+ private IPojoFactory retrieveFactory(String factoryPid) {
+ synchronized (this) {
+ return m_factories.get(factoryPid);
+ }
+ }
+
+ private ComponentInstance retrieveInstance(String instanceName) {
+ Collection<IPojoFactory> factories;
+ synchronized (this) {
+ factories = m_factories.values();
+ }
+ for (IPojoFactory factory : factories) {
+ ComponentInstance instance = factory.getInstanceByName(instanceName);
+ if (instance != null) {
+ return instance;
+ }
+ }
+ return null;
+ }
+
+ private Configuration getConfiguration(final ConfigurationAdmin admin, final String pid,
+ final String bundleLocation) {
+ if (admin == null) {
+ return null;
+ }
+
+ try {
+ // Even if it is possible, we don't build the filter with bundle.location to detect the case where the
+ // configuration exists but can't be managed by iPOJO.
+ final Configuration cfg = admin.getConfiguration(pid);
+
+ if (bundleLocation.equals(cfg.getBundleLocation())) {
+ return cfg;
+ }
+
+ // Multi-location with only ?
+ if (cfg.getBundleLocation().equals("?")) {
+ return cfg;
+ }
+
+ // Multi-location specifying the pid
+ if (cfg.getBundleLocation().startsWith("?")) {
+ String sn = cfg.getBundleLocation().substring(1); // Remove ?
+ if (sn.equals(pid)) {
+ return cfg;
+ }
+ }
+
+ // configuration belongs to another bundle, cannot be used here
+ m_logger.log(Log.ERROR, "Cannot use configuration pid=" + pid + " for bundle "
+ + bundleLocation + " because it belongs to bundle " + cfg.getBundleLocation());
+ } catch (IOException ioe) {
+ m_logger.log(Log.WARNING, "Failed reading configuration for pid=" + pid, ioe);
+ }
+
+ return null;
+ }
+
+ public List<Configuration> findFactoryConfiguration(final ConfigurationAdmin admin, final IPojoFactory factory) {
+ final String filter = "(service.factoryPid=" + factory.getFactoryName() + ")";
+ return findConfigurations(admin, filter);
+ }
+
+ public Configuration findSingletonConfiguration(final ConfigurationAdmin admin, final String pid) {
+ final String filter = "(service.pid=" + pid + ")";
+ List<Configuration> list = findConfigurations(admin, filter);
+ if (list.isEmpty()) {
+ return null;
+ } else {
+ return list.get(0);
+ }
+ }
+
+ private List<Configuration> findConfigurations(final ConfigurationAdmin admin, final String filter) {
+ List<Configuration> configurations = Collections.emptyList();
+ if (admin == null) {
+ return configurations;
+ }
+
+ try {
+ Configuration[] list = admin.listConfigurations(filter);
+ if (list == null) {
+ return configurations;
+ } else {
+ return Arrays.asList(list);
+ }
+ } catch (InvalidSyntaxException e) {
+ m_logger.log(Log.ERROR, "Invalid Configuration selection filter " + filter, e);
+ } catch (IOException e) {
+ m_logger.log(Log.ERROR, "Error when retrieving configurations for filter=" + filter, e);
+ }
+ return configurations;
+ }
+}
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FactoryClassloader.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FactoryClassloader.java?rev=1477027&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FactoryClassloader.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FactoryClassloader.java Mon Apr 29 12:59:52 2013
@@ -0,0 +1,88 @@
+/*
+ * 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.felix.ipojo;
+
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class defines the classloader attached to a factory.
+ * This class loader is used to load the implementation (e.g. manipulated)
+ * class.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * @see ClassLoader
+ */
+class FactoryClassloader extends ClassLoader {
+
+ /**
+ * The map of defined classes [Name, Class Object].
+ */
+ private final Map<String, Class<?>> m_definedClasses = new HashMap<String, Class<?>>();
+ private ComponentFactory factory;
+
+ public FactoryClassloader(ComponentFactory factory) {
+ this.factory = factory;
+ }
+
+ /**
+ * The defineClass method.
+ *
+ * @param name name of the class
+ * @param clazz the byte array of the class
+ * @param domain the protection domain
+ * @return the defined class.
+ */
+ public Class<?> defineClass(String name, byte[] clazz, ProtectionDomain domain) {
+ if (m_definedClasses.containsKey(name)) {
+ return m_definedClasses.get(name);
+ }
+ Class clas = super.defineClass(name, clazz, 0, clazz.length, domain);
+ m_definedClasses.put(name, clas);
+ return clas;
+ }
+
+ /**
+ * Returns the URL of the required resource.
+ *
+ * @param arg the name of the resource to find.
+ * @return the URL of the resource.
+ * @see ClassLoader#getResource(String)
+ */
+ public URL getResource(String arg) {
+ return factory.m_context.getBundle().getResource(arg);
+ }
+
+ /**
+ * Loads the given class.
+ *
+ * @param name the name of the class
+ * @param resolve should be the class resolve now ?
+ * @return the loaded class object
+ * @throws ClassNotFoundException if the class to load is not found
+ * @see ClassLoader#loadClass(String, boolean)
+ * @see ClassLoader#loadClass(String, boolean)
+ */
+ protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ return factory.m_context.getBundle().loadClass(name);
+ }
+}
Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java?rev=1477027&r1=1477026&r2=1477027&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java Mon Apr 29 12:59:52 2013
@@ -35,8 +35,10 @@ import java.util.*;
/**
* This class defines common mechanisms of iPOJO component factories
* (i.e. component type).
- * This class implements both the Factory and ManagedServiceFactory
- * services.
+ *
+ * The factory is also tracking Factory configuration from the configuration admin to created / delete and update
+ * instances from this factory.
+ *
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public abstract class IPojoFactory implements Factory, ManagedServiceFactory {
@@ -49,7 +51,7 @@ public abstract class IPojoFactory imple
* The list of the managed instance name.
* This list is shared by all factories and is used to assert name uniqueness.
*/
- protected static final List INSTANCE_NAME = Collections.synchronizedList(new ArrayList());
+ protected static final List<String> INSTANCE_NAME = Collections.synchronizedList(new ArrayList<String>());
/**
* The component type description exposed by the {@link Factory} service.
@@ -60,7 +62,7 @@ public abstract class IPojoFactory imple
* The list of the managed instance managers.
* The key of this map is the name (i.e. instance names) of the created instance
*/
- protected final Map m_componentInstances = new HashMap();
+ protected final Map<String, ComponentInstance> m_componentInstances = new HashMap<String, ComponentInstance>();
/**
* The component type metadata.
@@ -82,13 +84,13 @@ public abstract class IPojoFactory imple
/**
* The list of required handlers.
*/
- protected List m_requiredHandlers = new ArrayList();
+ protected List<RequiredHandler> m_requiredHandlers = new ArrayList<RequiredHandler>();
/**
* The list of factory state listeners.
* @see FactoryStateListener
*/
- protected List m_listeners = new ArrayList(1);
+ protected List<FactoryStateListener> m_listeners = new ArrayList<FactoryStateListener>(1);
/**
* The logger for the factory.
@@ -202,7 +204,7 @@ public abstract class IPojoFactory imple
* Each sub-type must override this method.
* @return the required handler list
*/
- public abstract List getRequiredHandlerList();
+ public abstract List<RequiredHandler> getRequiredHandlerList();
/**
* Creates an instance.
@@ -292,14 +294,15 @@ public abstract class IPojoFactory imple
// Here we are sure to be valid until the end of the method.
HandlerManager[] handlers = new HandlerManager[m_requiredHandlers.size()];
for (int i = 0; i < handlers.length; i++) {
- RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
- handlers[i] = getHandler(req, serviceContext);
+ handlers[i] = getHandler(m_requiredHandlers.get(i), serviceContext);
}
try {
ComponentInstance instance = createInstance(configuration, context, handlers);
m_componentInstances.put(name, instance);
m_logger.log(Logger.INFO, "Instance " + name + " from factory " + m_factoryName + " created");
+ // Register the instance on the ConfigurationTracker to be updated if needed.
+ ConfigurationTracker.get().instanceCreated(this, instance);
return instance;
} catch (ConfigurationException e) {
INSTANCE_NAME.remove(name);
@@ -361,10 +364,9 @@ public abstract class IPojoFactory imple
* @return the list of missing handlers.
* @see org.apache.felix.ipojo.Factory#getMissingHandlers()
*/
- public List getMissingHandlers() {
- List list = new ArrayList();
- for (int i = 0; i < m_requiredHandlers.size(); i++) {
- RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+ public List<String> getMissingHandlers() {
+ List<String> list = new ArrayList<String>();
+ for (RequiredHandler req : m_requiredHandlers) {
if (req.getReference() == null) {
list.add(req.getFullName());
}
@@ -389,10 +391,9 @@ public abstract class IPojoFactory imple
* @return the list of required handlers.
* @see org.apache.felix.ipojo.Factory#getRequiredHandlers()
*/
- public synchronized List getRequiredHandlers() {
- List list = new ArrayList();
- for (int i = 0; i < m_requiredHandlers.size(); i++) {
- RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+ public synchronized List<String> getRequiredHandlers() {
+ List<String> list = new ArrayList<String>();
+ for (RequiredHandler req : m_requiredHandlers) {
list.add(req.getFullName());
}
return list;
@@ -409,6 +410,17 @@ public abstract class IPojoFactory imple
}
/**
+ * Gets a component instance created by the current factory.
+ * @param name the instance name
+ * @return the component instance, {@literal null} if not found
+ */
+ public ComponentInstance getInstanceByName(String name) {
+ synchronized (this) {
+ return m_componentInstances.get(name);
+ }
+ }
+
+ /**
* Checks if the configuration is acceptable.
* @param conf the configuration to test.
* @return <code>true</code> if the configuration is acceptable.
@@ -435,7 +447,8 @@ public abstract class IPojoFactory imple
* @throws UnacceptableConfiguration if the configuration is unacceptable.
* @throws MissingHandlerException if an handler is missing.
*/
- public void checkAcceptability(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {
+ public void checkAcceptability(Dictionary<String, ?> conf) throws UnacceptableConfiguration,
+ MissingHandlerException {
PropertyDescription[] props;
synchronized (this) {
if (m_state == Factory.INVALID) {
@@ -447,14 +460,15 @@ public abstract class IPojoFactory imple
// Check that the configuration does not override immutable properties.
- for (int i = 0; i < props.length; i++) {
+ for (PropertyDescription prop : props) {
// Is the property immutable
- if (props[i].isImmutable() && conf.get(props[i].getName()) != null) {
- throw new UnacceptableConfiguration("The property " + props[i] + " cannot be overide : immutable property"); // The instance configuration tries to override an immutable property.
+ if (prop.isImmutable() && conf.get(prop.getName()) != null) {
+ throw new UnacceptableConfiguration("The property " + prop + " cannot be overridden : immutable " +
+ "property"); // The instance configuration tries to override an immutable property.
}
// Is the property required ?
- if (props[i].isMandatory() && props[i].getValue() == null && conf.get(props[i].getName()) == null) {
- throw new UnacceptableConfiguration("The mandatory property " + props[i].getName() + " is missing"); // The property must be set.
+ if (prop.isMandatory() && prop.getValue() == null && conf.get(prop.getName()) == null) {
+ throw new UnacceptableConfiguration("The mandatory property " + prop.getName() + " is missing"); // The property must be set.
}
}
}
@@ -480,7 +494,7 @@ public abstract class IPojoFactory imple
name = (String) properties.get("name");
}
- ComponentInstance instance = (ComponentInstance) m_componentInstances.get(name);
+ ComponentInstance instance = m_componentInstances.get(name);
if (instance == null) { // The instance does not exists.
return;
}
@@ -520,13 +534,16 @@ public abstract class IPojoFactory imple
m_sr.unregister();
m_sr = null;
}
+
+ ConfigurationTracker.get().unregisterFactory(this);
+
stopping(); // Method called when holding the lock.
int oldState = m_state; // Create a variable to store the old state. Using a variable is important as
// after the next instruction, the getState() method must return INVALID.
m_state = INVALID; // Set here to avoid to create instances during the stops.
- Set col = m_componentInstances.keySet();
- Iterator it = col.iterator();
+ Set<String> col = m_componentInstances.keySet();
+ Iterator<String> it = col.iterator();
instances = new ComponentInstance[col.size()]; // Stack confinement
int index = 0;
while (it.hasNext()) {
@@ -535,23 +552,23 @@ public abstract class IPojoFactory imple
}
if (oldState == VALID) { // Check if the old state was valid.
- for (int i = 0; i < m_listeners.size(); i++) {
- ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
+ for (FactoryStateListener listener : m_listeners) {
+ listener.stateChanged(this, INVALID);
}
}
// Dispose created instances.
- for (int i = 0; i < instances.length; i++) {
- ComponentInstance instance = instances[i];
+ for (ComponentInstance instance : instances) {
if (instance.getState() != ComponentInstance.DISPOSED) {
instance.dispose();
}
}
// Release each handler
- for (int i = 0; i < m_requiredHandlers.size(); i++) {
- ((RequiredHandler) m_requiredHandlers.get(i)).unRef();
+ for (RequiredHandler req : m_requiredHandlers) {
+ req.unRef();
}
+
m_described = false;
m_componentDesc = null;
m_componentInstances.clear();
@@ -601,13 +618,17 @@ public abstract class IPojoFactory imple
if (m_isPublic) {
// Exposition of the factory service
if (m_componentDesc == null) {
- System.out.println("Description of " + m_factoryName + " " + m_componentDesc);
+ m_logger.log(Logger.ERROR, "Unexpected state, the description of " + m_factoryName + " is null");
+ return;
}
BundleContext bc = SecurityHelper.selectContextToRegisterServices(m_componentDesc.getFactoryInterfacesToPublish(),
m_context, getIPOJOBundleContext());
m_sr =
bc.registerService(m_componentDesc.getFactoryInterfacesToPublish(), this, m_componentDesc
.getPropertiesToPublish());
+
+ // Register the factory on the ConfigurationTracker
+ ConfigurationTracker.get().registerFactory(this);
}
m_logger.log(Logger.INFO, "Factory " + m_factoryName + " started");
@@ -637,11 +658,12 @@ public abstract class IPojoFactory imple
* @param properties the new configuration of the instance
* @throws org.osgi.service.cm.ConfigurationException if the configuration is not consistent for this component type
* @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String, java.util.Dictionary)
+ * TODO this method should disappear.
*/
public void updated(String name, Dictionary properties) throws org.osgi.service.cm.ConfigurationException {
ComponentInstance instance;
synchronized (this) {
- instance = (ComponentInstance) m_componentInstances.get(name);
+ instance = m_componentInstances.get(name);
}
if (instance == null) {
@@ -677,6 +699,7 @@ public abstract class IPojoFactory imple
* Deletes an instance.
* @param name the name of the instance to delete
* @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
+ * todo this method should disappear.
*/
public synchronized void deleted(String name) {
INSTANCE_NAME.remove(name);
@@ -707,9 +730,7 @@ public abstract class IPojoFactory imple
* This method is called with the lock.
*/
protected void computeDescription() {
- for (int i = 0; i < m_requiredHandlers.size(); i++) {
- RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
-
+ for (RequiredHandler req : m_requiredHandlers) {
if (getHandler(req, null) == null) {
// TODO this does not really looks good.
m_logger.log(Logger.ERROR, "Cannot extract handler object from " + m_factoryName + " " + req
@@ -720,7 +741,7 @@ public abstract class IPojoFactory imple
handler.setFactory(this);
handler.initializeComponentFactory(m_componentDesc, m_componentMetadata);
((Pojo) handler).getComponentInstance().dispose();
- } catch (org.apache.felix.ipojo.ConfigurationException e) {
+ } catch (ConfigurationException e) {
((Pojo) handler).getComponentInstance().dispose();
m_logger.log(Logger.ERROR, e.getMessage());
stop();
@@ -739,8 +760,7 @@ public abstract class IPojoFactory imple
*/
protected void computeFactoryState() {
boolean isValid = true;
- for (int i = 0; i < m_requiredHandlers.size(); i++) {
- RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+ for (RequiredHandler req : m_requiredHandlers) {
if (req.getReference() == null) {
isValid = false;
break;
@@ -760,25 +780,24 @@ public abstract class IPojoFactory imple
if (m_sr != null) {
m_sr.setProperties(m_componentDesc.getPropertiesToPublish());
}
- for (int i = 0; i < m_listeners.size(); i++) {
- ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, VALID);
+ for (FactoryStateListener listener : m_listeners) {
+ listener.stateChanged(this, VALID);
}
- return;
}
} else {
if (m_state == VALID) {
m_state = INVALID;
// Notify listeners.
- for (int i = 0; i < m_listeners.size(); i++) {
- ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
+ for (FactoryStateListener listener : m_listeners) {
+ listener.stateChanged(this, INVALID);
}
// Dispose created instances.
- Set col = m_componentInstances.keySet();
- String[] keys = (String[]) col.toArray(new String[col.size()]);
- for (int i = 0; i < keys.length; i++) {
- ComponentInstance instance = (ComponentInstance) m_componentInstances.get(keys[i]);
+ // We must create a copy to avoid concurrent exceptions
+ Set<? extends String> keys = new HashSet<String>(m_componentInstances.keySet());
+ for (String key : keys) {
+ ComponentInstance instance = m_componentInstances.get(key);
if (instance.getState() != ComponentInstance.DISPOSED) {
instance.dispose();
}
@@ -790,8 +809,6 @@ public abstract class IPojoFactory imple
if (m_sr != null) {
m_sr.setProperties(m_componentDesc.getPropertiesToPublish());
}
-
- return;
}
}
}
@@ -803,7 +820,7 @@ public abstract class IPojoFactory imple
* @param ref the service reference.
* @return <code>true</code> if the service reference can fulfill the handler requirement
*/
- protected boolean match(RequiredHandler req, ServiceReference ref) {
+ protected boolean match(RequiredHandler req, ServiceReference<? extends Object> ref) {
String name = (String) ref.getProperty(Handler.HANDLER_NAME_PROPERTY);
String namespace = (String) ref.getProperty(Handler.HANDLER_NAMESPACE_PROPERTY);
if (HandlerFactory.IPOJO_NAMESPACE.equals(namespace)) {
@@ -927,7 +944,7 @@ public abstract class IPojoFactory imple
return null;
}
if (m_factory == null) {
- m_factory = (HandlerFactory) m_context.getService(getReference());
+ m_factory = m_context.getService(getReference());
}
return m_factory;
}
@@ -952,7 +969,7 @@ public abstract class IPojoFactory imple
return m_namespace;
}
- public ServiceReference getReference() {
+ public ServiceReference<? extends HandlerFactory> getReference() {
return m_reference;
}
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveTypeDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveTypeDescription.java?rev=1477027&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveTypeDescription.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveTypeDescription.java Mon Apr 29 12:59:52 2013
@@ -0,0 +1,228 @@
+/*
+ * 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.felix.ipojo;
+
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.osgi.framework.Bundle;
+
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class defines the description of primitive (non-composite) component
+ * types. An instance of this class will be returned when invoking the
+ * {@link org.apache.felix.ipojo.ComponentFactory#getComponentDescription()} method.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+final class PrimitiveTypeDescription extends ComponentTypeDescription {
+
+ /**
+ * Set to keep component's all super-class class-names.
+ */
+ private Set<String> m_superClasses = new HashSet<String>();
+
+ /**
+ * Set to keep component's all interface class-names.
+ */
+ private Set<String> m_interfaces = new HashSet<String>();
+
+ /**
+ * The described component factory.
+ */
+ private ComponentFactory m_factory;
+
+ /**
+ * Creates a PrimitiveTypeDescription object.
+ *
+ * @param factory the m_factory attached to this component type description.
+ */
+ public PrimitiveTypeDescription(ComponentFactory factory) {
+ super(factory);
+ this.m_factory = factory;
+
+ try {
+ // The inspection can be done only for primitive components
+ if (factory.getClassName() != null) {
+ // Read inherited classes and interfaces into given Sets.
+ new InheritanceInspector(factory.getPojoMetadata(), getBundleContext().getBundle()).
+ computeInterfacesAndSuperClasses(m_interfaces, m_superClasses);
+ }
+ } catch (ClassNotFoundException e) {
+ m_interfaces.clear();
+ m_superClasses.clear();
+ }
+
+ }
+
+ /**
+ * Computes the properties to publish.
+ * The <code>component.class</code> property contains the implementation class name.
+ *
+ * @return the dictionary of properties to publish
+ * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getPropertiesToPublish()
+ */
+ public Dictionary<String, Object> getPropertiesToPublish() {
+ Dictionary<String, Object> dict = super.getPropertiesToPublish();
+ if (m_factory.getClassName() != null) {
+ dict.put("component.class", m_factory.getClassName());
+ }
+ return dict;
+ }
+
+ /**
+ * Adds the "implementation-class" attribute to the type description.
+ *
+ * @return the component type description.
+ * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getDescription()
+ */
+ public Element getDescription() {
+ Element elem = super.getDescription();
+ elem.addAttribute(new Attribute("Implementation-Class", m_factory.getClassName()));
+
+ /* Adding interfaces and super-classes of component into description */
+ Element inheritance = new Element("Inherited", "");
+
+ inheritance.addAttribute(new Attribute("Interfaces", m_interfaces.toString()));
+ inheritance.addAttribute(new Attribute("SuperClasses", m_superClasses.toString()));
+
+ elem.addElement(inheritance);
+
+ return elem;
+ }
+
+ /**
+ * This class is used to collect interfaces and super-classes of given component in specified Sets.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+ private final class InheritanceInspector {
+ /*
+ * PojoMetadata of target Component.
+ */
+ private PojoMetadata m_pojoMetadata;
+ /*
+ * Bundle exposing target component.
+ */
+ private Bundle m_bundle;
+
+
+ /**
+ * Creates a TypeCollector object
+ *
+ * @param pojoMetadata PojoMetadata describing Component.
+ * @param bundle Bundle which has been exposed the intended Component.
+ */
+ public InheritanceInspector(PojoMetadata pojoMetadata, Bundle bundle) {
+ m_pojoMetadata = pojoMetadata;
+ m_bundle = bundle;
+ }
+
+ /**
+ * Collect interfaces implemented by the POJO into given Sets.
+ *
+ * @param interfaces : the set of implemented interfaces
+ * @param classes : the set of extended classes
+ * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
+ */
+ public void computeInterfacesAndSuperClasses(Set<String> interfaces, Set<String> classes) throws ClassNotFoundException {
+ String[] immediateInterfaces = m_pojoMetadata.getInterfaces();
+ String parentClass = m_pojoMetadata.getSuperClass();
+
+ // First iterate on found specification in manipulation metadata
+ for (String immediateInterface : immediateInterfaces) {
+ interfaces.add(immediateInterface);
+ // Iterate on interfaces implemented by the current interface
+ Class<?> clazz = m_bundle.loadClass(immediateInterface);
+ collectInterfaces(clazz, interfaces, m_bundle);
+ }
+
+ // Look for parent class.
+ if (parentClass != null) {
+ Class clazz = m_bundle.loadClass(parentClass);
+ collectInterfacesFromClass(clazz, interfaces, m_bundle);
+ classes.add(parentClass);
+ collectParentClassesFromClass(clazz, classes, m_bundle);
+ }
+
+ // Removing Object Class from the inherited classes list.
+ classes.remove(Object.class.getName());
+ }
+
+ /**
+ * Look for inherited interfaces.
+ *
+ * @param clazz : interface name to explore (class object)
+ * @param acc : set (accumulator)
+ * @param bundle : bundle
+ * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
+ */
+ private void collectInterfaces(Class<?> clazz, Set<String> acc, Bundle bundle) throws ClassNotFoundException {
+ Class[] clazzes = clazz.getInterfaces();
+ for (Class clazze : clazzes) {
+ acc.add(clazze.getName());
+ collectInterfaces(clazze, acc, bundle);
+ }
+ }
+
+ /**
+ * Collect interfaces for the given class.
+ * This method explores super class to.
+ *
+ * @param clazz : class object.
+ * @param acc : set of implemented interface (accumulator)
+ * @param bundle : bundle.
+ * @throws ClassNotFoundException : occurs if an interface cannot be load.
+ */
+ private void collectInterfacesFromClass(Class<?> clazz, Set<String> acc,
+ Bundle bundle) throws ClassNotFoundException {
+ Class[] clazzes = clazz.getInterfaces();
+ for (Class clazze : clazzes) {
+ acc.add(clazze.getName());
+ collectInterfaces(clazze, acc, bundle);
+ }
+ // Iterate on parent classes
+ Class sup = clazz.getSuperclass();
+ if (sup != null) {
+ collectInterfacesFromClass(sup, acc, bundle);
+ }
+ }
+
+ /**
+ * Collect parent classes for the given class.
+ *
+ * @param clazz : class object.
+ * @param acc : set of extended classes (accumulator)
+ * @param bundle : bundle.
+ * @throws ClassNotFoundException : occurs if an interface cannot be load.
+ */
+ private void collectParentClassesFromClass(Class<?> clazz, Set<String> acc, Bundle bundle) throws ClassNotFoundException {
+ Class<?> parent = clazz.getSuperclass();
+ if (parent != null) {
+ acc.add(parent.getName());
+ collectParentClassesFromClass(parent, acc, bundle);
+ }
+ }
+ }
+}
Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java?rev=1477027&r1=1477026&r2=1477027&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java Mon Apr 29 12:59:52 2013
@@ -18,11 +18,6 @@
*/
package org.apache.felix.ipojo.architecture;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Properties;
-
import org.apache.felix.ipojo.Factory;
import org.apache.felix.ipojo.IPojoFactory;
import org.apache.felix.ipojo.metadata.Attribute;
@@ -31,34 +26,37 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.service.cm.ManagedServiceFactory;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
/**
* Component Type description.
+ *
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class ComponentTypeDescription {
/**
+ * Represented factory.
+ */
+ private final IPojoFactory m_factory;
+ /**
* Provided service by the component type.
*/
private String[] m_providedServiceSpecification = new String[0];
-
/**
* Configuration Properties accepted by the component type.
*/
private PropertyDescription[] m_properties = new PropertyDescription[0];
-
/*
* Used by custom handlers to keep and retrieve custom info.
*/
private Dictionary m_handlerInfoSlot = new Hashtable();
/**
- * Represented factory.
- */
- private final IPojoFactory m_factory;
-
- /**
* Constructor.
+ *
* @param factory : represented factory.
*/
public ComponentTypeDescription(IPojoFactory factory) {
@@ -67,6 +65,7 @@ public class ComponentTypeDescription {
/**
* Gets the attached factory.
+ *
* @return the factory
*/
public IPojoFactory getFactory() {
@@ -75,6 +74,7 @@ public class ComponentTypeDescription {
/**
* Gets a printable form of the current component type description.
+ *
* @return printable form of the component type description
* @see java.lang.Object#toString()
*/
@@ -84,6 +84,7 @@ public class ComponentTypeDescription {
/**
* Gets the implementation class of this component type.
+ *
* @return the component type implementation class name.
* @deprecated
*/
@@ -93,8 +94,9 @@ public class ComponentTypeDescription {
/**
* Gets the component type version.
+ *
* @return the component type version or
- * <code>null</code> if not set.
+ * <code>null</code> if not set.
*/
public String getVersion() {
return m_factory.getVersion();
@@ -102,6 +104,7 @@ public class ComponentTypeDescription {
/**
* Gets component-type properties.
+ *
* @return the list of configuration properties accepted by the component type type.
*/
public PropertyDescription[] getProperties() {
@@ -110,7 +113,8 @@ public class ComponentTypeDescription {
/**
* Adds a String property in the component type.
- * @param name : property name.
+ *
+ * @param name : property name.
* @param value : property value.
*/
public void addProperty(String name, String value) {
@@ -119,8 +123,9 @@ public class ComponentTypeDescription {
/**
* Adds a String property in the component type.
- * @param name : property name.
- * @param value : property value.
+ *
+ * @param name : property name.
+ * @param value : property value.
* @param immutable : the property is immutable.
*/
public void addProperty(String name, String value, boolean immutable) {
@@ -130,6 +135,7 @@ public class ComponentTypeDescription {
/**
* Adds a configuration properties to the component type.
+ *
* @param pd : the property to add
*/
public void addProperty(PropertyDescription pd) { //NOPMD remove the instance name of the 'name' property.
@@ -138,7 +144,9 @@ public class ComponentTypeDescription {
// Check if the property is not already in the array
for (int i = 0; i < m_properties.length; i++) {
PropertyDescription desc = m_properties[i];
- if (desc.getName().equals(name)) { return; }
+ if (desc.getName().equals(name)) {
+ return;
+ }
}
PropertyDescription[] newProps = new PropertyDescription[m_properties.length + 1];
@@ -146,35 +154,32 @@ public class ComponentTypeDescription {
newProps[m_properties.length] = pd;
m_properties = newProps;
}
-
+
/**
* Adds the HandlerInfo for specified handler.
- * @param handlerNs Handler's namespace
+ *
+ * @param handlerNs Handler's namespace
* @param handlerName Handler's name
- * @param info HandlerInfo associated with the given custom handler.
+ * @param info HandlerInfo associated with the given custom handler.
*/
- public void setHandlerInfo(String handlerNs, String handlerName, CustomHandlerInfo info)
- {
- String fullHandlerName = handlerNs + ":" + handlerName;
-
- if(info == null)
- {
- m_handlerInfoSlot.remove(fullHandlerName);
- }
- else
- {
- m_handlerInfoSlot.put(fullHandlerName, info);
- }
- }
-
- public CustomHandlerInfo getHandlerInfo(String handlerNs, String handlerName)
- {
- String fullHandlerName = handlerNs + ":" + handlerName;
- return (CustomHandlerInfo)m_handlerInfoSlot.get(fullHandlerName);
+ public void setHandlerInfo(String handlerNs, String handlerName, CustomHandlerInfo info) {
+ String fullHandlerName = handlerNs + ":" + handlerName;
+
+ if (info == null) {
+ m_handlerInfoSlot.remove(fullHandlerName);
+ } else {
+ m_handlerInfoSlot.put(fullHandlerName, info);
+ }
+ }
+
+ public CustomHandlerInfo getHandlerInfo(String handlerNs, String handlerName) {
+ String fullHandlerName = handlerNs + ":" + handlerName;
+ return (CustomHandlerInfo) m_handlerInfoSlot.get(fullHandlerName);
}
/**
* Gets the list of provided service offered by instances of this type.
+ *
* @return the list of the provided service.
*/
public String[] getprovidedServiceSpecification() {
@@ -183,6 +188,7 @@ public class ComponentTypeDescription {
/**
* Adds a provided service to the component type.
+ *
* @param serviceSpecification : the provided service to add (interface name)
*/
public void addProvidedServiceSpecification(String serviceSpecification) {
@@ -194,6 +200,7 @@ public class ComponentTypeDescription {
/**
* Returns the component-type name.
+ *
* @return the name of this component type
*/
public String getName() {
@@ -203,10 +210,11 @@ public class ComponentTypeDescription {
/**
* Computes the default service properties to publish :
* factory.name, service.pid, component.providedServiceSpecification, component.properties, component.description, factory.State.
+ *
* @return : the dictionary of properties to publish.
*/
- public Dictionary getPropertiesToPublish() {
- Properties props = new Properties();
+ public Dictionary<String, Object> getPropertiesToPublish() {
+ Hashtable<String, Object> props = new Hashtable<String, Object>();
props.put("factory.name", m_factory.getName());
props.put(Constants.SERVICE_PID, m_factory.getName()); // Service PID is required for the integration in the configuration admin.
@@ -222,14 +230,14 @@ public class ComponentTypeDescription {
props.put("component.description", this);
// add every immutable property
- for (int i = 0; i < m_properties.length; i++) {
- if (m_properties[i].isImmutable() && m_properties[i].getValue() != null) {
- props.put(m_properties[i].getName(), m_properties[i].getObjectValue(m_factory.getBundleContext()));
+ for (PropertyDescription m_property : m_properties) {
+ if (m_property.isImmutable() && m_property.getValue() != null) {
+ props.put(m_property.getName(), m_property.getObjectValue(m_factory.getBundleContext()));
}
}
// Add factory state
- props.put("factory.state", new Integer(m_factory.getState()));
+ props.put("factory.state", m_factory.getState());
return props;
@@ -238,14 +246,16 @@ public class ComponentTypeDescription {
/**
* Gets the interfaces published by the factory.
* By default publish both {@link Factory} and {@link ManagedServiceFactory}.
+ *
* @return : the list of interface published by the factory.
*/
public String[] getFactoryInterfacesToPublish() {
- return new String[] {Factory.class.getName(), ManagedServiceFactory.class.getName()};
+ return new String[]{Factory.class.getName()};
}
/**
* Gets the component type description.
+ *
* @return : the description
*/
public Element getDescription() {
@@ -253,8 +263,8 @@ public class ComponentTypeDescription {
desc.addAttribute(new Attribute("name", m_factory.getName()));
desc.addAttribute(
- new Attribute("bundle",
- Long.toString(m_factory.getBundleContext().getBundle().getBundleId())));
+ new Attribute("bundle",
+ Long.toString(m_factory.getBundleContext().getBundle().getBundleId())));
String state = "valid";
if (m_factory.getState() == Factory.INVALID) {
@@ -280,24 +290,22 @@ public class ComponentTypeDescription {
Element prop = new Element("property", "");
prop.addAttribute(new Attribute("name", m_properties[i].getName()));
prop.addAttribute(new Attribute("type", m_properties[i].getType()));
- if (m_properties[i].isMandatory() && m_properties[i].getValue() == null) {
+ if (m_properties[i].isMandatory() && m_properties[i].getValue() == null) {
prop.addAttribute(new Attribute("value", "REQUIRED"));
} else {
prop.addAttribute(new Attribute("value", m_properties[i].getValue()));
}
desc.addElement(prop);
}
-
- if(m_handlerInfoSlot.size() > 0)
- {
- Enumeration keys = m_handlerInfoSlot.keys();
-
- while(keys.hasMoreElements())
- {
- String fullHandlerName = (String) keys.nextElement();
-
- CustomHandlerInfo handlerInfo = (CustomHandlerInfo)m_handlerInfoSlot.get(fullHandlerName);
- desc.addElement( handlerInfo.getDescription() );
+
+ if (m_handlerInfoSlot.size() > 0) {
+ Enumeration keys = m_handlerInfoSlot.keys();
+
+ while (keys.hasMoreElements()) {
+ String fullHandlerName = (String) keys.nextElement();
+
+ CustomHandlerInfo handlerInfo = (CustomHandlerInfo) m_handlerInfoSlot.get(fullHandlerName);
+ desc.addElement(handlerInfo.getDescription());
}
}
Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java?rev=1477027&r1=1477026&r2=1477027&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java Mon Apr 29 12:59:52 2013
@@ -19,7 +19,6 @@
package org.apache.felix.ipojo.configuration;
-import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.Factory;
import java.util.*;
@@ -49,6 +48,10 @@ public class Instance {
return new Pair<K, T>(k, v);
}
+ public static <K, T> Pair<K, T> entry(K k, T v) {
+ return new Pair<K, T>(k, v);
+ }
+
public String factory() {
return factory;
}
Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java?rev=1477027&r1=1477026&r2=1477027&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java Mon Apr 29 12:59:52 2013
@@ -19,6 +19,7 @@
package org.apache.felix.ipojo.extender.internal;
+import org.apache.felix.ipojo.ConfigurationTracker;
import org.apache.felix.ipojo.EventDispatcher;
import org.apache.felix.ipojo.extender.internal.linker.DeclarationLinker;
import org.apache.felix.ipojo.extender.internal.processor.*;
@@ -115,6 +116,9 @@ public class Extender implements BundleA
EventDispatcher.create(context);
}
+ // Initialize ConfigurationTracker
+ ConfigurationTracker.initialize();
+
BundleProcessor extensionBundleProcessor = new ExtensionBundleProcessor(m_logger);
BundleProcessor componentsProcessor = new ComponentsBundleProcessor(m_logger);
BundleProcessor configurationProcessor = new ConfigurationProcessor(m_logger);
@@ -169,6 +173,9 @@ public class Extender implements BundleA
public void stop(BundleContext context) throws Exception {
context.removeBundleListener(this);
+ //Shutdown ConfigurationTracker
+ ConfigurationTracker.shutdown();
+
m_processor.stop();
if (DISPATCHER_ENABLED) {
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/ServiceLocator.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/ServiceLocator.java?rev=1477027&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/ServiceLocator.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/ServiceLocator.java Mon Apr 29 12:59:52 2013
@@ -0,0 +1,61 @@
+/*
+ * 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.felix.ipojo.util;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A simple utility class to retrive services from the service registry.
+ */
+public class ServiceLocator<T> {
+
+ private final BundleContext m_context;
+ private final Class<T> m_clazz;
+
+ private ServiceReference<T> m_reference;
+ private T m_service;
+
+ public ServiceLocator(Class<T> clazz, BundleContext context) {
+ m_clazz = clazz;
+ m_context = context;
+ }
+
+ public synchronized T get() {
+ if (m_service != null) {
+ return m_service;
+ }
+
+ m_reference = m_context.getServiceReference(m_clazz);
+ if (m_reference == null) {
+ return null;
+ }
+ m_service = m_context.getService(m_reference);
+
+ return m_service;
+ }
+
+ public synchronized void unget() {
+ m_service = null;
+ if (m_reference != null) {
+ m_context.ungetService(m_reference);
+ m_reference = null;
+ }
+ }
+}