You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2014/03/18 22:44:31 UTC

svn commit: r1579064 - in /felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl: ResourceAdapterImpl.java ResourceDependencyImpl.java ResourceEventImpl.java

Author: pderop
Date: Tue Mar 18 21:44:31 2014
New Revision: 1579064

URL: http://svn.apache.org/r1579064
Log:
added resource adapter/ resource dependency impl

Added:
    felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceAdapterImpl.java
    felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceDependencyImpl.java
    felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceEventImpl.java

Added: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceAdapterImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceAdapterImpl.java?rev=1579064&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceAdapterImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceAdapterImpl.java Tue Mar 18 21:44:31 2014
@@ -0,0 +1,126 @@
+package dm.impl;
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+
+import dm.Component;
+import dm.ComponentStateListener;
+import dm.Dependency;
+import dm.DependencyManager;
+import dm.ResourceDependency;
+import dm.context.DependencyContext;
+
+/**
+ * Resource adapter service implementation. This class extends the FilterService in order to catch
+ * some Service methods for configuring actual resource adapter service implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResourceAdapterImpl extends FilterComponent {
+    private Object m_callbackInstance = null;
+    private String m_callbackChanged = "changed";
+    private String m_callbackAdded = "setResource";
+    private final String m_resourceFilter;
+    
+    /**
+     * Creates a new Resource Adapter Service implementation.
+     * @param dm the dependency manager used to create our internal adapter service
+     */
+    public ResourceAdapterImpl(DependencyManager dm, String resourceFilter, boolean propagate, Object callbackInstance, String callbackSet, String callbackChanged) {
+        super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
+        m_callbackInstance = callbackInstance;
+        m_callbackAdded = callbackSet;
+        m_callbackChanged = callbackChanged;
+        m_resourceFilter = resourceFilter;
+        m_component.setImplementation(new ResourceAdapterDecorator(propagate))
+            .add(dm.createResourceDependency()
+                 .setFilter(resourceFilter)
+                 .setAutoConfig(false)
+                 .setCallbacks("added", "removed"))
+            .setCallbacks("init", null, "stop", null);
+    }
+    
+    public ResourceAdapterImpl(DependencyManager dm, String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackSet, String callbackChanged) {
+        super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
+        m_callbackInstance = callbackInstance;
+        m_callbackAdded = callbackSet;
+        m_callbackChanged = callbackChanged;
+        m_resourceFilter = resourceFilter;
+        m_component.setImplementation(new ResourceAdapterDecorator(propagateCallbackInstance, propagateCallbackMethod))
+            .add(dm.createResourceDependency()
+                 .setFilter(resourceFilter)
+                 .setAutoConfig(false)
+                 .setCallbacks("added", "removed"))
+            .setCallbacks("init", null, "stop", null);
+    }   
+    
+    public String getName() {
+        return "Resource Adapter" + ((m_resourceFilter != null) ? " with filter " + m_resourceFilter : "");
+    }
+
+    public class ResourceAdapterDecorator extends AbstractDecorator {
+        private final boolean m_propagate;
+        private final Object m_propagateCallbackInstance;
+        private final String m_propagateCallbackMethod;
+
+        public ResourceAdapterDecorator(boolean propagate) {
+            this(propagate, null, null);
+        }
+
+        public ResourceAdapterDecorator(Object propagateCallbackInstance, String propagateCallbackMethod) {
+            this(true, propagateCallbackInstance, propagateCallbackMethod);
+        }
+        
+        private ResourceAdapterDecorator(boolean propagate, Object propagateCallbackInstance, String propagateCallbackMethod) {
+            m_propagate = propagate;
+            m_propagateCallbackInstance = propagateCallbackInstance;
+            m_propagateCallbackMethod = propagateCallbackMethod;
+        }
+
+        public Component createService(Object[] properties) {
+            URL resource = (URL) properties[0]; 
+            Properties props = new Properties();
+            if (m_serviceProperties != null) {
+                Enumeration e = m_serviceProperties.keys();
+                while (e.hasMoreElements()) {
+                    Object key = e.nextElement();
+                    props.put(key, m_serviceProperties.get(key));
+                }
+            }
+            List<DependencyContext> dependencies = m_component.getDependencies();
+            // the first dependency is always the dependency on the resource, which
+            // will be replaced with a more specific dependency below
+            dependencies.remove(0);
+            ResourceDependency resourceDependency = m_manager.createResourceDependency()
+                 .setResource(resource)
+                 .setCallbacks(m_callbackInstance, m_callbackAdded, m_callbackChanged, null)
+                 .setAutoConfig(m_callbackAdded == null)
+                 .setRequired(true);
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                resourceDependency.setPropagate(m_propagateCallbackInstance, m_propagateCallbackMethod);
+            } else {
+                resourceDependency.setPropagate(m_propagate);
+            }
+            Component service = m_manager.createComponent()
+                .setInterface(m_serviceInterfaces, props)
+                .setImplementation(m_serviceImpl)
+                .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
+                .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
+                .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
+                .add(resourceDependency);
+            
+            configureAutoConfigState(service, m_component);
+
+            for (DependencyContext dc : dependencies) {
+                service.add((Dependency) dc.createCopy());
+            }
+
+            for (ComponentStateListener stateListener : m_stateListeners) {
+                service.add(stateListener);
+            }
+            return service;
+        }
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceDependencyImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceDependencyImpl.java?rev=1579064&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceDependencyImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceDependencyImpl.java Tue Mar 18 21:44:31 2014
@@ -0,0 +1,232 @@
+package dm.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+
+import dm.Component;
+import dm.ResourceDependency;
+import dm.ResourceHandler;
+import dm.admin.ComponentDependencyDeclaration;
+import dm.context.DependencyContext;
+import dm.context.Event;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResourceDependencyImpl extends DependencyImpl<ResourceDependency> implements ResourceDependency, ResourceHandler, ComponentDependencyDeclaration {
+    private volatile BundleContext m_context;
+    private volatile ServiceRegistration m_registration;
+    private volatile String m_resourceFilter;
+    private volatile URL m_trackedResource;
+    private final Logger m_logger;
+
+    public ResourceDependencyImpl(BundleContext context, Logger logger) {
+        super(true /* autoconfig */);
+        m_context = context;
+        m_logger = logger;
+    }
+    
+    public ResourceDependencyImpl(ResourceDependencyImpl prototype) {
+        super(prototype);
+        m_context = prototype.m_context;
+        m_resourceFilter = prototype.m_resourceFilter;
+        m_trackedResource = prototype.m_trackedResource;
+        m_logger = prototype.m_logger;
+    }
+    
+    @Override
+    public DependencyContext createCopy() {
+        return new ResourceDependencyImpl(this);
+    }
+    
+    @Override
+    public void start() {
+        boolean wasStarted = isStarted();
+        super.start();
+        if (!wasStarted) {
+            Dictionary props = null;
+            if (m_trackedResource != null) {
+                props = new Properties();
+                props.put(ResourceHandler.URL, m_trackedResource);
+            }
+            else { 
+                if (m_resourceFilter != null) {
+                    props = new Properties();
+                    props.put(ResourceHandler.FILTER, m_resourceFilter);
+                }
+            }
+            m_registration = m_context.registerService(ResourceHandler.class.getName(), this, props);
+        }
+    }
+
+    @Override
+    public void stop() {
+        boolean wasStarted = isStarted();
+        super.stop();
+        if (wasStarted) {
+            m_registration.unregister();
+            m_registration = null;
+        }
+    }
+
+    public void added(URL resource) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            add(new ResourceEventImpl(resource, null));
+        }
+    }
+    
+    public void added(URL resource, Dictionary resourceProperties) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            add(new ResourceEventImpl(resource, resourceProperties));
+        }
+    }
+        
+    public void changed(URL resource) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            change(new ResourceEventImpl(resource, null));
+        }
+    }
+    
+    public void changed(URL resource, Dictionary resourceProperties) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            change(new ResourceEventImpl(resource, resourceProperties));
+        }
+    }
+
+    public void removed(URL resource) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            remove(new ResourceEventImpl(resource, null));
+        }
+    }
+    
+    public void removed(URL resource, Dictionary resourceProperties) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            remove(new ResourceEventImpl(resource, resourceProperties));
+        }
+    }
+    
+    @Override
+    public void invoke(String method, Event e) {
+        ResourceEventImpl re = (ResourceEventImpl) e;
+        URL serviceInstance = re.getResource();
+        Dictionary<?,?> resourceProperties = re.getResourceProperties();
+       
+        m_component.invokeCallbackMethod(getInstances(), method,
+            new Class[][] {
+                    { Component.class, URL.class, Dictionary.class }, 
+                    { Component.class, URL.class },
+                    { Component.class },  
+                    { URL.class, Dictionary.class }, 
+                    { URL.class },
+                    { Object.class }, 
+                    {}},
+            new Object[][] {
+                    { m_component, serviceInstance, resourceProperties }, 
+                    { m_component, serviceInstance }, 
+                    { m_component }, 
+                    { serviceInstance, resourceProperties },
+                    { serviceInstance },
+                    { serviceInstance }, 
+                    {}}
+        );
+
+    }  
+                    
+    public ResourceDependency setResource(URL resource) {
+        m_trackedResource = resource;
+        return this;
+    }
+    
+    public ResourceDependency setFilter(String resourceFilter) {
+        ensureNotActive();
+        m_resourceFilter = resourceFilter;
+        return this;
+    }
+    
+    public ResourceDependency setFilter(String resourceFilter, String resourcePropertiesFilter) {
+        ensureNotActive();
+        m_resourceFilter = resourceFilter;
+        return this;
+    }
+    
+    @Override
+    protected Object getService() {
+        ResourceEventImpl re = (ResourceEventImpl) m_component.getDependencyEvent(this);
+        return re != null ? re.getResource() : null;
+    }
+            
+    @Override
+    public Class<?> getAutoConfigType() {
+        return URL.class;
+    }
+        
+    public Dictionary<?,?> getProperties() {
+        ResourceEventImpl re = (ResourceEventImpl) m_component.getDependencyEvent(this);
+        if (re != null) {
+            URL resource = re.getResource();
+            Dictionary<?,?> resourceProperties = re.getResourceProperties();
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                try {
+                    return (Dictionary<?,?>) InvocationUtil.invokeCallbackMethod(m_propagateCallbackInstance, m_propagateCallbackMethod, new Class[][] {{ URL.class }}, new Object[][] {{ resource }});
+                }
+                catch (InvocationTargetException e) {
+                    m_logger.log(LogService.LOG_WARNING, "Exception while invoking callback method", e.getCause());
+                }
+                catch (Exception e) {
+                    m_logger.log(LogService.LOG_WARNING, "Exception while trying to invoke callback method", e);
+                }
+                throw new IllegalStateException("Could not invoke callback");
+            }
+            else {
+                Properties props = new Properties();
+                props.setProperty(ResourceHandler.HOST, resource.getHost());
+                props.setProperty(ResourceHandler.PATH, resource.getPath());
+                props.setProperty(ResourceHandler.PROTOCOL, resource.getProtocol());
+                props.setProperty(ResourceHandler.PORT, Integer.toString(resource.getPort()));
+                // add the custom resource properties
+                if (resourceProperties != null) {
+                    Enumeration properyKeysEnum = resourceProperties.keys(); 
+                    while (properyKeysEnum.hasMoreElements()) {
+                        String key = (String) properyKeysEnum.nextElement();
+                        if (!key.equals(ResourceHandler.HOST) &&
+                                !key.equals(ResourceHandler.PATH) &&
+                                !key.equals(ResourceHandler.PROTOCOL) &&
+                                !key.equals(ResourceHandler.PORT)) {
+                            props.setProperty(key, resourceProperties.get(key).toString());
+                        } else {
+                            m_logger.log(LogService.LOG_WARNING, "Custom resource property is overlapping with the default resource property for key: " + key);
+                        }
+                    }
+                }
+                return props;
+            }
+        }
+        else {
+            throw new IllegalStateException("cannot find resource");
+        }
+    }
+
+    @Override
+    public String getName() {
+        StringBuilder sb = new StringBuilder();
+        if (m_resourceFilter != null) {
+            sb.append(m_resourceFilter);
+        }
+        if (m_trackedResource != null) {
+            sb.append(m_trackedResource.toString());
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String getType() {
+        return "resource";
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceEventImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceEventImpl.java?rev=1579064&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceEventImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ResourceEventImpl.java Tue Mar 18 21:44:31 2014
@@ -0,0 +1,68 @@
+package dm.impl;
+
+import java.net.URL;
+import java.util.Dictionary;
+
+public class ResourceEventImpl extends EventImpl implements Comparable {
+    final URL m_resource;
+    final Dictionary<?, ?> m_resourceProperties;
+    
+    public ResourceEventImpl(URL resource, Dictionary<?,?> resourceProperties) {
+        m_resource = resource;
+        m_resourceProperties = resourceProperties;
+    }
+    
+    public URL getResource() {
+        return m_resource;
+    }
+    
+    public Dictionary<?, ?> getResourceProperties() {
+        return m_resourceProperties;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ResourceEventImpl) {
+            ResourceEventImpl r1 = this;
+            ResourceEventImpl r2 = (ResourceEventImpl) obj;
+            boolean match = r1.getResource().equals(r2.getResource());
+            if (match) {
+                Dictionary<?,?> d1 = getResourceProperties();
+                Dictionary<?,?> d2 = r2.getResourceProperties();
+
+                if (d1 == null && d2 == null) {
+                    return match;
+                }
+                
+                if (d1 == null && d2 != null) {
+                    return false;
+                }
+                
+                if (d1 != null && d2 == null) {
+                    return false;
+                }
+                return d1.equals(d2);
+            }
+        }
+        return false;
+    }
+    
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + getResource().hashCode();
+        result = prime * result + ((getResourceProperties() == null) ? 0 : getResourceProperties().hashCode());
+        return result;
+    }
+
+    @Override
+    public int compareTo(Object that) {
+        if (this.equals(that)) {
+            return 0;
+        }
+        
+        // Sort by resource name.
+        return getResource().toString().compareTo(that.toString());
+    }
+}