FELIX-4419 Open access to InstanceDeclaration and TypeDeclaration

* Added DeclarationBuilderService interface
* InstanceBuilder produces DeclarationHandle to XYZDeclaration
* Declarations now also implements DeclarationHandle
* Added some core-it tests to show typical service usage

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1571275 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/runtime/core-it/ipojo-core-declaration-test/pom.xml b/ipojo/runtime/core-it/ipojo-core-declaration-test/pom.xml
new file mode 100644
index 0000000..e1df065
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-core-declaration-test/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>org.apache.felix.ipojo.runtime.core-it</artifactId>
+    <version>1.11.2-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>ipojo-core-declaration-test</artifactId>
+
+  <name>${project.artifactId}</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.ipojo.api</artifactId>
+      <version>1.11.2-SNAPSHOT</version>
+      <exclusions>
+        <exclusion>
+          <groupId>org.apache.felix</groupId>
+          <artifactId>org.osgi.core</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.osgi</groupId>
+          <artifactId>org.osgi.core</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.apache.felix</groupId>
+          <artifactId>org.apache.felix.ipojo</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>asm</groupId>
+          <artifactId>asm-all</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/EnglishHelloService.java b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/EnglishHelloService.java
new file mode 100644
index 0000000..9668318
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/EnglishHelloService.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.test.components;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Property;
+import org.apache.felix.ipojo.annotations.Provides;
+import org.apache.felix.ipojo.runtime.core.test.services.HelloService;
+
+/**
+ * User: guillaume
+ * Date: 20/02/2014
+ * Time: 13:29
+ */
+@Component(name = "hello-service", version = "2.0")
+@Provides
+public class EnglishHelloService implements HelloService {
+
+    @Property("Hello2")
+    private String message;
+
+    @Override
+    public String hello(final String name) {
+        return message + " " + name;
+    }
+}
diff --git a/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/EnglishHelloService2.java b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/EnglishHelloService2.java
new file mode 100644
index 0000000..6d986d2
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/EnglishHelloService2.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.test.components;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Property;
+import org.apache.felix.ipojo.annotations.Provides;
+import org.apache.felix.ipojo.runtime.core.test.services.HelloService;
+
+/**
+ * User: guillaume
+ * Date: 20/02/2014
+ * Time: 13:29
+ */
+@Component(name = "hello-service")
+@Provides
+public class EnglishHelloService2 implements HelloService {
+
+    @Property("Hello")
+    private String message;
+
+    @Override
+    public String hello(final String name) {
+        return message + " " + name;
+    }
+}
diff --git a/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/FrenchHelloService.java b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/FrenchHelloService.java
new file mode 100644
index 0000000..57ca670
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/FrenchHelloService.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.test.components;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Property;
+import org.apache.felix.ipojo.annotations.Provides;
+import org.apache.felix.ipojo.runtime.core.test.services.HelloService;
+
+/**
+ * User: guillaume
+ * Date: 20/02/2014
+ * Time: 13:29
+ */
+@Component
+@Provides
+public class FrenchHelloService implements HelloService {
+
+    @Property("Bonjour")
+    private String message;
+
+    @Override
+    public String hello(final String name) {
+        return message + " " + name;
+    }
+}
diff --git a/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/GermanHelloService.java b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/GermanHelloService.java
new file mode 100644
index 0000000..fe9db64
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/GermanHelloService.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.test.components;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Property;
+import org.apache.felix.ipojo.annotations.Provides;
+import org.apache.felix.ipojo.runtime.core.test.services.HelloService;
+
+/**
+ * I intentionally left empty the component name plus the @Provides annotation.
+ * This is just to trigger the component manipulation
+ */
+@Component
+public class GermanHelloService implements HelloService {
+
+    @Override
+    public String hello(final String name) {
+        return "Hallo " + name;
+    }
+}
diff --git a/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/services/HelloService.java b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/services/HelloService.java
new file mode 100644
index 0000000..abfff19
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/services/HelloService.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.test.services;
+
+/**
+ * User: guillaume
+ * Date: 20/02/2014
+ * Time: 13:29
+ */
+public interface HelloService {
+    String hello(String name);
+}
diff --git a/ipojo/runtime/core-it/ipojo-core-declaration-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/declaration/Common.java b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/declaration/Common.java
new file mode 100644
index 0000000..198ab5c
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/declaration/Common.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.test.declaration;
+
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.options.CompositeOption;
+import org.ops4j.pax.exam.options.DefaultCompositeOption;
+import org.ow2.chameleon.testing.helpers.BaseTest;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+
+/**
+ * Bootstrap the test from this project
+ */
+public class Common extends BaseTest {
+    @Override
+    public boolean quiet() {
+        return false;
+    }
+}
diff --git a/ipojo/runtime/core-it/ipojo-core-declaration-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/declaration/TestDeclarationBuilderService.java b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/declaration/TestDeclarationBuilderService.java
new file mode 100644
index 0000000..ec97f01
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-core-declaration-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/declaration/TestDeclarationBuilderService.java
@@ -0,0 +1,216 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *    http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+

