package org.ow2.chameleon.fuchsia.core.component;


import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.ow2.chameleon.fuchsia.core.declaration.ImportDeclaration;
import org.slf4j.Logger;

import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;

/**
 * Abstract implementation of an discovery component which provides an {@link DiscoveryService}.
 * Start must be call before registering the service !
 * Stop must be called while the service is no more available !
 *
 * @author Morgan Martinet
 */
public abstract class AbstractDiscoveryComponent implements DiscoveryService, DiscoveryIntrospection {

    private final Map<ImportDeclaration, ServiceRegistration> importDeclarationsRegistered;

    private final BundleContext bundleContext;


    protected AbstractDiscoveryComponent(BundleContext bundleContext) {
        this.importDeclarationsRegistered = new HashMap<ImportDeclaration, ServiceRegistration>();
        this.bundleContext = bundleContext;
    }

    /**
     * Start the discovery component, iPOJO Validate instance callback.
     * Must be override !
     */
    protected void start() {
    }

    /**
     * Stop the discovery component, iPOJO Invalidate instance callback.
     * Must be override !
     */
    protected void stop() {
        synchronized (importDeclarationsRegistered) {
            for (ServiceRegistration registration : importDeclarationsRegistered.values()) {
                if (registration != null) {
                    registration.unregister();
                }
            }
            importDeclarationsRegistered.clear();
        }
    }


    /**
     * Utility method to register an ImportDeclaration has a Service in OSGi.
     * If you use it make sure to use unregisterImportDeclaration(...) to unregister the ImportDeclaration
     *
     * @param importDeclaration the ImportDeclaration to register
     */
    protected void registerImportDeclaration(ImportDeclaration importDeclaration) {
        Dictionary<String, Object> props = new Hashtable<String, Object>();
        String clazzes[] = new String[]{ImportDeclaration.class.getName()};
        ServiceRegistration registration;
        registration = bundleContext.registerService(clazzes, importDeclaration, props);
        synchronized (importDeclarationsRegistered) {
            importDeclarationsRegistered.put(importDeclaration, registration);
        }
    }


    /**
     * Utility method to unregister an ImportDeclaration of OSGi.
     * Use it only if you have used registerImportDeclaration(...) to register the ImportDeclaration
     *
     * @param importDeclaration the ImportDeclaration to unregister
     */
    protected void unregisterImportDeclaration(ImportDeclaration importDeclaration) {
        ServiceRegistration registration;
        synchronized (importDeclarationsRegistered) {
            registration = importDeclarationsRegistered.remove(importDeclaration);
        }
        if (registration != null) {
            registration.unregister();
        }
    }

    @Override
    public String toString() {
        return getName();
    }

    public Set<ImportDeclaration> getImportDeclarations() {
        return new HashSet<ImportDeclaration>(importDeclarationsRegistered.keySet());
    }

    protected BundleContext getBundleContext() {
        return bundleContext;
    }

    public abstract Logger getLogger();
}

@@ -832,17 +832,16 @@
 stered;%0A
-%0A
     priv
@@ -1725,33 +1725,32 @@
        %7D%0A    %7D%0A%0A
-%0A
     /**%0A     * U
@@ -2083,32 +2083,293 @@
 tDeclaration) %7B%0A
+        synchronized (importDeclarationsRegistered) %7B%0A            if (importDeclarationsRegistered.containsKey(importDeclaration)) %7B%0A                throw new IllegalStateException(%22The given ImportDeclaration has already been registered.%22);%0A            %7D%0A%0A    
         Dictiona
@@ -2424,24 +2424,28 @@
  Object%3E();%0A
+    
         Stri
@@ -2508,32 +2508,36 @@
 ame()%7D;%0A        
+ 
+   
 ServiceRegistrat
@@ -2546,32 +2546,36 @@
 n registration;%0A
+    
         registra
@@ -2651,61 +2651,8 @@
 s);%0A
-        synchronized (importDeclarationsRegistered) %7B
 %0A   
@@ -2744,17 +2744,16 @@
 %0A    %7D%0A%0A
-%0A
     /**%0A
@@ -3267,30 +3267,24 @@
 ation);%0A    
-    %7D%0A
         if (
@@ -3288,33 +3288,33 @@
 f (registration 
-!
+=
 = null) %7B%0A      
@@ -3315,37 +3315,164 @@
             
-registration.
+    throw new IllegalStateException(%22The given ImportDeclaration has never been registered%22%0A                        + %22or have already been 
 unregister()
@@ -3461,33 +3461,36 @@
  been unregister
-(
+ed.%22
 );%0A        %7D%0A   
@@ -3476,33 +3476,82 @@
 red.%22);%0A        
+ 
-%7D
+   %7D%0A        %7D%0A        registration.unregister();
 %0A    %7D%0A%0A    @Ove

Handle duplicate ImportDeclaration into ADiscovery