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:34:43 UTC

svn commit: r1579054 - /felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/BundleDependencyImpl.java

Author: pderop
Date: Tue Mar 18 21:34:43 2014
New Revision: 1579054

URL: http://svn.apache.org/r1579054
Log:
added Bundle Dependency impl

Added:
    felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/BundleDependencyImpl.java

Added: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/BundleDependencyImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/BundleDependencyImpl.java?rev=1579054&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/BundleDependencyImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/BundleDependencyImpl.java Tue Mar 18 21:34:43 2014
@@ -0,0 +1,247 @@
+package dm.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.log.LogService;
+
+import tracker.BundleTracker;
+import tracker.BundleTrackerCustomizer;
+import dm.BundleDependency;
+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 BundleDependencyImpl extends DependencyImpl<BundleDependency> implements BundleDependency, BundleTrackerCustomizer, ComponentDependencyDeclaration {
+    private final BundleContext m_context;
+    private BundleTracker m_tracker;
+    private int m_stateMask = Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE;
+    private Bundle m_bundleInstance;
+    private Filter m_filter;
+    private long m_bundleId = -1;
+    private Object m_nullObject;
+    private boolean m_propagate;
+    private Object m_propagateCallbackInstance;
+    private String m_propagateCallbackMethod;
+    private final Logger m_logger;
+
+    public BundleDependencyImpl(BundleContext context, Logger logger) {
+        super(true /* autoconfig */);
+        m_context = context;
+        m_logger = logger;
+    }
+    
+    public BundleDependencyImpl(BundleDependencyImpl prototype) {
+        super(prototype);
+        m_logger = prototype.m_logger;
+        m_context = prototype.m_context;
+        m_stateMask = prototype.m_stateMask;
+        m_nullObject = prototype.m_nullObject;
+        m_bundleInstance = prototype.m_bundleInstance;
+        m_filter = prototype.m_filter;
+        m_bundleId = prototype.m_bundleId;
+        m_propagate = prototype.m_propagate;
+        m_propagateCallbackInstance = prototype.m_propagateCallbackInstance;
+        m_propagateCallbackMethod = prototype.m_propagateCallbackMethod;       
+    }
+    
+    @Override
+    public DependencyContext createCopy() {
+        return new BundleDependencyImpl(this);
+    }
+    
+    @Override
+    public void start() {
+        boolean wasStarted = isStarted();
+        super.start();
+        if (!wasStarted) {
+            m_tracker = new BundleTracker(m_context, m_stateMask, this);
+            m_tracker.open();
+        }
+    }
+
+    @Override
+    public void stop() {
+        boolean wasStarted = isStarted();
+        super.stop();
+        if (wasStarted) {
+            m_tracker.close();
+            m_tracker = null;
+        }            
+    }
+
+    @Override
+    public String getName() {
+        StringBuilder sb = new StringBuilder();
+        if ((m_stateMask & Bundle.ACTIVE) != 0) {
+            sb.append("active ");
+        }
+        if ((m_stateMask & Bundle.INSTALLED) != 0) {
+            sb.append("installed ");
+        }
+        if ((m_stateMask & Bundle.RESOLVED) != 0) {
+            sb.append("resolved ");
+        }
+        if (m_filter != null) {
+            sb.append(m_filter.toString());
+        }
+        if (m_bundleId != -1) {
+            sb.append("bundle.id=" + m_bundleId);
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String getType() {
+        return "bundle";
+    }
+
+    public Object addingBundle(Bundle bundle, BundleEvent event) {
+        // if we don't like a bundle, we could reject it here by returning null
+        long bundleId = bundle.getBundleId();
+        if (m_bundleId >= 0 && m_bundleId != bundleId) {
+            return null;
+        }
+        Filter filter = m_filter;
+        if (filter != null) {
+            Dictionary<?,?> headers = bundle.getHeaders();
+            if (!m_filter.match(headers)) {
+                return null;
+            }
+        }
+        return bundle;
+    }
+    
+    public void addedBundle(Bundle bundle, BundleEvent event, Object object) {
+        add(new BundleEventImpl(bundle, event));
+    }
+        
+    public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+        change(new BundleEventImpl(bundle, event));
+    }
+
+    public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+        remove(new BundleEventImpl(bundle, event));
+    }
+    
+    @Override
+    public void invoke(String method, Event e) {
+        BundleEventImpl be = (BundleEventImpl) e;
+        m_component.invokeCallbackMethod(getInstances(), method,
+            new Class[][] {{Bundle.class}, {Object.class}, {}},             
+            new Object[][] {{be.getBundle()}, {be.getBundle()}, {}}
+        );
+    }  
+        
+    public BundleDependency setBundle(Bundle bundle) {
+        m_bundleId = bundle.getBundleId();
+        return this;
+    }
+
+    public BundleDependency setFilter(String filter) throws IllegalArgumentException {
+        if (filter != null) {
+            try {
+                m_filter = m_context.createFilter(filter);
+            } 
+            catch (InvalidSyntaxException e) {
+                throw new IllegalArgumentException(e.getMessage());
+            }
+        }
+        return this;
+    }
+    
+    public BundleDependency setStateMask(int mask) {
+        m_stateMask = mask;
+        return this;
+    }
+    
+    @Override
+    public Object getAutoConfigInstance() {
+        return getService();
+    }
+
+    @Override
+    public Class<?> getAutoConfigType() {
+        return Bundle.class;
+    }
+    
+    @Override
+    public Dictionary<?,?> getProperties() {
+        Bundle bundle = (Bundle) getService();
+        if (bundle != null) {
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                try {
+                    return (Dictionary<?,?>) InvocationUtil.invokeCallbackMethod(m_propagateCallbackInstance, m_propagateCallbackMethod, new Class[][] {{ Bundle.class }}, new Object[][] {{ bundle }});
+                }
+                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 {
+                return bundle.getHeaders();
+            }
+        }
+        else {
+            throw new IllegalStateException("cannot find bundle");
+        }
+    }
+    
+    @Override
+    protected Object getService() {
+        Bundle service = null;
+        if (isStarted()) {
+            BundleEventImpl be = (BundleEventImpl) m_component.getDependencyEvent(this);
+            return be != null ? be.getBundle() : null;
+        }
+        else {
+            Bundle[] bundles = m_context.getBundles();
+            for (int i = 0; i < bundles.length; i++) {
+                if ((bundles[i].getState() & m_stateMask) > 0) {
+                    Filter filter = m_filter;
+                    if (filter == null) {
+                        service = bundles[i];
+                        break;
+                    }
+                    else if (filter.match(bundles[i].getHeaders())) {
+                        service = bundles[i];
+                        break;
+                    }
+                }
+            }
+        }
+        if (service == null && isAutoConfig()) {
+            // TODO does it make sense to add support for custom bundle impls?
+//            service = getDefaultImplementation();
+            if (service == null) {
+                service = getNullObject();
+            }
+        }
+        return service;
+    }
+    
+    private Bundle getNullObject() {
+        if (m_nullObject == null) {
+            try {
+                m_nullObject = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Bundle.class }, new DefaultNullObject()); 
+            }
+            catch (Exception e) {
+                m_logger.log(Logger.LOG_ERROR, "Could not create null object for Bundle.", e);
+            }
+        }
+        return (Bundle) m_nullObject;
+    }
+}
+