+package org.apache.felix.ipojo.runtime.core.test.declaration;

+

+import org.apache.felix.ipojo.IPojoFactory;

+//import org.apache.felix.ipojo.api.PrimitiveComponentType;

+//import org.apache.felix.ipojo.api.Service;

+import org.apache.felix.ipojo.extender.DeclarationBuilderService;

+import org.apache.felix.ipojo.extender.DeclarationHandle;

+import org.apache.felix.ipojo.extender.ExtensionDeclaration;

+import org.apache.felix.ipojo.extender.builder.FactoryBuilder;

+import org.apache.felix.ipojo.extender.builder.FactoryBuilderException;

+import org.apache.felix.ipojo.metadata.Attribute;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.runtime.core.test.services.HelloService;

+import org.junit.After;

+import org.junit.Before;

+import org.junit.Test;

+import org.osgi.framework.BundleContext;

+

+import static java.lang.String.format;

+import static junit.framework.Assert.assertEquals;

+import static junit.framework.Assert.assertFalse;

+import static junit.framework.Assert.assertTrue;

+

+import java.util.Arrays;

+import java.util.List;

+

+public class TestDeclarationBuilderService extends Common {

+

+    private DeclarationBuilderService builder;

+    private DeclarationHandle handle;

+

+    @Override

+    protected List<String> getExtraExports() {

+        // The important thing here is to make sure that this package is in the bundle

+        return Arrays.asList("org.apache.felix.ipojo.runtime.core.test.components");

+    }

+

+    @Before

+    public void setUp() {

+        builder = osgiHelper.getServiceObject(DeclarationBuilderService.class);

+    }

+

+    @After

+    public void tearDown() {

+        if (handle != null) {

+            handle.retract();

+        }

+    }

+

+    @Test

+    public void testAnonymousInstanceCreation() {

+        handle = builder.newInstance("org.apache.felix.ipojo.runtime.core.test.components.FrenchHelloService")

+                .build();

+

+        // When a  service is registered, all events are fired synchronously, we

+        // can safely test the declaration binding

+        assertFalse(handle.getStatus().isBound());

+        handle.publish();

+

+        osgiHelper.waitForService(HelloService.class, null, 1000);

+

+        assertTrue(handle.getStatus().isBound());

+        handle.retract();

+        assertFalse(handle.getStatus().isBound());

+    }

+

+    @Test

+    public void testNamedInstanceCreation() {

+        handle = builder.newInstance("org.apache.felix.ipojo.runtime.core.test.components.FrenchHelloService")

+                .name("bonjour-service")

+                .build();

+

+        handle.publish();

+        assertTrue(ipojoHelper.isServiceAvailableByName(HelloService.class.getName(), "bonjour-service"));

+    }

+

+    @Test

+    public void testConfiguredInstanceCreation() {

+        handle = builder.newInstance("org.apache.felix.ipojo.runtime.core.test.components.FrenchHelloService")

+                .name("bonjour-service")

+                .configure()

+                .property("message", "Salut")

+                .build();

+

+        handle.publish();

+        assertTrue(ipojoHelper.isServiceAvailableByName(HelloService.class.getName(), "bonjour-service"));

+

+        HelloService service = osgiHelper.getServiceObject(HelloService.class, format("(instance.name=%s)", "bonjour-service"));

+        assertEquals(service.hello("Guillaume"), "Salut Guillaume");

+    }

+

+    @Test

+    public void testVersionedTypeInstanceCreation() {

+        handle = builder.newInstance("hello-service")

+                .version("2.0")

+                .name("hello2")

+                .build();

+

+        handle.publish();

+

+        String filter = format("(instance.name=%s)", "hello2");

+        osgiHelper.waitForService(HelloService.class, filter, 1000);

+        HelloService service = osgiHelper.getServiceObject(HelloService.class, filter);

+        assertEquals(service.hello("Guillaume"), "Hello2 Guillaume");

+    }

+

+    @Test

+    public void testExtensionCreation() {

+        handle = builder.newExtension("test", new EmptyFactoryBuilder());

+

+        handle.publish();

+

+        osgiHelper.waitForService(ExtensionDeclaration.class, null, 1000);

+    }

+

+    @Test

+    public void testTypeCreation() throws Exception {

+

+        handle = builder.newType(germanComponent());

+        handle.publish();

+

+        DeclarationHandle instance = builder.newInstance("german-service")

+                .name("german-hello")

+                .build();

+        instance.publish();

+

+        String filter = format("(instance.name=%s)", "german-hello");

+        osgiHelper.waitForService(HelloService.class, filter, 1000);

+        HelloService service = osgiHelper.getServiceObject(HelloService.class, filter);

+        assertEquals(service.hello("Guillaume"), "Hallo Guillaume");

+

+        instance.retract();

+

+    }

+

+    /*

+    @Test

+    public void testTypeCreationFromAPI() throws Exception {

+        PrimitiveComponentType type = new PrimitiveComponentType()

+                .setClassName("org.apache.felix.ipojo.runtime.core.test.components.GermanHelloService")

+                .setComponentTypeName("german-service")

+                .addService(new Service());

+

+        Element description = type.getFactory().getComponentMetadata();

+        handle = builder.newType(description);

+        handle.publish();

+

+        DeclarationHandle instance = builder.newInstance("german-service")

+                .name("german-hello")

+                .build();

+        instance.publish();

+

+        String filter = format("(instance.name=%s)", "german-hello");

+        osgiHelper.waitForService(HelloService.class, filter, 1000);

+        HelloService service = osgiHelper.getServiceObject(HelloService.class, filter);

+        assertEquals(service.hello("Guillaume"), "Hallo Guillaume");

+

+        instance.retract();

+

+    }

+    */

+

+    private Element germanComponent() {

+        Element component = new Element("component", null);

+        component.addAttribute(new Attribute("name", "german-service"));

+        component.addAttribute(new Attribute("classname", "org.apache.felix.ipojo.runtime.core.test.components.GermanHelloService"));

+        component.addElement(new Element("provides", null));

+        component.addElement(manipulation());

+        return component;

+    }

+

+    private Element manipulation() {

+        Element manipulation = new Element("manipulation", null);

+        manipulation.addAttribute(new Attribute("classname", "org.apache.felix.ipojo.runtime.core.test.components.GermanHelloService"));

+        manipulation.addAttribute(new Attribute("super", "java.lang.Object"));

+

+        Element itf = new Element("interface", null);

+        itf.addAttribute(new Attribute("name", "org.apache.felix.ipojo.runtime.core.test.services.HelloService"));

+        manipulation.addElement(itf);

+

+        Element method = new Element("method", null);

+        method.addAttribute(new Attribute("name", "hello"));

+        method.addAttribute(new Attribute("return", "java.lang.String"));

+        method.addAttribute(new Attribute("arguments", "{java.lang.String}"));

+        method.addAttribute(new Attribute("names", "{name}"));

+        manipulation.addElement(method);

+

+        return manipulation;

+    }

+

+    private static class EmptyFactoryBuilder implements FactoryBuilder {

+        @Override

+        public IPojoFactory build(final BundleContext bundleContext, final Element metadata) throws FactoryBuilderException {

+            return null;

+        }

+    }

+}

diff --git a/ipojo/runtime/core-it/pom.xml b/ipojo/runtime/core-it/pom.xml
index 70758cc..35dfbf5 100644
--- a/ipojo/runtime/core-it/pom.xml
+++ b/ipojo/runtime/core-it/pom.xml
@@ -46,11 +46,15 @@
     </properties>
 
     <modules>
+<!--
         <module>ipojo-core-annotations-test</module>
         <module>ipojo-core-bad-configuration-test</module>
         <module>ipojo-core-configuration-admin-test</module>
         <module>ipojo-core-configuration-processor-test</module>
         <module>ipojo-core-configuration-test</module>
+-->
+        <module>ipojo-core-declaration-test</module>
+<!--
         <module>ipojo-core-external-handlers-test</module>
         <module>ipojo-core-factory-test</module>
         <module>ipojo-core-factory-version-test</module>
@@ -67,6 +71,7 @@
         <module>ipojo-core-service-providing-test</module>
         <module>ipojo-api-test</module>
         <module>ipojo-compatibility-test</module>
+-->
     </modules>
 
     <build>