Fixed FELIX-3172.
Implements the new API
Updates service registration to avoid the cast issue
Propagates changes to iPOJO Service Context (and implementations)
Configures the maven-compiler-plugin to generate 1.4 bytecode (same trick as for the Felix framework)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1186255 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/core/pom.xml b/ipojo/core/pom.xml
index c9b7537..d1b36f1 100644
--- a/ipojo/core/pom.xml
+++ b/ipojo/core/pom.xml
@@ -47,7 +47,7 @@
     <dependency>
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.core</artifactId>
-      <version>4.0.0</version>
+      <version>4.3.0</version>
     </dependency>
     <dependency>
       <groupId>org.osgi</groupId>
@@ -74,6 +74,14 @@
   <build>
     <plugins>
       <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <target>jsr14</target>
+          <source>1.5</source>
+        </configuration>
+      </plugin>
+      <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
         <version>1.4.3</version>
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
index 80c7c3c..77cf3b3 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
@@ -20,6 +20,7 @@
 
 import java.io.File;
 import java.io.InputStream;
+import java.util.Collection;
 import java.util.Dictionary;
 
 import org.osgi.framework.Bundle;
@@ -175,6 +176,15 @@
     }
 
     /**
+     * Gets a bundle by symbolic name
+     * @param s the name
+     * @return the matching bundle or <code>null</code> if not found
+     */
+    public Bundle getBundle(String s) {
+        return m_bundleContext.getBundle(s);
+    }
+
+    /**
      * Gets the service references matching with the given query.
      * Uses the service context if specified, used the bundle context
      * otherwise.
@@ -250,16 +260,16 @@
      * context otherwise.
      * This method may throw {@link IllegalStateException} if the used bundle
      * context is no more valid (because we're leaving).
-     * @param reference the required service reference 
+     * @param ref the required service reference
      * @return the service object or <code>null</code> if the service reference 
      * is no more valid or if the service object is not accessible.
      * @see org.osgi.framework.BundleContext#getService(org.osgi.framework.ServiceReference)
      */
-    public Object getService(ServiceReference reference) {
+    public <S> S getService(ServiceReference<S> ref) {
         if (m_serviceContext == null) {
-            return m_bundleContext.getService(reference);
+            return m_bundleContext.getService(ref);
         } else {
-            return m_serviceContext.getService(reference);
+            return (S) m_serviceContext.getService(ref);
         }
     }
 
@@ -280,6 +290,43 @@
         }
     }
 
+     /**
+     * Gets a service reference for the given interface.
+     * This method uses the service context if specified, the bundle
+     * context otherwise.
+     * @param sClass the required interface class
+     * @param <S> the service class
+     * @return a service reference on a available provider or <code>null</code>
+     * if no providers available
+     * @see org.osgi.framework.BundleContext#getServiceReference(java.lang.String)
+     */
+    public <S> ServiceReference<S> getServiceReference(Class<S> sClass) {
+        if (m_serviceContext == null) {
+            return m_bundleContext.getServiceReference(sClass);
+        } else {
+            return m_serviceContext.getServiceReference(sClass);
+        }
+    }
+
+    /**
+     * Gets service reference list for the given query.
+     * This method uses the service context if specified, the bundle
+     * context otherwise.
+     * @param sClass the name of the required service interface
+     * @param filter the LDAP filter to apply on service provider
+     * @param <S> the service class
+     *  @return the array of consistent service reference or <code>null</code>
+     * if no available providers
+     * @throws InvalidSyntaxException if the LDAP filter is malformed
+     */
+    public <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> sClass, String filter) throws InvalidSyntaxException {
+        if (m_serviceContext == null) {
+            return m_bundleContext.getServiceReferences(sClass, filter);
+        } else {
+            return m_serviceContext.getServiceReferences(sClass, filter);
+        }
+    }
+
     /**
      * Gets service reference list for the given query.
      * This method uses the service context if specified, the bundle
@@ -379,6 +426,22 @@
     }
 
     /**
+     * Registers a service
+     * @param sClass  the service class
+     * @param s the service object (must implement sClass)
+     * @param stringDictionary service properties
+     * @param <S> the Service Class (specification)
+     * @return the service registration
+     */
+    public <S> ServiceRegistration<S> registerService(Class<S> sClass, S s, Dictionary<String, ?> stringDictionary) {
+        if (m_serviceContext == null) {
+            return m_bundleContext.registerService(sClass, s, stringDictionary);
+        } else {
+            return m_serviceContext.registerService(sClass, s, stringDictionary);
+        }
+    }
+
+    /**
      * Removes a service listener.
      * Removes the service listener from where it was registered so either in
      * the global context, or in the service context or in the internal dispatcher.
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
index 28ef113..0153683 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
@@ -20,6 +20,9 @@
 

 import java.io.File;

 import java.io.InputStream;

+import java.util.Arrays;

+import java.util.Collection;

+import java.util.Collections;

 import java.util.Dictionary;

 

 import org.osgi.framework.Bundle;

@@ -217,6 +220,35 @@
     }

 

     /**

+     * Gets a service reference.

+     * This method is delegated on PolicyServiceContext#getServiceReference(String)

+     * @param sClass the service interface class

+     * @param <S> the service interface class

+     * @return the service reference of <code>null</code> if not found

+     * @see PolicyServiceContext#getServiceReference(String)

+     */

