Author: marrs
Date: Tue Feb  7 19:17:35 2012
New Revision: 1241558

URL: http://svn.apache.org/viewvc?rev=1241558&view=rev
Log:
FELIX-3329 FELIX-3330 Implemented support for deferred as well as multiple 
configuration admins. Deferred configuration admin services can be started and 
will be considered until the deployment session ends. Filtering can be done by 
adding an optional attribute to the <MetaData> tag with a filtercondition which 
will be applied on the configuration admin service. If it matches, or if there 
is no such filter, the configuration will be applied.

Modified:
    felix/trunk/deploymentadmin/autoconf/pom.xml
    
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/Activator.java
    
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResource.java
    
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResourceProcessor.java
    
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/PersistencyManager.java

Modified: felix/trunk/deploymentadmin/autoconf/pom.xml
URL: 
http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/pom.xml?rev=1241558&r1=1241557&r2=1241558&view=diff
==============================================================================
--- felix/trunk/deploymentadmin/autoconf/pom.xml (original)
+++ felix/trunk/deploymentadmin/autoconf/pom.xml Tue Feb  7 19:17:35 2012
@@ -57,7 +57,7 @@
         <dependency>
             <groupId>${pom.groupId}</groupId>
             <artifactId>org.apache.felix.metatype</artifactId>
-            <version>1.0.4</version>
+            <version>1.0.5-SNAPSHOT</version>
         </dependency>
     </dependencies>
     <build>

Modified: 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/Activator.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/Activator.java?rev=1241558&r1=1241557&r2=1241558&view=diff
==============================================================================
--- 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/Activator.java
 (original)
+++ 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/Activator.java
 Tue Feb  7 19:17:35 2012
@@ -25,8 +25,9 @@ import org.apache.felix.dm.DependencyAct
 import org.apache.felix.dm.DependencyManager;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
-import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.deploymentadmin.spi.ResourceProcessor;
+import org.osgi.service.event.EventConstants;
+import org.osgi.service.event.EventHandler;
 import org.osgi.service.log.LogService;
 import org.osgi.service.metatype.MetaTypeService;
 
@@ -38,14 +39,12 @@ public class Activator extends Dependenc
     public void init(BundleContext context, DependencyManager manager) throws 
