blob: 5bc3838ae2ac93dc448a108b01e0cbee9de04e75 [file] [log] [blame]
package org.apache.felix.ipojo.test.scenarios.component.strategies;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.IPOJOServiceFactory;
import org.apache.felix.ipojo.InstanceManager;
import org.apache.felix.ipojo.handlers.providedservice.CreationStrategy;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
public class DummyCreationStrategy extends CreationStrategy implements InvocationHandler {
/**
* Map [ComponentInstance->ServiceObject] storing created service objects.
*/
private Map/*<ComponentInstance, ServiceObject>*/ m_instances = new HashMap();
private InstanceManager m_manager;
private String[] m_specs;
/**
* A method is invoked on the proxy object.
* If the method is the {@link IPOJOServiceFactory#getService(ComponentInstance)}
* method, this method creates a service object if no already created for the asking
* component instance.
* If the method is {@link IPOJOServiceFactory#ungetService(ComponentInstance, Object)}
* the service object is unget (i.e. removed from the map and deleted).
* In all other cases, a {@link UnsupportedOperationException} is thrown as this policy
* requires to use the {@link IPOJOServiceFactory} interaction pattern.
* @param arg0 the proxy object
* @param arg1 the called method
* @param arg2 the arguments
* @return the service object attached to the asking instance for 'get',
* <code>null</code> for 'unget',
* a {@link UnsupportedOperationException} for all other methods.
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object arg0, Method arg1, Object[] arg2) {
if (isGetServiceMethod(arg1)) {
return getService((ComponentInstance) arg2[0]);
}
if (isUngetServiceMethod(arg1)) {
ungetService((ComponentInstance) arg2[0], arg2[1]);
return null;
}
throw new UnsupportedOperationException("This service requires an advanced creation policy. "
+ "Before calling the service, call the getService(ComponentInstance) method to get "
+ "the service object. " + arg1.getName());
}
/**
* A service object is required.
* This policy returns a service object per asking instance.
* @param instance the instance requiring the service object
* @return the service object for this instance
* @see org.apache.felix.ipojo.IPOJOServiceFactory#getService(org.apache.felix.ipojo.ComponentInstance)
*/
public Object getService(ComponentInstance instance) {
Object obj = m_instances.get(instance);
if (obj == null) {
obj = m_manager.createPojoObject();
m_instances.put(instance, obj);
}
return obj;
}
/**
* A service object is unget.
* The service object is removed from the map and deleted.
* @param instance the instance releasing the service
* @param svcObject the service object
* @see org.apache.felix.ipojo.IPOJOServiceFactory#ungetService(org.apache.felix.ipojo.ComponentInstance, java.lang.Object)
*/
public void ungetService(ComponentInstance instance, Object svcObject) {
Object pojo = m_instances.remove(instance);
m_manager.deletePojoObject(pojo);
}
/**
* The service is going to be registered.
* @param im the instance manager
* @param interfaces the published interfaces
* @param props the properties
* @see org.apache.felix.ipojo.handlers.providedservice.CreationStrategy#onPublication(org.osgi.framework.BundleContext, java.lang.String[], java.util.Properties)
*/
public void onPublication(InstanceManager im, String[] interfaces,
Properties props) {
m_manager = im;
m_specs = interfaces;
}
/**
* The service is going to be unregistered.
* The instance map is cleared. Created object are disposed.
* @see org.apache.felix.ipojo.handlers.providedservice.CreationStrategy#onUnpublication()
*/
public void onUnpublication() {
Collection col = m_instances.values();
Iterator it = col.iterator();
while (it.hasNext()) {
m_manager.deletePojoObject(it.next());
}
m_instances.clear();
}
/**
* OSGi Service Factory getService method.
* @param arg0 the asking bundle
* @param arg1 the service registration
* @return a proxy implementing the {@link IPOJOServiceFactory}
* @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
*/
public Object getService(Bundle arg0, ServiceRegistration arg1) {
Object proxy = Proxy.newProxyInstance(m_manager.getClazz().getClassLoader(),
getSpecificationsWithIPOJOServiceFactory(m_specs, m_manager.getContext()), this);
return proxy;
}
/**
* OSGi Service factory unget method.
* Does nothing.
* @param arg0 the asking bundle
* @param arg1 the service registration
* @param arg2 the service object created for this bundle.
* @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
*/
public void ungetService(Bundle arg0, ServiceRegistration arg1,
Object arg2) { }
/**
* Utility method returning the class array of provided service
* specification and the {@link IPOJOServiceFactory} interface.
* @param specs the published service interface
* @param bc the bundle context, used to load classes
* @return the class array containing provided service specification and
* the {@link IPOJOServiceFactory} class.
*/
private Class[] getSpecificationsWithIPOJOServiceFactory(String[] specs, BundleContext bc) {
Class[] classes = new Class[specs.length + 1];
int i = 0;
for (i = 0; i < specs.length; i++) {
try {
classes[i] = bc.getBundle().loadClass(specs[i]);
} catch (ClassNotFoundException e) {
// Should not happen.
}
}
classes[i] = IPOJOServiceFactory.class;
return classes;
}
}