+    public <S> ServiceReference<S> getServiceReference(Class<S> sClass) {

+        return (ServiceReference<S>) getServiceReference(sClass.getName());

+    }

+

+    /**

+     * Gets a collection of service references

+     * @param clazz the service interface class

+     * @param filter the filter

+     * @param <S> the service interface class

+     * @return the set of service reference

+     * @throws InvalidSyntaxException the filter is invalid

+     * @see PolicyServiceContext#getServiceReferences(String, String)

+     */

+    public <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz, String filter) throws InvalidSyntaxException {

+         ServiceReference<S>[] refs =

+            (ServiceReference<S>[]) getServiceReferences(clazz.getName(), filter);

+        return (refs == null)

+            ? Collections.EMPTY_LIST

+            : (Collection<ServiceReference<S>>) Arrays.asList(refs);

+    }

+

+    /**

      * Get a service reference for the required service specification.

      * The services are looked inside the context according to the policy.

      * @param clazz the required service specification

@@ -347,6 +379,15 @@
     }

 

     /**

+     * Gets a bundle by name

+     * @param s the name

+     * @return the matching bundle or <code>null</code> if not found

+     */

+    public Bundle getBundle(String s) {

+        return m_global.getBundle(s);

+    }

+

+    /**

      * Gets the current bundle.

      * @return the current bundle

      * @see org.osgi.framework.BundleContext#getBundle()

@@ -437,4 +478,17 @@
         m_global.removeFrameworkListener(listener);

     }

 

+    /**

+     * Registers a service.

+     * Operation not supported.

+     * @param sClass

+     * @param s

+     * @param stringDictionary

+     * @param <S>

+     * @return

+     */

+    public <S> ServiceRegistration<S> registerService(Class<S> sClass, S s, Dictionary<String, ?> stringDictionary) {

+        throw new UnsupportedOperationException("PolicyServiceContext can only be used for service dependency and not to provide services");

+    }

+

 }

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java
index aa56992..7d3765c 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java
@@ -79,7 +79,7 @@
      * @return the service object or null if the service reference is no more valid or if the service object is not accessible
      * @see org.osgi.framework.BundleContext#getService(org.osgi.framework.ServiceReference)
      */
-    Object getService(ServiceReference reference);
+    <S> S getService(ServiceReference<S> reference);
 
     /**
      * Gets a service reference for the given interface.
@@ -114,7 +114,7 @@
      * and does not have any meaning in other contexts.
      * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
      */
