FELIX-4785 : Incompatible SCR API

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1660309 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/Activator.java b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/Activator.java
index fe1416c..f0f9c8c 100644
--- a/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/Activator.java
+++ b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/Activator.java
@@ -19,6 +19,7 @@
 package org.apache.felix.scr.impl.compat;
 
 
+import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -39,6 +40,9 @@
     // tracker of the runtime service
     private volatile ServiceTracker<ServiceComponentRuntime, ServiceComponentRuntime> runtimeTracker;
 
+    // tracker of the new ScrInfoservice
+    private volatile ServiceTracker<org.apache.felix.scr.info.ScrInfo, org.apache.felix.scr.info.ScrInfo> infoTracker;
+
     // the service registrations
     private final Map<Long, ServiceRegistration<ScrService>> scrServiceRegMap = new ConcurrentHashMap<Long, ServiceRegistration<ScrService>>();
 
@@ -57,20 +61,13 @@
                         final ServiceComponentRuntime runtime = context.getService(reference);
                         if ( runtime != null )
                         {
-                            Hashtable props = new Hashtable();
+                            final Dictionary<String, Object> props = new Hashtable<String, Object>();
                             props.put(Constants.SERVICE_DESCRIPTION, "Apache Felix Compat ScrService");
                             props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
 
                             final ScrService service = new ScrServiceImpl(context, runtime);
                             scrServiceRegMap.put((Long)reference.getProperty(Constants.SERVICE_ID),
                                     context.registerService(ScrService.class, service, props));
-
-                            props = new Hashtable();
-                            props.put(Constants.SERVICE_DESCRIPTION, "Apache Felix Compat SCR Info service");
-                            props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
-                            final ScrInfo info = new ScrCommand(context, service);
-                            scrCommandRegMap.put((Long)reference.getProperty(Constants.SERVICE_ID),
-                                    context.registerService(ScrInfo.class, info, props));
                         }
                         return runtime;
                     }
@@ -89,19 +86,62 @@
                         {
                             reg.unregister();
                         }
-                        final ServiceRegistration<ScrInfo> reg2 =  scrCommandRegMap.remove(reference.getProperty(Constants.SERVICE_ID));
-                        if ( reg2 != null )
-                        {
-                            reg2.unregister();
-                        }
                         context.ungetService(reference);
                     }
         });
         this.runtimeTracker.open();
+        this.infoTracker = new ServiceTracker<org.apache.felix.scr.info.ScrInfo, org.apache.felix.scr.info.ScrInfo>(context, org.apache.felix.scr.info.ScrInfo.class,
+                new ServiceTrackerCustomizer<org.apache.felix.scr.info.ScrInfo, org.apache.felix.scr.info.ScrInfo>()
+                {
+
+                    public org.apache.felix.scr.info.ScrInfo addingService(
+                            final ServiceReference<org.apache.felix.scr.info.ScrInfo> reference)
+                    {
+                        final org.apache.felix.scr.info.ScrInfo runtime = context.getService(reference);
+                        if ( runtime != null )
+                        {
+                            final Dictionary<String, Object> props = new Hashtable<String, Object>();
+                            props.put(Constants.SERVICE_DESCRIPTION, "Apache Felix Compat SCR Info service");
+                            props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+
+                            final ScrInfo info = new ScrCommand(runtime);
+                            scrCommandRegMap.put((Long)reference.getProperty(Constants.SERVICE_ID),
+                                    context.registerService(ScrInfo.class, info, props));
+                        }
+                        return runtime;
+                    }
+
+                    public void modifiedService(
+                            final ServiceReference<org.apache.felix.scr.info.ScrInfo> reference,
+                            final org.apache.felix.scr.info.ScrInfo service) {
+                        // nothing to do
+                    }
+
+                    public void removedService(
+                            final ServiceReference<org.apache.felix.scr.info.ScrInfo> reference,
+                            final org.apache.felix.scr.info.ScrInfo service) {
+                        final ServiceRegistration<ScrInfo> reg =  scrCommandRegMap.remove(reference.getProperty(Constants.SERVICE_ID));
+                        if ( reg != null )
+                        {
+                            reg.unregister();
+                        }
+                        context.ungetService(reference);
+                    }
+        });
+        this.infoTracker.open();
     }
 
     public void stop(final BundleContext context) throws Exception
     {
-        this.runtimeTracker.close();
+        if ( this.infoTracker != null )
+        {
+            this.infoTracker.close();
+            this.infoTracker = null;
+        }
+        if ( this.runtimeTracker != null )
+        {
+            this.runtimeTracker.close();
+            this.runtimeTracker = null;
+        }
     }
 }