Exception {
        Dictionary properties = new Properties();
         properties.put(Constants.SERVICE_PID, 
"org.osgi.deployment.rp.autoconf");
+        properties.put(EventConstants.EVENT_TOPIC, 
org.apache.felix.deploymentadmin.Constants.EVENTTOPIC_COMPLETE);
         
         manager.add(createComponent()
-            .setInterface(ResourceProcessor.class.getName(), properties)
+            .setInterface(new String[] { ResourceProcessor.class.getName(), 
EventHandler.class.getName() }, properties)
             .setImplementation(AutoConfResourceProcessor.class)
             .add(createServiceDependency()
-                .setService(ConfigurationAdmin.class)
-                .setRequired(true))
-            .add(createServiceDependency()
                 .setService(MetaTypeService.class)
                 .setRequired(false))
             .add(createServiceDependency()

Modified: 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResource.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResource.java?rev=1241558&r1=1241557&r2=1241558&view=diff
==============================================================================
--- 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResource.java
 (original)
+++ 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResource.java
 Tue Feb  7 19:17:35 2012
@@ -31,12 +31,15 @@ public class AutoConfResource implements
        private final String m_bundleLoc;
        private final boolean m_merge;
        private final String m_name;
+       private final String m_filter;
 
        private String m_alias = null;
+
        
-       public AutoConfResource(String name, String pid, String factoryPid, 
String bundleLocation, boolean merge, Dictionary properties) {
+       public AutoConfResource(String name, String pid, String factoryPid, 
String bundleLocation, boolean merge, Dictionary properties, String filter) {
                m_name = name;
                m_pid = pid;
+        m_filter = filter;
                m_factoryPid = (factoryPid == null) ? "" : factoryPid;
                m_bundleLoc = bundleLocation;
                m_merge = merge;
@@ -50,6 +53,10 @@ public class AutoConfResource implements
        public String getPid() {
                return m_pid;
        }
+       
+       public String getFilter() {
+        return m_filter;
+    }
 
        /**
         * Returns empty string if this configuration is not a factory 
configuration, otherwise the factory

Modified: 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResourceProcessor.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResourceProcessor.java?rev=1241558&r1=1241557&r2=1241558&view=diff
==============================================================================
--- 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResourceProcessor.java
 (original)
+++ 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResourceProcessor.java
 Tue Feb  7 19:17:35 2012
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -33,6 +34,10 @@ import java.util.Map;
 import java.util.Set;
 import java.util.Vector;
 
+import org.apache.felix.deploymentadmin.Constants;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ServiceDependency;
 import org.apache.felix.metatype.Attribute;
 import org.apache.felix.metatype.Designate;
 import org.apache.felix.metatype.MetaData;
@@ -40,11 +45,16 @@ import org.apache.felix.metatype.MetaDat
 import org.apache.felix.metatype.OCD;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
 import org.osgi.service.cm.Configuration;
 import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.deploymentadmin.spi.DeploymentSession;
 import org.osgi.service.deploymentadmin.spi.ResourceProcessor;
 import org.osgi.service.deploymentadmin.spi.ResourceProcessorException;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
 import org.osgi.service.log.LogService;
 import org.osgi.service.metatype.AttributeDefinition;
 import org.osgi.service.metatype.MetaTypeInformation;
@@ -52,21 +62,27 @@ import org.osgi.service.metatype.MetaTyp
 import org.osgi.service.metatype.ObjectClassDefinition;
 import org.xmlpull.v1.XmlPullParserException;
 
-public class AutoConfResourceProcessor implements ResourceProcessor {
-
-       private static final String LOCATION_PREFIX = "osgi-dp:";
-       
-       private volatile LogService m_log;                                      
// injected by dependency manager
-       private volatile ConfigurationAdmin m_configAdmin;      // injected by 
dependency manager
-       private volatile MetaTypeService m_metaService;         // injected by 
dependency manager
-       private volatile BundleContext m_bc;                            // 
injected by dependency manager
+public class AutoConfResourceProcessor implements ResourceProcessor, 
EventHandler {
+    private static final String LOCATION_PREFIX = "osgi-dp:";
+    public static final String CONFIGURATION_ADMIN_FILTER_ATTRIBUTE = "filter";
+
+       // dependencies injected by Dependency Manager
+       private volatile LogService m_log;
+       private volatile ConfigurationAdmin m_configAdmin;
+       private volatile MetaTypeService m_metaService;
+       private volatile BundleContext m_bc;
+       private volatile Component m_component;
        
+       private final Object LOCK = new Object(); // protects the members below
+
        private DeploymentSession m_session = null;
-       private Map m_toBeInstalled = new HashMap(); // Map<String, 
List<AutoConfResource>>
-       private Map m_toBeDeleted = new HashMap();
+       private final Map m_toBeInstalled = new HashMap(); // Map<String, 
List<AutoConfResource>>
+       private final Map m_toBeDeleted = new HashMap();
        
        private PersistencyManager m_persistencyManager;
 
+    private ServiceDependency m_configurationAdminDependency;
+
        public void start() throws IOException {
                File root = m_bc.getDataFile("");
                if (root == null) {
@@ -76,70 +92,89 @@ public class AutoConfResourceProcessor i
        }
        
     public void begin(DeploymentSession session) {
-           m_session = session;
+        synchronized (LOCK) {
+            if (m_session != null) {
+                throw new IllegalArgumentException("Trying to begin new 
deployment session while already in one.");
+            }
+            if (session == null) {
+                throw new IllegalArgumentException("Trying to begin new 
deployment session with a null session.");
+            }
+            m_session = session;
+            m_toBeInstalled.clear();
+            m_toBeDeleted.clear();
+        }
     }
  
     public void process(String name, InputStream stream) throws 
ResourceProcessorException {
-          
-          // initial validation
-          if (m_session == null) {
-                  throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can 
not process resource without a Deployment Session");
-          }
-          MetaDataReader reader = new MetaDataReader();
-          MetaData data = null;
-          try {
-                  data = reader.parse(stream);
-          } catch (IOException e) {
-                  throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Unable 
to process resource.", e);
-          } catch (XmlPullParserException e) {
-                  throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, 
"Supplied configuration is not conform the metatype xml specification.", e);
-          }
-          if (data == null) {
-                  throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, 
"Supplied configuration is not conform the metatype xml specification.");
-          }
-
-          // process resources
-          Map designates = data.getDesignates();
-          if (designates == null) {
-              // if there are no designates, there's nothing to process
-              m_log.log(LogService.LOG_INFO, "No designates found in the 
resource, so there's nothing to process.");
-              return;
-          }
-          Map localOcds = data.getObjectClassDefinitions();
-          Iterator i = designates.keySet().iterator();
-          while (i.hasNext()) {
-                  Designate designate = (Designate) designates.get(i.next());
-                  
-                  // determine OCD
-                  ObjectClassDefinition ocd = null;
-                  String ocdRef = designate.getObject().getOcdRef();
-                  OCD localOcd = (OCD) localOcds.get(ocdRef);
-                  // ask meta type service for matching OCD if no local OCD 
has been defined
-                  ocd = (localOcd != null) ? new 
ObjectClassDefinitionImpl(localOcd) : getMetaTypeOCD(data, designate);
-                  if (ocd == null) {
-                          throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "No 
Object Class Definition found with id=" + ocdRef);
-                  }
-                  
-                  // determine configuration data based on the values and 
their type definition
-                  Dictionary dict = getProperties(designate, ocd);
-                  if (dict == null) {
-                          // designate does not match it's definition, but was 
marked optional, ignore it
-                          continue;
-                  }
-                  
-                  // add to session data
-                  if (!m_toBeInstalled.containsKey(name)) {
-                          m_toBeInstalled.put(name, new ArrayList());
-                  }
-                  List resources = (List) m_toBeInstalled.get(name);
-                  resources.add(new AutoConfResource(name, designate.getPid(), 
designate.getFactoryPid(), designate.getBundleLocation(), designate.isMerge(), 
dict));
-          }
+        // initial validation
+        synchronized (LOCK) {
+            if (m_session == null) {
+                throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can 
not process resource without a Deployment Session");
+            }
+        }
+        MetaDataReader reader = new MetaDataReader();
+        MetaData data = null;
+        try {
+            data = reader.parse(stream);
+        }
+        catch (IOException e) {
+            throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Unable 
to process resource.", e);
+        }
+        catch (XmlPullParserException e) {
+            throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, 
"Supplied configuration is not conform the metatype xml specification.", e);
+        }
+        if (data == null) {
+            throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, 
"Supplied configuration is not conform the metatype xml specification.");
+        }
+        // process resources
+        String filter = null;
+        Map optionalAttributes = data.getOptionalAttributes();
+        if (optionalAttributes != null) {
+            filter = (String) 
optionalAttributes.get(AutoConfResourceProcessor.CONFIGURATION_ADMIN_FILTER_ATTRIBUTE);
+        }
+        // add to session data
+        if (!m_toBeInstalled.containsKey(name)) {
+            m_toBeInstalled.put(name, new ArrayList());
+        }
+        Map designates = data.getDesignates();
+        if (designates == null) {
+            // if there are no designates, there's nothing to process
+            m_log.log(LogService.LOG_INFO, "No designates found in the 
resource, so there's nothing to process.");
+            return;
+        }
+        Map localOcds = data.getObjectClassDefinitions();
+        if (localOcds == null) {
+            localOcds = Collections.EMPTY_MAP;
+        }
+        Iterator i = designates.keySet().iterator();
+        while (i.hasNext()) {
+            Designate designate = (Designate) designates.get(i.next());
+            // determine OCD
+            ObjectClassDefinition ocd = null;
+            String ocdRef = designate.getObject().getOcdRef();
+            OCD localOcd = (OCD) localOcds.get(ocdRef);
+            // ask meta type service for matching OCD if no local OCD has been 
defined
+            ocd = (localOcd != null) ? new ObjectClassDefinitionImpl(localOcd) 
: getMetaTypeOCD(data, designate);
+            if (ocd == null) {
+                throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "No 
Object Class Definition found with id=" + ocdRef);
+            }
+            // determine configuration data based on the values and their type 
definition
+            Dictionary dict = getProperties(designate, ocd);
+            if (dict == null) {
+                // designate does not match it's definition, but was marked 
optional, ignore it
+                continue;
+            }
+            List resources = (List) m_toBeInstalled.get(name);
+            resources.add(new AutoConfResource(name, designate.getPid(), 
designate.getFactoryPid(), designate.getBundleLocation(), designate.isMerge(), 
dict, filter));
+        }
     }
 
     public void dropped(String name) throws ResourceProcessorException {
-       if (m_session == null) {
-               throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can 
not process resource without a Deployment Session");
-       }
+        synchronized (LOCK) {
+               if (m_session == null) {
+                       throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can 
not process resource without a Deployment Session");
+               }
+        }
        try {
                List resources = m_persistencyManager.load(name);
                if (!m_toBeDeleted.containsKey(name)) {
@@ -153,9 +188,11 @@ public class AutoConfResourceProcessor i
     }
 
     public void dropAllResources() throws ResourceProcessorException {
-       if (m_session == null) {
-               throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can 
not drop all resources without a Deployment Session");
-       }
+        synchronized (LOCK) {
+               if (m_session == null) {
+                       throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can 
not drop all resources without a Deployment Session");
+               }
+        }
        try {
                Map loadAll = m_persistencyManager.loadAll();
                for (Iterator i = loadAll.keySet().iterator(); i.hasNext();) {
@@ -178,12 +215,16 @@ public class AutoConfResourceProcessor i
                throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Unable 
to drop resources, data area is not accessible");
        }
     }
+    
+    private List m_configurationAdminTasks = new ArrayList();
+    private List m_postCommitTasks = new ArrayList();
 
     public void prepare() throws ResourceProcessorException {
-       if (m_session == null) {
-               throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can 
not process resource without a Deployment Session");
-       }
-
+        synchronized (LOCK) {
+               if (m_session == null) {
+                       throw new 
ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can 
not process resource without a Deployment Session");
+               }
+        }
        try {
                // delete dropped resources
                for (Iterator i = m_toBeDeleted.keySet().iterator(); 
i.hasNext();) {
@@ -191,15 +232,9 @@ public class AutoConfResourceProcessor i
                        List resources = (List) m_toBeDeleted.get(name);
                        for (Iterator j = resources.iterator(); j.hasNext();) {
                                AutoConfResource resource = (AutoConfResource) 
j.next();
-                               if (resource.isFactoryConfig()) {
-                                       Configuration configuration = 
m_configAdmin.getConfiguration(resource.getGeneratedPid(), 
resource.getBundleLocation());
-                                       configuration.delete();
-                               } else {
-                                       Configuration configuration = 
m_configAdmin.getConfiguration(resource.getPid(), resource.getBundleLocation());
-                                       configuration.delete();
-                               }
+                               m_configurationAdminTasks.add(new 
DropResourceTask(resource));
                        }
-                       m_persistencyManager.delete(name);
+                       m_postCommitTasks.add(new DeleteResourceTask(name));
                }
 
                // install new/updated resources
@@ -208,63 +243,17 @@ public class AutoConfResourceProcessor i
                        List existingResources = null;
                        try {
                                existingResources = 
m_persistencyManager.load(name);
-                       } catch (IOException ioe) {
+                       }
+                       catch (IOException ioe) {
                                throw new 
ResourceProcessorException(ResourceProcessorException.CODE_PREPARE, "Unable to 
read existing resources for resource " + name, ioe);
                        }
                        List resources = (List) m_toBeInstalled.get(name);
                        for (Iterator iterator = resources.iterator(); 
iterator.hasNext();) {
                                AutoConfResource resource = (AutoConfResource) 
iterator.next();
+                               
+                               m_configurationAdminTasks.add(new 
InstallOrUpdateResourceTask(resource));
 
-                               Dictionary properties = 
resource.getProperties();
-                               String bundleLocation = 
resource.getBundleLocation();
-                               Configuration configuration = null;
-
-                               // update configuration
-                               if (resource.isFactoryConfig()) {
-                                       // check if this is an factory config 
instance update
-                                       for (Iterator i = 
existingResources.iterator(); i.hasNext();) {
-                                               AutoConfResource 
existingResource = (AutoConfResource) i.next();
-                                               if 
(resource.equalsTargetConfiguration(existingResource)) {
-                                                       // existing instance 
found
-                                                       configuration = 
m_configAdmin.getConfiguration(existingResource.getGeneratedPid(), 
bundleLocation);
-                                                       
existingResources.remove(existingResource);
-                                                       break;
-                                               }
-                                       }
-                                       if (configuration == null) {
-                                               // no existing instance, create 
new
-                                               configuration = 
m_configAdmin.createFactoryConfiguration(resource.getFactoryPid(), 
bundleLocation);
-                                       }
-                                       
resource.setGeneratedPid(configuration.getPid());
-                               }
-                               else {
-                                       for (Iterator i = 
existingResources.iterator(); i.hasNext();) {
-                                               AutoConfResource 
existingResource = (AutoConfResource) i.next();
-                                               if 
(resource.getPid().equals(existingResource.getPid())) {
-                                                       // existing resource 
found
-                                                       
existingResources.remove(existingResource);
-                                                       break;
-                                               }
-                                       }
-                                       configuration = 
m_configAdmin.getConfiguration(resource.getPid(), bundleLocation);
-                                       if 
(!bundleLocation.equals(configuration.getBundleLocation())) {
-                                               // an existing configuration 
exists that is bound to a different location, which is not allowed
-                                               throw new 
ResourceProcessorException(ResourceProcessorException.CODE_PREPARE, "Existing 
configuration was not unbound and not bound to the specified bundlelocation");
-                                       }
-                               }
-                               if (resource.isMerge()) {
-                                       Dictionary existingProperties = 
configuration.getProperties();
-                                       if (existingProperties != null) {
-                                               Enumeration keys = 
existingProperties.keys();
-                                               while (keys.hasMoreElements()) {
-                                                       Object key = 
keys.nextElement();
-                                                       properties.put(key, 
existingProperties.get(key));
-                                               }
-                                       }
-                               }
-                               configuration.update(properties);
                        }
-
                        // remove existing configurations that were not in the 
new version of the resource
                        for (Iterator i = existingResources.iterator(); 
i.hasNext();) {
                                AutoConfResource existingResource = 
(AutoConfResource) i.next();
@@ -276,7 +265,7 @@ public class AutoConfResourceProcessor i
                                }
                                configuration.delete();
                        }
-                       m_persistencyManager.store(name, resources);
+                       m_postCommitTasks.add(new StoreResourceTask(name, 
resources));
                }
        }
        catch (IOException ioe) {
@@ -286,9 +275,57 @@ public class AutoConfResourceProcessor i
     }
 
     public synchronized void commit() {
-       m_toBeInstalled.clear();
-       m_toBeDeleted.clear();
-       m_session = null;
+        DependencyManager dm = m_component.getDependencyManager();
+        m_configurationAdminDependency = dm.createServiceDependency()
+            .setService(ConfigurationAdmin.class)
+            .setCallbacks("addConfigurationAdmin", null)
+            .setRequired(false);
+        m_component.add(m_configurationAdminDependency);
+    }
+    
+    public void addConfigurationAdmin(ServiceReference ref, ConfigurationAdmin 
ca) {
+        Iterator iterator = m_configurationAdminTasks.iterator();
+        while (iterator.hasNext()) {
+            ConfigurationAdminTask task = (ConfigurationAdminTask) 
iterator.next();
+            try {
+                Filter filter = null;
+                String filterString = task.getFilter();
+                if (filterString != null) {
+                    try {
+                        filter = m_bc.createFilter(filterString);
+                    }
+                    catch (InvalidSyntaxException e) {
+                        m_log.log(LogService.LOG_ERROR, "Could not parse 
filter, ignoring it: " + filterString, e);
+                    }
+                }
+                if (filter == null || filter != null && filter.match(ref)) {
+                    task.run(m_persistencyManager, ca);
+                }
+            }
+            catch (Exception e) {
+                m_log.log(LogService.LOG_ERROR, "Exception during 
configuration to " + ca + ". Trying to continue.", e);
+            }
+        }
+    }
+    
+    public void postcommit() {
+        m_component.remove(m_configurationAdminDependency);
+        Iterator iterator = m_postCommitTasks.iterator();
+        while (iterator.hasNext()) {
+            PostCommitTask task = (PostCommitTask) iterator.next();
+            try {
+                task.run(m_persistencyManager);
+            }
+            catch (Exception e) {
+                m_log.log(LogService.LOG_ERROR, "Exception during post commit 
wrap-up. Trying to continue.", e);
+            }
+        }
+        m_toBeInstalled.clear();
+        m_toBeDeleted.clear();
+        m_postCommitTasks.clear();
+        m_configurationAdminTasks.clear();
+        m_session = null;
+        m_component.remove(m_configurationAdminDependency);
     }
 
     public void rollback() {
@@ -533,4 +570,146 @@ public class AutoConfResourceProcessor i
        }
        return result;
     }
+
+    public void handleEvent(Event event) {
+        Boolean result = (Boolean) 
event.getProperty(Constants.EVENTPROPERTY_SUCCESSFUL);
+        // check if successful
+        if (result.booleanValue()) {
+            postcommit();
+        }
+        else {
+            postcommit();
+        }
+    }
 }
+
+interface ConfigurationAdminTask {
+    public String getFilter();
+    public void run(PersistencyManager persistencyManager, ConfigurationAdmin 
configAdmin) throws Exception;
+}
+
+interface PostCommitTask {
+    public void run(PersistencyManager manager) throws Exception;
+}
+
+class DropResourceTask implements ConfigurationAdminTask {
+    private final AutoConfResource m_resource;
+
+    public DropResourceTask(AutoConfResource resource) {
+        m_resource = resource;
+    }
+    
+    public String getFilter() {
+        return m_resource.getFilter();
+    }
+
+    public void run(PersistencyManager persistencyManager, ConfigurationAdmin 
configAdmin) throws Exception {
+        String pid;
+        if (m_resource.isFactoryConfig()) {
+            pid = m_resource.getGeneratedPid();
+        }
+        else {
+            pid = m_resource.getPid();
+        }
+        Configuration configuration = configAdmin.getConfiguration(pid, 
m_resource.getBundleLocation());
+        configuration.delete();
+    }
+}
+
+class InstallOrUpdateResourceTask implements ConfigurationAdminTask {
+    private final AutoConfResource m_resource;
+
+    public InstallOrUpdateResourceTask(AutoConfResource resource) {
+        m_resource = resource;
+    }
+
+    public String getFilter() {
+        return m_resource.getFilter();
+    }
+
+    public void run(PersistencyManager persistencyManager, ConfigurationAdmin 
configAdmin) throws Exception {
+        String name = m_resource.getName();
+        Dictionary properties = m_resource.getProperties();
+        String bundleLocation = m_resource.getBundleLocation();
+        Configuration configuration = null;
+
+        List existingResources = null;
+        try {
+            existingResources = persistencyManager.load(name);
+        }
+        catch (IOException ioe) {
+            throw new 
ResourceProcessorException(ResourceProcessorException.CODE_PREPARE, "Unable to 
read existing resources for resource " + name, ioe);
+        }
+        
+        // update configuration
+        if (m_resource.isFactoryConfig()) {
+            // check if this is an factory config instance update
+            for (Iterator i = existingResources.iterator(); i.hasNext();) {
+                AutoConfResource existingResource = (AutoConfResource) 
i.next();
+                if (m_resource.equalsTargetConfiguration(existingResource)) {
+                    // existing instance found
+                    configuration = 
configAdmin.getConfiguration(existingResource.getGeneratedPid(), 
bundleLocation);
+                    existingResources.remove(existingResource);
+                    break;
+                }
+            }
+            if (configuration == null) {
+                // no existing instance, create new
+                configuration = 
configAdmin.createFactoryConfiguration(m_resource.getFactoryPid(), 
bundleLocation);
+            }
+            m_resource.setGeneratedPid(configuration.getPid());
+        }
+        else {
+            for (Iterator i = existingResources.iterator(); i.hasNext();) {
+                AutoConfResource existingResource = (AutoConfResource) 
i.next();
+                if (m_resource.getPid().equals(existingResource.getPid())) {
+                    // existing resource found
+                    existingResources.remove(existingResource);
+                    break;
+                }
+            }
+            configuration = configAdmin.getConfiguration(m_resource.getPid(), 
bundleLocation);
+            if (!bundleLocation.equals(configuration.getBundleLocation())) {
+                // an existing configuration exists that is bound to a 
different location, which is not allowed
+                throw new 
ResourceProcessorException(ResourceProcessorException.CODE_PREPARE, "Existing 
configuration was bound to " + configuration.getBundleLocation() + " instead of 
" + bundleLocation);
+            }
+        }
+        if (m_resource.isMerge()) {
+            Dictionary existingProperties = configuration.getProperties();
+            if (existingProperties != null) {
+                Enumeration keys = existingProperties.keys();
+                while (keys.hasMoreElements()) {
+                    Object key = keys.nextElement();
+                    properties.put(key, existingProperties.get(key));
+                }
+            }
+        }
+        configuration.update(properties);
+    }
+}
+
+class DeleteResourceTask implements PostCommitTask {
+    private final String m_name;
+
+    public DeleteResourceTask(String name) {
+        m_name = name;
+    }
+
+    public void run(PersistencyManager manager) throws Exception {
+        manager.delete(m_name);
+    }
+}
+
+class StoreResourceTask implements PostCommitTask {
+    private final String m_name;
+    private final List m_resources;
+
+    public StoreResourceTask(String name, List resources) {
+        m_name = name;
+        m_resources = resources;
+    }
+
+    public void run(PersistencyManager manager) throws Exception {
+        manager.store(m_name, m_resources);
+    }
+}
\ No newline at end of file

Modified: 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/PersistencyManager.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/PersistencyManager.java?rev=1241558&r1=1241557&r2=1241558&view=diff
==============================================================================
--- 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/PersistencyManager.java
 (original)
+++ 
felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/PersistencyManager.java
 Tue Feb  7 19:17:35 2012
@@ -46,9 +46,6 @@ public class PersistencyManager {
         * @throws IOException If the resource could not be stored.
         */
        public void store(String name, List configs) throws IOException {
-               if (configs.isEmpty()) {
-                       return;
-               }
                File targetDir = m_root;
                name = name.replace('/', File.separatorChar);
                
@@ -67,7 +64,8 @@ public class PersistencyManager {
                try {
                        out = new ObjectOutputStream(new 
FileOutputStream(target));
                        out.writeObject(configs);
-               } finally {
+               }
+               finally {
                        if (out != null) {
                                try {
                                        out.close();


Reply via email to