-    ServiceRegistration registerService(String[] clazzes, Object service, Dictionary properties);
+    ServiceRegistration registerService(String[] clazzes, Object service, Dictionary<String, ?> properties);
 
     /**
      * Registers a service inside this service context.
@@ -127,7 +127,7 @@
      * and does not have any meaning in other contexts.
      * @see org.osgi.framework.BundleContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
      */
-    ServiceRegistration registerService(String clazz, Object service, Dictionary properties);
+    ServiceRegistration registerService(String clazz, Object service, Dictionary<String, ?> properties);
 
     /**
      * Removes a service listener.
@@ -144,6 +144,6 @@
      * @return <code>true</code> if you are the last user of the reference.
      * @see org.osgi.framework.BundleContext#ungetService(org.osgi.framework.ServiceReference)
      */
-    boolean ungetService(ServiceReference reference);
+    boolean ungetService(ServiceReference<?> reference);
 
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
index 5dac071..26bd0a7 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -213,8 +213,7 @@
      * @param metadata the metadata of the component
      * @param configuration the instance configuration
      * @throws ConfigurationException one property metadata is not correct
-     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager,
-     * org.apache.felix.ipojo.metadata.Element)
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
     public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
         // Build the map
@@ -354,7 +353,7 @@
             // Security Check
             if (SecurityHelper.hasPermissionToRegisterService(ManagedService.class.getName(),
                     getInstanceManager().getContext())) {
-                m_sr = getInstanceManager().getContext().registerService(ManagedService.class.getName(), this, props);
+                m_sr = getInstanceManager().getContext().registerService(ManagedService.class.getName(), this, (Dictionary) props);
             } else {
                 error("Cannot register the ManagedService - The bundle "
                         + getInstanceManager().getContext().getBundle().getBundleId()
@@ -449,7 +448,7 @@
 
     /**
      * Reconfigures the given property with the given value.
-     * This methods handles {@link InstanceManager#onSet(Object, String, Object)}
+     * This methods handles {@link org.apache.felix.ipojo.InstanceManager#onSet(Object, String, Object)}
      * call and the callback invocation.
      * The reconfiguration occurs only if the value changes.
      * @param prop the property object to reconfigure
@@ -496,7 +495,7 @@
      * This method is override to allow delayed callback invocation.
      * Invokes the updated method is needed.
      * @param instance : the created object
-     * @see org.apache.felix.ipojo.Handler#onCreation(java.lang.Object)
+     * @see org.apache.felix.ipojo.PrimitiveHandler#onCreation(Object)
      */
     public void onCreation(Object instance) {
         for (int i = 0; i < m_configurableProperties.size(); i++) {
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
index 6476583..84c8f9f 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
@@ -134,7 +134,7 @@
     /**
      * The published properties.
      */
-    private Properties m_publishedProperties = new Properties();
+    private Dictionary m_publishedProperties = new Properties();
 
     /**
      * Creates a provided service object.
@@ -361,7 +361,7 @@
                                 serviceProperties);
                         m_serviceRegistration = bc.registerService(
                                 getServiceSpecificationsToRegister(), this,
-                                serviceProperties);
+                                (Dictionary) serviceProperties);
                         reg = m_serviceRegistration; // Stack confinement
                     } else {
                         throw new SecurityException("The bundle "
@@ -378,7 +378,7 @@
         // This must be call outside the synchronized block.
         if (reg != null && m_wasUpdated) {
             Properties updated = getServiceProperties();
-            reg.setProperties(updated);
+            reg.setProperties((Dictionary) updated);
             m_publishedProperties = updated;
             m_wasUpdated = false;
         }
@@ -481,8 +481,8 @@
         // Update the service registration
         if (m_serviceRegistration != null) {
             Properties updated = getServiceProperties();
-            Properties oldProps = (Properties) m_publishedProperties.clone();
-            Properties newProps = (Properties) updated.clone();
+            Dictionary oldProps = (Dictionary) ((Properties) m_publishedProperties).clone();
+            Dictionary newProps = (Dictionary) (updated.clone());
 
             // Remove keys that must not be compared
             newProps.remove("instance.name");
@@ -502,7 +502,7 @@
             if (oldProps.size() != newProps.size()) {
                 m_handler.info("Updating Registration : " + oldProps.size() + " / " + newProps.size());
                 m_publishedProperties = updated;
-                m_serviceRegistration.setProperties(updated);
+                m_serviceRegistration.setProperties((Dictionary) updated);
             } else {
                 // Check changes
                 Enumeration keys = oldProps.keys();
@@ -512,7 +512,7 @@
                     if (! val.equals(updated.get(k))) {
                         m_handler.info("Updating Registration : " + k);
                         m_publishedProperties = updated;
-                        m_serviceRegistration.setProperties(updated);
+                        m_serviceRegistration.setProperties((Dictionary) updated);
                         return;
                     }
                 }
diff --git a/ipojo/core/src/test/java/org/apache/felix/ipojo/test/MockBundle.java b/ipojo/core/src/test/java/org/apache/felix/ipojo/test/MockBundle.java
index bfc6a51..85bc1fc 100644
--- a/ipojo/core/src/test/java/org/apache/felix/ipojo/test/MockBundle.java
+++ b/ipojo/core/src/test/java/org/apache/felix/ipojo/test/MockBundle.java
@@ -1,14 +1,16 @@
 package org.apache.felix.ipojo.test;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.security.cert.X509Certificate;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
 
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceReference;
+import org.osgi.framework.*;
 
 public class MockBundle implements Bundle {
 
@@ -25,9 +27,15 @@
         return 0;
     }
 
+    public void start(int i) throws BundleException {
+    }
+
     public void start() throws BundleException {
     }
 
+    public void stop(int i) throws BundleException {
+    }
+
     public void stop() throws BundleException {
     }
 
@@ -100,4 +108,65 @@
             boolean recurse) {
         return null;
     }
+
+    public BundleContext getBundleContext() {
+        return null;
+    }
+
+    public Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int i) {
+        return null;
+    }
+
+    public Version getVersion() {
+        return null;
+    }
+
+    public <A> A adapt(Class<A> aClass) {
+        return null;
+    }
+
+    public File getDataFile(String s) {
+        return null;
+    }
+
+    /**
+     * Compares this object with the specified object for order.  Returns a
+     * negative integer, zero, or a positive integer as this object is less
+     * than, equal to, or greater than the specified object.
+     * <p/>
+     * <p>The implementor must ensure <tt>sgn(x.compareTo(y)) ==
+     * -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>.  (This
+     * implies that <tt>x.compareTo(y)</tt> must throw an exception iff
+     * <tt>y.compareTo(x)</tt> throws an exception.)
+     * <p/>
+     * <p>The implementor must also ensure that the relation is transitive:
+     * <tt>(x.compareTo(y)&gt;0 &amp;&amp; y.compareTo(z)&gt;0)</tt> implies
+     * <tt>x.compareTo(z)&gt;0</tt>.
+     * <p/>
+     * <p>Finally, the implementor must ensure that <tt>x.compareTo(y)==0</tt>
+     * implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for
+     * all <tt>z</tt>.
+     * <p/>
+     * <p>It is strongly recommended, but <i>not</i> strictly required that
+     * <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>.  Generally speaking, any
+     * class that implements the <tt>Comparable</tt> interface and violates
+     * this condition should clearly indicate this fact.  The recommended
+     * language is "Note: this class has a natural ordering that is
+     * inconsistent with equals."
+     * <p/>
+     * <p>In the foregoing description, the notation
+     * <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
+     * <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
+     * <tt>0</tt>, or <tt>1</tt> according to whether the value of
+     * <i>expression</i> is negative, zero or positive.
+     *
+     * @param o the object to be compared.
+     * @return a negative integer, zero, or a positive integer as this object
+     *         is less than, equal to, or greater than the specified object.
+     * @throws ClassCastException if the specified object's type prevents it
+     *                            from being compared to this object.
+     */
+    public int compareTo(Bundle o) {
+        return 0;
+    }
 }
\ No newline at end of file