\ No newline at end of file
diff --git a/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrCommand.java b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrCommand.java
index 785c344..957b8d7 100644
--- a/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrCommand.java
+++ b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrCommand.java
@@ -19,459 +19,40 @@
 package org.apache.felix.scr.impl.compat;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Dictionary;
-import java.util.TreeSet;
-import java.util.regex.Pattern;
 
-import org.apache.felix.scr.Component;
-import org.apache.felix.scr.Reference;
 import org.apache.felix.scr.ScrInfo;
-import org.apache.felix.scr.ScrService;
-import org.apache.felix.scr.impl.config.ScrConfiguration;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
 
-/**
- * The <code>ScrCommand</code> class provides the implementations for the
- * Apache Felix Gogo and legacy Apache Felix Shell commands. The
- * {@link #register(BundleContext, ScrService, ScrConfiguration)} method
- * instantiates and registers the Gogo and Shell commands as possible.
- */
 public class ScrCommand implements ScrInfo
 {
 
-    private final BundleContext bundleContext;
-    private final ScrService scrService;
+    private final org.apache.felix.scr.info.ScrInfo scrInfo;
 
-    public ScrCommand(final BundleContext bundleContext, final  ScrService scrService)
+    public ScrCommand(final org.apache.felix.scr.info.ScrInfo scrInfo)
     {
-        this.scrService = scrService;
-        this.bundleContext = bundleContext;
-
-    }
-
-    static boolean isBundleActive( final Bundle bundle )
-    {
-        if ( bundle != null )
-        {
-            if ( bundle.getState() == Bundle.ACTIVE )
-            {
-                return true;
-            }
-
-            if ( bundle.getState() == Bundle.STARTING )
-            {
-                // according to the spec the activationPolicy header is only
-                // set to request a bundle to be lazily activated. So in this
-                // simple check we just verify the header is set to assume
-                // the bundle is considered a lazily activated bundle
-                return bundle.getHeaders().get( Constants.BUNDLE_ACTIVATIONPOLICY ) != null;
-            }
-        }
-
-        // fall back: bundle is not considered active
-        return false;
-    }
+        this.scrInfo = scrInfo;
+     }
 
     /* (non-Javadoc)
      * @see org.apache.felix.scr.impl.ScrInfo#list(java.lang.String, java.io.PrintStream, java.io.PrintStream)
      */
     public void list(final String bundleIdentifier, final PrintWriter out)
     {
-        Component[] components;
-
-        if (bundleIdentifier != null)
-        {
-            Bundle bundle = null;
-            try
-            {
-                long bundleId = Long.parseLong(bundleIdentifier);
-                bundle = bundleContext.getBundle(bundleId);
-            }
-            catch (NumberFormatException nfe)
-            {
-                // might be a bundle symbolic name
-                Bundle[] bundles = bundleContext.getBundles();
-                for (int i = 0; i < bundles.length; i++)
-                {
-                    if (bundleIdentifier.equals(bundles[i].getSymbolicName()))
-                    {
-                        bundle = bundles[i];
-                        break;
-                    }
-                }
-            }
-
-            if (bundle == null)
-            {
-                throw new IllegalArgumentException("Missing bundle with ID " + bundleIdentifier);
-            }
-            if (isBundleActive(bundle))
-            {
-                components = scrService.getComponents(bundle);
-                if (components == null)
-                {
-                    out.println("Bundle " + bundleIdentifier + " declares no components");
-                    return;
-                }
-            }
-            else
-            {
-                out.println("Bundle " + bundleIdentifier + " is not active");
-                return;
-            }
-        }
-        else
-        {
-            components = scrService.getComponents();
-            if (components == null)
-            {
-                out.println("No components registered");
-                return;
-            }
-        }
-
-        Arrays.sort( components, new Comparator<Component>()
-                {
-
-                    public int compare(Component c1, Component c2)
-                    {
-                        return Long.signum(c1.getId() - c2.getId());
-                    }
-
-                });
-
-        out.println(" Id   State BundleId Name");
-        for ( Component component : components )
-        {
-            out.println( String.format( "[%1$4d] [%2$s] [%3$4d] %4$s", component.getId(), toStateString( component.getState() ), component.getBundle().getBundleId(), component.getName() ) );
-        }
-        out.flush();
-   }
+        this.scrInfo.list(bundleIdentifier, out);
+    }
 
     /* (non-Javadoc)
      * @see org.apache.felix.scr.impl.ScrInfo#info(java.lang.String, java.io.PrintStream, java.io.PrintStream)
      */
