Author: [email protected]
Date: Tue Dec 20 12:12:59 2011
New Revision: 1860

Log:
AMDATU-472 Processed review feedback and minimized holding locks while taking 
to osgi

Added:
   
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetaTypeArtifactInstaller.java
      - copied, changed from r1851, 
/trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetatypeArtifactInstaller.java
Removed:
   
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetatypeArtifactInstaller.java
Modified:
   
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/AttributeDefinitionImpl.java
   
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetaTypeFileInstall.java

Modified: 
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/AttributeDefinitionImpl.java
==============================================================================
--- 
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/AttributeDefinitionImpl.java
     (original)
+++ 
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/AttributeDefinitionImpl.java
     Tue Dec 20 12:12:59 2011
@@ -19,7 +19,7 @@
 import org.osgi.service.metatype.AttributeDefinition;
 
 /**
- * Copy if org.apache.felix.deployment.rp.autoconf.AttributeDefinitionImpl
+ * Copy of org.apache.felix.deployment.rp.autoconf.AttributeDefinitionImpl
  */
 public class AttributeDefinitionImpl implements AttributeDefinition {
 

Copied: 
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetaTypeArtifactInstaller.java
 (from r1851, 
/trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetatypeArtifactInstaller.java)
==============================================================================
--- 
/trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetatypeArtifactInstaller.java
  (original)
+++ 
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetaTypeArtifactInstaller.java
   Tue Dec 20 12:12:59 2011
@@ -45,14 +45,20 @@
 import org.osgi.service.metatype.MetaTypeService;
 import org.osgi.service.metatype.ObjectClassDefinition;
 
-public final class MetatypeArtifactInstaller implements ArtifactInstaller {
+/**
+ * FileInstall artifact installer extension that can handle metatype and pass 
the configuration off to an instance
+ * of ConfigurationAdmin.
+ * 
+ * @author <a href="mailto:[email protected]";>Amdatu Project 
Team</a>
+ */
+public final class MetaTypeArtifactInstaller implements ArtifactInstaller {
 
     private final BundleContext m_bundleContext;
     private final ConfigurationAdmin m_configAdmin;
     private final MetaTypeService m_metaTypeService;
     private final Logger m_logger;
 
-    public MetatypeArtifactInstaller(BundleContext bundleContext, 
ConfigurationAdmin configAdmin,
+    public MetaTypeArtifactInstaller(BundleContext bundleContext, 
ConfigurationAdmin configAdmin,
         MetaTypeService metaTypeService, Logger logger) {
         m_bundleContext = bundleContext;
         m_configAdmin = configAdmin;
@@ -60,6 +66,9 @@
         m_logger = logger;
     }
 
+    /**
+     * @see 
org.apache.felix.fileinstall.ArtifactListener#canHandle(java.io.File)
+     */
     public boolean canHandle(File artifact) {
         if (!artifact.getName().endsWith(".xml")) {
             return false;
@@ -75,6 +84,9 @@
         return metaData != null;
     }
 
+    /**
+     * @see 
org.apache.felix.fileinstall.ArtifactInstaller#install(java.io.File)
+     */
     public void install(File artifact) throws Exception {
         m_logger.log(LogService.LOG_DEBUG,
             "Installing metatype configuration file " + artifact.getName());
@@ -137,11 +149,11 @@
                         + designate.getPid() + ")");
                 if (configurations != null && configurations.length > 0) {
 
+                    configuration = configurations[0];
                     m_logger.log(
                         LogService.LOG_DEBUG,
                         "Using existing factory configuration " + 
configuration.getPid() + " for designate with pid "
                             + designate.getPid());
-                    configuration = configurations[0];
                 }
                 else {
 
@@ -166,6 +178,9 @@
         }
     }
 
+    /**
+     * @see org.apache.felix.fileinstall.ArtifactInstaller#update(java.io.File)
+     */
     public void update(File artifact) throws Exception {
         m_logger.log(LogService.LOG_DEBUG,
             "Updating metatype configuration file " + artifact.getName());
@@ -174,6 +189,9 @@
         install(artifact);
     }
 
+    /**
+     * @see 
org.apache.felix.fileinstall.ArtifactInstaller#uninstall(java.io.File)
+     */
     public void uninstall(File artifact) throws Exception {
         m_logger.log(LogService.LOG_DEBUG,
             "Uninstalling metatype configuration file " + artifact.getName());

Modified: 
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetaTypeFileInstall.java
==============================================================================
--- 
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetaTypeFileInstall.java
 (original)
+++ 
trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetaTypeFileInstall.java
 Tue Dec 20 12:12:59 2011
@@ -32,8 +32,12 @@
 import org.osgi.util.tracker.ServiceTracker;
 
 /**
- * A plugin for FileInstall that can handle MetaType files.
+ * FileInstall extension that handles metatype artifacts by handing them off 
to all available {@link ConfigurationAdmin} services.
+ * <br/>
+ * At least one {@link MetaTypeService} service registration must be available 
for this extension
+ * to work.
  * 
+ * @author <a href="mailto:[email protected]";>Amdatu Project 
Team</a>
  */
 public final class MetaTypeFileInstall implements BundleActivator {
 
@@ -59,11 +63,12 @@
     };
 
     private BundleContext m_bundleContext;
-    private ServiceTracker m_configAdminAdaptor;
+    private ServiceTracker m_configurationAdminAdaptor;
     private ServiceTracker m_logServiceTracker;
     private ServiceTracker m_metaTypeServiceTracker;
 
     public void start(BundleContext bundleContext) throws Exception {
+
         m_bundleContext = bundleContext;
 
         m_logServiceTracker = new ServiceTracker(bundleContext, 
LogService.class.getName(), null);
@@ -71,60 +76,126 @@
 
         m_metaTypeServiceTracker = new ServiceTracker(bundleContext, 
MetaTypeService.class.getName(), null) {
 
-            private volatile ServiceReference m_metaTypeServiceRef;
-
-            public Object addingService(ServiceReference metaTypeServiceRef) {
+            private volatile ServiceReference m_metaTypeServiceReference;
 
-                MetaTypeService metaTypeService = (MetaTypeService) 
super.addingService(metaTypeServiceRef);
-                if (metaTypeService == null)
+            /**
+             * @see 
org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
+             */
+            public Object addingService(ServiceReference 
metaTypeServicereference) {
+                MetaTypeService metaTypeService = (MetaTypeService) 
context.getService(metaTypeServicereference);
+                if (metaTypeService == null) {
                     return null;
-
-                if (m_metaTypeServiceRef == null || 
metaTypeServiceRef.compareTo(m_metaTypeServiceRef) > 0) {
-                    m_metaTypeServiceRef = metaTypeServiceRef;
-                    if (m_configAdminAdaptor != null)
-                        m_configAdminAdaptor.close();
-                    m_configAdminAdaptor = new 
ConfigAdminAdaptor(m_bundleContext, metaTypeService, m_logger);
-                    m_configAdminAdaptor.open();
                 }
+                ServiceTracker closeConfigurationAdminAdaptor = null;
+                ServiceTracker openConfigurationAdminAdaptor = null;
+                synchronized (this) {
+                    if (m_metaTypeServiceReference == null
+                        || 
metaTypeServicereference.compareTo(m_metaTypeServiceReference) > 0) {
+                        m_metaTypeServiceReference = metaTypeServicereference;
+                        if (m_configurationAdminAdaptor != null) {
+                            closeConfigurationAdminAdaptor = 
m_configurationAdminAdaptor;
+                            m_configurationAdminAdaptor = null;
+                        }
+                        m_configurationAdminAdaptor =
+                            new ConfigAdminAdaptor(m_bundleContext, 
metaTypeService, m_logger);
+                        openConfigurationAdminAdaptor = 
m_configurationAdminAdaptor;
+                    }
+                }
+                safeCloseAdaptor(closeConfigurationAdminAdaptor);
+                safeOpenAdaptor(openConfigurationAdminAdaptor);
                 return metaTypeService;
             }
 
-            public void modifiedService(ServiceReference metaTypeServiceRef, 
Object service) {
-                // TODO handle ranking change?
+            /**
+             * @see 
org.osgi.util.tracker.ServiceTracker#modifiedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
+             */
+            public void modifiedService(ServiceReference 
metaTypeServiceReference, Object service) {
+                updateToHighestTrackedService();
+            }
+
+            /**
+             * @see 
org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
+             */
+            public void removedService(ServiceReference 
metaTypeServiceReference, Object service) {
+                context.ungetService(metaTypeServiceReference);
+                updateToHighestTrackedService();
             }
 
-            public void removedService(ServiceReference metaTypeServiceRef, 
Object service) {
-                super.removedService(metaTypeServiceRef, service);
-                if (metaTypeServiceRef == m_metaTypeServiceRef) {
-                    if (m_configAdminAdaptor != null)
-                        m_configAdminAdaptor.close();
-
-                    m_metaTypeServiceRef = getServiceReference();
-                    if (m_metaTypeServiceRef != null) {
-                        MetaTypeService metaTypeService = (MetaTypeService) 
getService(m_metaTypeServiceRef);
-                        m_configAdminAdaptor = new 
ConfigAdminAdaptor(m_bundleContext, metaTypeService, m_logger);
-                        m_configAdminAdaptor.open();
+            private void updateToHighestTrackedService() {
+                ServiceTracker closeConfigurationAdminAdaptor = null;
+                ServiceTracker openConfigurationAdminAdaptor = null;
+                synchronized (this) {
+                    ServiceReference highestRankedServiceReference = 
getServiceReference();
+                    MetaTypeService metaTypeService = null;
+                    if (highestRankedServiceReference != null) {
+                        metaTypeService = (MetaTypeService) getService();
                     }
+                    if (highestRankedServiceReference == null || 
metaTypeService == null) {
+                        m_metaTypeServiceReference = null;
+                        if (m_configurationAdminAdaptor != null) {
+                            closeConfigurationAdminAdaptor = 
m_configurationAdminAdaptor;
+                            m_configurationAdminAdaptor = null;
+                        }
+                    }
+                    else {
+                        if (m_metaTypeServiceReference == null
+                            || 
highestRankedServiceReference.compareTo(m_metaTypeServiceReference) > 0) {
+
+                            m_metaTypeServiceReference = 
highestRankedServiceReference;
+                            if (m_configurationAdminAdaptor != null) {
+                                closeConfigurationAdminAdaptor = 
m_configurationAdminAdaptor;
+                                m_configurationAdminAdaptor = null;
+                            }
+                            m_configurationAdminAdaptor =
+                                new ConfigAdminAdaptor(m_bundleContext, 
metaTypeService, m_logger);
+                            openConfigurationAdminAdaptor = 
m_configurationAdminAdaptor;
+                        }
+                    }
+                }
+                safeCloseAdaptor(closeConfigurationAdminAdaptor);
+                safeOpenAdaptor(openConfigurationAdminAdaptor);
+            }
+
+            private void safeOpenAdaptor(ServiceTracker adaptor) {
+                if (adaptor == null) {
+                    return;
+                }
+                try {
+                    adaptor.open();
+                }
+                catch (Exception e) {
+                    m_logger.log(LogService.LOG_WARNING, "Unexpected exception 
during close", e);
+                }
+            }
+
+            private void safeCloseAdaptor(ServiceTracker adaptor) {
+                if (adaptor == null) {
+                    return;
+                }
+                try {
+                    adaptor.close();
+                }
+                catch (Exception e) {
+                    m_logger.log(LogService.LOG_WARNING, "Unexpected exception 
during close", e);
                 }
             }
         };
+
         m_metaTypeServiceTracker.open();
     }
 
     public void stop(BundleContext context) throws Exception {
         m_metaTypeServiceTracker.close();
+        m_metaTypeServiceTracker = null;
         m_logServiceTracker.close();
+        m_logServiceTracker = null;
     }
 
     public void log(int level, String message) {
-        if (m_logServiceTracker == null)
-            return;
         log(level, message, null);
     }
 
     public void log(int level, String message, Throwable exception) {
-        if (m_logServiceTracker == null)
-            return;
         Object[] services = m_logServiceTracker.getServices();
         if (services != null) {
             for (int i = 0; i < services.length; i++) {
@@ -139,8 +210,7 @@
         private final MetaTypeService m_metaTypeService;
         private final Logger m_logger;
 
-        private final Map m_configAdminRefs = new HashMap();
-        private final Map m_installerRegs = new HashMap();
+        private final Map m_configAdminReferences = new HashMap();
 
         public ConfigAdminAdaptor(BundleContext bundleContext, MetaTypeService 
metaTypeService, Logger logger) {
             super(bundleContext, ConfigurationAdmin.class.getName(), null);
@@ -149,61 +219,140 @@
             m_logger = logger;
         }
 
+        /**
+         * Register a new installer when a new reference is added.
+         * 
+         * @see 
org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
+         */
         public Object addingService(ServiceReference reference) {
+
             ConfigurationAdmin configAdmin = (ConfigurationAdmin) 
super.addingService(reference);
-            synchronized (m_configAdminRefs) {
-                if (!m_configAdminRefs.containsKey(reference)) {
-                    m_logger.log(LogService.LOG_INFO,
-                        "Registering metatype installer for ConfigurationAdmin 
with service.id "
-                            + reference.getProperty(Constants.SERVICE_ID));
-                    registerMetatypeArtifactInstaller(reference, configAdmin);
+
+            boolean registerInstaller = false;
+            synchronized (this) {
+                if (!m_configAdminReferences.containsKey(reference)) {
+                    m_configAdminReferences.put(reference, null);
+                    registerInstaller = true;
+                }
+            }
+
+            if (registerInstaller) {
+
+                m_logger.log(LogService.LOG_INFO,
+                    "Registering metatype installer for ConfigurationAdmin 
with service.id "
+                        + reference.getProperty(Constants.SERVICE_ID));
+
+                ServiceRegistration installerRegistration = 
safeRegisterMetaTypeArtifactInstaller(configAdmin);
+
+                boolean unregisterInstaller = false;
+                synchronized (this) {
+                    if (m_configAdminReferences.containsKey(reference)) {
+                        m_configAdminReferences.put(reference, 
installerRegistration);
+                    }
+                    else {
+                        unregisterInstaller = true;
+                    }
+                }
+                if (unregisterInstaller) {
+                    
safeUnregisterMetaTypeArtifactInstaller(installerRegistration);
                 }
             }
             return configAdmin;
         }
 
+        /**
+         * Try to unregister and then register a new installer when a 
reference is modified.
+         * 
+         * @see 
org.osgi.util.tracker.ServiceTracker#modifiedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
+         */
         public void modifiedService(ServiceReference reference, Object 
service) {
-            synchronized (m_configAdminRefs) {
-                if (m_configAdminRefs.containsKey(reference)) {
-                    m_logger.log(LogService.LOG_INFO,
-                        "Updating metatype installer for ConfigurationAdmin 
with service.id "
-                            + reference.getProperty(Constants.SERVICE_ID));
-                    unregisterMetatypeArtifactInstaller(reference);
-                    registerMetatypeArtifactInstaller(reference, 
(ConfigurationAdmin) service);
+
+            ConfigurationAdmin configAdmin = (ConfigurationAdmin) service;
+
+            ServiceRegistration installerRegistration = null;
+            synchronized (this) {
+                installerRegistration = (ServiceRegistration) 
m_configAdminReferences.get(reference);
+                m_configAdminReferences.put(reference, null);
+            }
+
+            if (installerRegistration != null) {
+
+                m_logger.log(LogService.LOG_INFO,
+                    "Unregistering metatype installer for ConfigurationAdmin 
with service.id "
+                        + reference.getProperty(Constants.SERVICE_ID));
+
+                safeUnregisterMetaTypeArtifactInstaller(installerRegistration);
+            }
+
+            m_logger.log(LogService.LOG_INFO,
+                "Registering metatype installer for ConfigurationAdmin with 
service.id "
+                    + reference.getProperty(Constants.SERVICE_ID));
+
+            installerRegistration = 
safeRegisterMetaTypeArtifactInstaller(configAdmin);
+
+            boolean unregisterInstaller = false;
+            synchronized (this) {
+                if (m_configAdminReferences.containsKey(reference)) {
+                    m_configAdminReferences.put(reference, 
installerRegistration);
                 }
+                else {
+                    unregisterInstaller = true;
+                }
+            }
+            if (unregisterInstaller) {
+                safeUnregisterMetaTypeArtifactInstaller(installerRegistration);
             }
         }
 
+        /**
+         * Remove the installer when a reference is removed.
+         * 
+         * @see 
org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
+         */
         public void removedService(ServiceReference reference, Object service) 
{
-            synchronized (m_configAdminRefs) {
-                if (m_configAdminRefs.containsKey(reference)) {
-                    m_logger.log(LogService.LOG_INFO,
-                        "Unregistering metatype installer for 
ConfigurationAdmin with service.id "
-                            + reference.getProperty(Constants.SERVICE_ID));
-                    unregisterMetatypeArtifactInstaller(reference);
-                }
-            }
+
             super.removedService(reference, service);
+            ServiceRegistration installerRegistration = null;
+
+            synchronized (this) {
+                installerRegistration = (ServiceRegistration) 
m_configAdminReferences.remove(reference);
+            }
+
+            if (installerRegistration != null) {
+                m_logger.log(LogService.LOG_INFO,
+                    "Unregistering metatype installer for ConfigurationAdmin 
with service.id "
+                        + reference.getProperty(Constants.SERVICE_ID));
+                safeUnregisterMetaTypeArtifactInstaller(installerRegistration);
+            }
         }
 
-        private void registerMetatypeArtifactInstaller(ServiceReference 
reference, ConfigurationAdmin configAdmin) {
-            MetatypeArtifactInstaller installer = new 
MetatypeArtifactInstaller(m_bundleContext, configAdmin,
-                m_metaTypeService, m_logger);
-            ServiceRegistration installerReg = m_bundleContext.registerService(
-                new String[] {
-                    ArtifactListener.class.getName(),
-                    ArtifactInstaller.class.getName()
-                },
-                installer, new Properties());
-            m_configAdminRefs.put(reference, installerReg);
-            m_installerRegs.put(installerReg, installer);
-        }
-
-        private void unregisterMetatypeArtifactInstaller(ServiceReference 
reference) {
-            ServiceRegistration installerReg = (ServiceRegistration) 
m_configAdminRefs.remove(reference);
-            m_installerRegs.remove(installerReg);
-            installerReg.unregister();
+        private ServiceRegistration 
safeRegisterMetaTypeArtifactInstaller(ConfigurationAdmin configurationAdmin) {
+            ServiceRegistration installerRegistration = null;
+            try {
+                installerRegistration =
+                    m_bundleContext
+                        .registerService(
+                            new String[] {
+                                ArtifactListener.class.getName(),
+                                ArtifactInstaller.class.getName()
+                            },
+                            new MetaTypeArtifactInstaller(m_bundleContext, 
configurationAdmin, m_metaTypeService,
+                                m_logger),
+                            new Properties());
+            }
+            catch (Exception e) {
+                m_logger.log(LogService.LOG_WARNING, "Unexpected exception 
during register", e);
+            }
+            return installerRegistration;
         }
-    };
 
+        private void 
safeUnregisterMetaTypeArtifactInstaller(ServiceRegistration 
installerRegistration) {
+            try {
+                installerRegistration.unregister();
+            }
+            catch (Exception e) {
+                m_logger.log(LogService.LOG_WARNING, "Unexpected exception 
during unregister", e);
+            }
+        }
+    };
 }
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to