-    public void info(final String componentId, PrintWriter out)
+    public void info(final String componentId, final PrintWriter out)
     {
-        Component[] components = getComponentFromArg(componentId);
-        if (components == null)
-        {
-            return;
-        }
-
-        Arrays.sort( components, new Comparator<Component>()
-                {
-
-                    public int compare(Component c1, Component c2)
-                    {
-                        long bundleId1 = c1.getBundle().getBundleId();
-                        long bundleId2 = c2.getBundle().getBundleId();
-                        int result = Long.signum(bundleId1 - bundleId2);
-                        if (result == 0) {
-                            result = Long.signum(c1.getId() - c2.getId());
-                        }
-                        return result;
-                    }
-
-                });
-
-        long bundleId = -1;
-
-        for ( Component component : components )
-        {
-            if (components.length > 1)
-            {
-                if ( component.getBundle().getBundleId() != bundleId )
-                {
-                    if ( bundleId != -1 )
-                    {
-                        out.println();
-                        out.println();
-                    }
-                    bundleId = component.getBundle().getBundleId();
-                    out.println(String.format("*** Bundle: %1$s (%2$d)", component.getBundle().getSymbolicName(), bundleId));
-                }
-                out.println();
-            }
-            out.print( "ID: " );
-            out.println( component.getId() );
-            out.print( "Name: " );
-            out.println( component.getName() );
-            out.print( "Bundle: " );
-            out.println( component.getBundle().getSymbolicName() + " (" + component.getBundle().getBundleId() + ")" );
-            out.print( "State: " );
-            out.println( toStateString( component.getState() ) );
-            out.print( "Default State: " );
-            out.println( component.isDefaultEnabled() ? "enabled" : "disabled" );
-            out.print( "Activation: " );
-            out.println( component.isImmediate() ? "immediate" : "delayed" );
-
-            // DS 1.1 new features
-            out.print( "Configuration Policy: " );
-            out.println( component.getConfigurationPolicy() );
-            out.print( "Activate Method: " );
-            out.print( component.getActivate() );
-            if ( component.isActivateDeclared() )
-            {
-                out.print( " (declared in the descriptor)" );
-            }
-            out.println();
-            out.print( "Deactivate Method: " );
-            out.print( component.getDeactivate() );
-            if ( component.isDeactivateDeclared() )
-            {
-                out.print( " (declared in the descriptor)" );
-            }
-            out.println();
-            out.print( "Modified Method: " );
-            if ( component.getModified() != null )
-            {
-                out.print( component.getModified() );
-            }
-            else
-            {
-                out.print( "-" );
-            }
-            out.println();
-
-            out.print( "Configuration Pid: " );
-            out.print( component.getConfigurationPid() );
-            if ( component.isConfigurationPidDeclared() )
-            {
-                out.print( " (declared in the descriptor)" );
-            }
-            out.println();
-
-            if ( component.getFactory() != null )
-            {
-                out.print( "Factory: " );
-                out.println( component.getFactory() );
-            }
-
-            String[] services = component.getServices();
-            if ( services != null )
-            {
-                out.print( "Services: " );
-                out.println( services[0] );
-                for ( int i = 1; i < services.length; i++ )
-                {
-                    out.print( "          " );
-                    out.println( services[i] );
-                }
-                out.print( "Service Type: " );
-                out.println( component.isServiceFactory() ? "service factory" : "service" );
-            }
-
-            Reference[] refs = component.getReferences();
-            if ( refs != null )
-            {
-                for ( Reference ref : refs )
-                {
-                    out.print( "Reference: " );
-                    out.println( ref.getName() );
-                    out.print( "    Satisfied: " );
-                    out.println( ref.isSatisfied() ? "satisfied" : "unsatisfied" );
-                    out.print( "    Service Name: " );
-                    out.println( ref.getServiceName() );
-                    if ( ref.getTarget() != null )
-                    {
-                        out.print( "    Target Filter: " );
-                        out.println( ref.getTarget() );
-                    }
-                    out.print( "    Multiple: " );
-                    out.println( ref.isMultiple() ? "multiple" : "single" );
-                    out.print( "    Optional: " );
-                    out.println( ref.isOptional() ? "optional" : "mandatory" );
-                    out.print( "    Policy: " );
-                    out.println( ref.isStatic() ? "static" : "dynamic" );
-                    out.print( "    Policy option: " );
-                    out.println( ref.isReluctant() ? "reluctant" : "greedy" );
-                    ServiceReference[] serviceRefs = ref.getServiceReferences();
-                    if ( serviceRefs != null )
-                    {
-                        out.print( "    Bound to:" );
-                        for ( int k = 0; k < serviceRefs.length; k++ )
-                        {
-                            out.print( "        " );
-                            out.println( serviceRefs[k] );
-                        }
-                    }
-                    else
-                    {
-                        out.println( "    (unbound)" );
-                    }
-                }
-            }
-
-            Dictionary props = component.getProperties();
-            if ( props != null )
-            {
-                out.println( "Properties:" );
-                TreeSet keys = new TreeSet( Collections.list( props.keys() ) );
-                for ( Object key : keys )
-                {
-                    out.print( "    " );
-                    out.print( key );
-                    out.print( " = " );
-
-                    Object prop = props.get( key );
-                    if ( prop.getClass().isArray() )
-                    {
-                        prop = Arrays.asList( ( Object[] ) prop );
-                    }
-                    out.print( prop );
-
-                    out.println();
-                }
-            }
-        }
-        out.flush();
-    }
-
-    void change(final String componentIdentifier, PrintWriter out, boolean enable)
-    {
-        Component[] components = getComponentFromArg(componentIdentifier);
-        ArrayList<String> disposed = new ArrayList<String>();
-        if (components == null)
-        {
-            return;
-        }
-
-        for ( Component component : components )
-        {
-            if ( component.getState() == Component.STATE_DISPOSED )
-            {
-                disposed.add(component.getName());
-            }
-            else if ( enable )
-            {
-                if ( component.getState() == Component.STATE_DISABLED )
-                {
-                    component.enable();
-                    out.println( "Component " + component.getName() + " enabled" );
-                }
-                else
-                {
-                    out.println( "Component " + component.getName() + " already enabled" );
-                }
-            }
-            else
-            {
-                if ( component.getState() != Component.STATE_DISABLED )
-                {
-                    component.disable();
-                    out.println( "Component " + component.getName() + " disabled" );
-                }
-                else
-                {
-                    out.println( "Component " + component.getName() + " already disabled" );
-                }
-            }
-        }
-        out.flush();
-        if ( !disposed.isEmpty() )
-        {
-            throw new IllegalArgumentException( "Components " + disposed + " already disposed, cannot change state" );
-
-        }
-    }
-
-    private String toStateString(int state)
-    {
-        switch (state) {
-
-        case (Component.STATE_DISABLED):
-            return "disabled    ";
-        case (Component.STATE_ENABLING):
-            return "enabling    ";
-        case (Component.STATE_ENABLED):
-            return "enabled     ";
-        case (Component.STATE_UNSATISFIED):
-            return "unsatisfied ";
-        case (Component.STATE_ACTIVATING):
-            return "activating  ";
-        case (Component.STATE_ACTIVE):
-            return "active      ";
-        case (Component.STATE_REGISTERED):
-            return "registered  ";
-        case (Component.STATE_FACTORY):
-            return "factory     ";
-        case (Component.STATE_DEACTIVATING):
-            return "deactivating";
-        case (Component.STATE_DISABLING):
-            return "disabling   ";
-        case (Component.STATE_DISPOSING):
-            return "disposing   ";
-        case (Component.STATE_DISPOSED):
-            return "disposed    ";
-        default:
-            return "unkown: " + state;
-        }
-    }
-
-    private Component[] getComponentFromArg(final String componentIdentifier)
-    {
-        Component[] components = null;
-        if (componentIdentifier != null)
-        {
-            try
-            {
-                long componentId = Long.parseLong(componentIdentifier);
-                Component component = scrService.getComponent(componentId);
-                if (component == null)
-                {
-                    throw new IllegalArgumentException("Missing Component with ID " + componentId);
-                }
-                else
-                {
-                    return new Component[]
-                        { component };
-                }
-            }
-            catch (NumberFormatException nfe)
-            {
-
-                // check whether it is a component name
-                components = scrService.getComponents(componentIdentifier);
-            }
-        }
-        if ( components == null)
-        {
-            components = scrService.getComponents();
-            if (componentIdentifier != null)
-            {
-                ArrayList<Component> cs = new ArrayList<Component>(components.length);
-                Pattern p = Pattern.compile(componentIdentifier);
-                for (Component component: components)
-                {
-                    if ( p.matcher( component.getName()).matches() )
-                    {
-                        cs.add( component );
-                    }
-                }
-                if (cs.isEmpty())
-                {
-                    throw new IllegalArgumentException("No Component with ID or matching " + componentIdentifier);
-                }
-                components = cs.toArray( new Component[cs.size()] );
-            }
-        }
-
-        return components;
+        this.scrInfo.info(componentId, out);
     }
 
     /* (non-Javadoc)
      * @see org.apache.felix.scr.impl.ScrInfo#config(java.io.PrintStream)
      */
-    public void config(PrintWriter out)
+    public void config(final PrintWriter out)
     {
-        out.println("Configuration not available.");
+        this.scrInfo.config(out);
     }
 }