You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2013/04/24 17:06:09 UTC
svn commit: r1471456 [2/2] - in /felix/trunk/ipojo/runtime:
core-it/src/it/ipojo-core-configuration-processor-test/
core-it/src/it/ipojo-core-configuration-processor-test/src/
core-it/src/it/ipojo-core-configuration-processor-test/src/main/
core-it/src...
Added: felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationOfTwoInstances.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationOfTwoInstances.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationOfTwoInstances.java (added)
+++ felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationOfTwoInstances.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+import junit.framework.Assert;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.runtime.core.components.ConfigureTwoInstances;
+import org.apache.felix.ipojo.runtime.core.components.MyComponent;
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.Test;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.OptionUtils;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOStrategy;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.ops4j.pax.exam.CoreOptions.streamBundle;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
+
+/**
+ * Check a @Configuration with 2 instances.
+ */
+public class TestConfigurationOfTwoInstances extends Common {
+
+ @Configuration
+ public Option[] config() throws IOException {
+ deployTestedBundle = false;
+ Option[] options = super.config();
+
+ // Build a service bundle
+ return OptionUtils.combine(options,
+ streamBundle(
+ TinyBundles.bundle()
+ .add(FooService.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "ServiceInterface")
+ .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.runtime.core.services")
+ .build(withBnd())
+ ),
+ streamBundle(
+ TinyBundles.bundle()
+ .add(ConfigureTwoInstances.class)
+ .add(MyComponent.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "MyComponent")
+ .build(IPOJOStrategy.withiPOJO())
+ )
+ );
+ }
+
+ @Test
+ public void testConfiguration() {
+ if (isKF()) {
+ return; // Test disabled on KF
+ }
+
+ osgiHelper.waitForService(FooService.class, null, 10000);
+
+ // Check we have two instances
+ ServiceReference[] refs = osgiHelper.getServiceReferences(FooService.class, null);
+ Assert.assertEquals(refs.length, 2);
+
+ List<Architecture> arch = osgiHelper.getServiceObjects(Architecture.class, null);
+ for (Architecture a : arch) {
+ System.out.println("Instance " + a.getInstanceDescription().getName());
+ }
+
+ // Check name
+ Assert.assertNotNull(ipojoHelper.getServiceReferenceByName(FooService.class.getName(), "hello"));
+ Assert.assertNotNull(ipojoHelper.getServiceReferenceByName(FooService.class.getName(), "myInstance1"));
+
+ }
+
+
+}
Added: felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationWithInheritedInstance.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationWithInheritedInstance.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationWithInheritedInstance.java (added)
+++ felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationWithInheritedInstance.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+import junit.framework.Assert;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.runtime.core.components.ConfigureTwoInstancesWithInheritance;
+import org.apache.felix.ipojo.runtime.core.components.MyComponent;
+import org.apache.felix.ipojo.runtime.core.components.ParentConfiguration;
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.Test;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.OptionUtils;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOStrategy;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.ops4j.pax.exam.CoreOptions.streamBundle;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
+
+/**
+ * Check a @Configuration inheriting an instance from a parent class.
+ */
+public class TestConfigurationWithInheritedInstance extends Common {
+
+ @Configuration
+ public Option[] config() throws IOException {
+ deployTestedBundle = false;
+ Option[] options = super.config();
+
+ // Build a service bundle
+ return OptionUtils.combine(options,
+ streamBundle(
+ TinyBundles.bundle()
+ .add(FooService.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "ServiceInterface")
+ .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.runtime.core.services")
+ .build(withBnd())
+ ),
+ streamBundle(
+ TinyBundles.bundle()
+ .add(ConfigureTwoInstancesWithInheritance.class)
+ .add(ParentConfiguration.class)
+ .add(MyComponent.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "MyComponent")
+ .build(IPOJOStrategy.withiPOJO())
+ )
+ );
+ }
+
+ @Test
+ public void testConfiguration() {
+ if (isKF()) {
+ return; // Test disabled on KF
+ }
+
+ osgiHelper.waitForService(FooService.class, null, 10000);
+
+ // Check we have two instances
+ ServiceReference[] refs = osgiHelper.getServiceReferences(FooService.class, null);
+ Assert.assertEquals(refs.length, 2);
+
+ List<Architecture> arch = osgiHelper.getServiceObjects(Architecture.class, null);
+ for (Architecture a : arch) {
+ System.out.println("Instance " + a.getInstanceDescription().getName());
+ }
+
+ // Check name
+ Assert.assertNotNull(ipojoHelper.getServiceReferenceByName(FooService.class.getName(), "hello"));
+ Assert.assertNotNull(ipojoHelper.getServiceReferenceByName(FooService.class.getName(), "myInstance1"));
+
+ }
+
+
+}
Added: felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationWithOverriddenInstance.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationWithOverriddenInstance.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationWithOverriddenInstance.java (added)
+++ felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestConfigurationWithOverriddenInstance.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+import junit.framework.Assert;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.runtime.core.components.ConfigureTwoInstancesWithOverridding;
+import org.apache.felix.ipojo.runtime.core.components.MyComponent;
+import org.apache.felix.ipojo.runtime.core.components.ParentConfiguration;
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.Test;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.OptionUtils;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOStrategy;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.ops4j.pax.exam.CoreOptions.streamBundle;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
+
+/**
+ * Check a @Configuration overriding instance declaration.
+ */
+public class TestConfigurationWithOverriddenInstance extends Common {
+
+ @Configuration
+ public Option[] config() throws IOException {
+ deployTestedBundle = false;
+ Option[] options = super.config();
+
+ // Build a service bundle
+ return OptionUtils.combine(options,
+ streamBundle(
+ TinyBundles.bundle()
+ .add(FooService.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "ServiceInterface")
+ .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.runtime.core.services")
+ .build(withBnd())
+ ),
+ streamBundle(
+ TinyBundles.bundle()
+ .add(ConfigureTwoInstancesWithOverridding.class)
+ .add(ParentConfiguration.class)
+ .add(MyComponent.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "MyComponent")
+ .build(IPOJOStrategy.withiPOJO())
+ )
+ );
+ }
+
+ @Test
+ public void testConfiguration() {
+ if (isKF()) {
+ return; // Test disabled on KF
+ }
+
+ osgiHelper.waitForService(FooService.class, null, 10000);
+
+ // Check we have two instances
+ ServiceReference[] refs = osgiHelper.getServiceReferences(FooService.class, null);
+ Assert.assertEquals(refs.length, 2);
+
+ List<Architecture> arch = osgiHelper.getServiceObjects(Architecture.class, null);
+ for (Architecture a : arch) {
+ System.out.println("Instance " + a.getInstanceDescription().getName());
+ }
+
+ // Check name
+ Assert.assertNotNull(ipojoHelper.getServiceReferenceByName(FooService.class.getName(), "hello-over"));
+ Assert.assertNotNull(ipojoHelper.getServiceReferenceByName(FooService.class.getName(), "myInstance1"));
+
+ }
+
+
+}
Added: felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestEmptyConfiguration.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestEmptyConfiguration.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestEmptyConfiguration.java (added)
+++ felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestEmptyConfiguration.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,76 @@
+/*
+ * 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;
+
+import junit.framework.Assert;
+import org.apache.felix.ipojo.runtime.core.components.ConfigureNothing;
+import org.apache.felix.ipojo.runtime.core.components.MyComponent;
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.Test;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.OptionUtils;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Constants;
+import org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOStrategy;
+
+import java.io.IOException;
+
+import static org.ops4j.pax.exam.CoreOptions.streamBundle;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
+
+/**
+ * Check an empty @Configuration
+ */
+public class TestEmptyConfiguration extends Common {
+
+ @Configuration
+ public Option[] config() throws IOException {
+ deployTestedBundle = false;
+ Option[] options = super.config();
+
+ // Build a service bundle
+ return OptionUtils.combine(options,
+ streamBundle(
+ TinyBundles.bundle()
+ .add(FooService.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "ServiceInterface")
+ .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.runtime.core.services")
+ .build(withBnd())
+ ),
+ streamBundle(
+ TinyBundles.bundle()
+ .add(MyComponent.class)
+ .add(ConfigureNothing.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "MyComponent")
+ .build(IPOJOStrategy.withiPOJO())
+ )
+ );
+ }
+
+ @Test
+ public void testConfiguration() throws InterruptedException {
+ Thread.sleep(200);
+ // Check configuration
+ Assert.assertNull(osgiHelper.getServiceReference(FooService.class));
+ }
+
+
+}
Added: felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestSeveralConfigurations.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestSeveralConfigurations.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestSeveralConfigurations.java (added)
+++ felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-processor-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestSeveralConfigurations.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+import junit.framework.Assert;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.runtime.core.components.ConfigureAnotherInstance;
+import org.apache.felix.ipojo.runtime.core.components.ConfigureOneInstance;
+import org.apache.felix.ipojo.runtime.core.components.MyComponent;
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.Test;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.OptionUtils;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOStrategy;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.ops4j.pax.exam.CoreOptions.streamBundle;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
+
+/**
+ * Check several configuration @Configuration in the same bundle.
+ */
+public class TestSeveralConfigurations extends Common {
+
+ @Configuration
+ public Option[] config() throws IOException {
+ deployTestedBundle = false;
+ Option[] options = super.config();
+
+ // Build a service bundle
+ return OptionUtils.combine(options,
+ streamBundle(
+ TinyBundles.bundle()
+ .add(FooService.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "ServiceInterface")
+ .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.runtime.core.services")
+ .build(withBnd())
+ ),
+ streamBundle(
+ TinyBundles.bundle()
+ .add(ConfigureOneInstance.class)
+ .add(ConfigureAnotherInstance.class)
+ .add(MyComponent.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "MyComponent")
+ .build(IPOJOStrategy.withiPOJO())
+ )
+ );
+ }
+
+ @Test
+ public void testConfiguration() {
+ if (isKF()) {
+ return; // Test disabled on KF
+ }
+
+ osgiHelper.waitForService(FooService.class, null, 10000);
+
+ // Check we have two instances
+ ServiceReference[] refs = osgiHelper.getServiceReferences(FooService.class, null);
+ Assert.assertEquals(refs.length, 2);
+
+ List<Architecture> arch = osgiHelper.getServiceObjects(Architecture.class, null);
+ for (Architecture a : arch) {
+ System.out.println("Instance " + a.getInstanceDescription().getName());
+ }
+
+ // Check name
+ Assert.assertNotNull(ipojoHelper.getServiceReferenceByName(FooService.class.getName(), "anotherInstance"));
+ Assert.assertNotNull(ipojoHelper.getServiceReferenceByName(FooService.class.getName(), "myInstance"));
+
+ }
+
+
+}
Modified: felix/trunk/ipojo/runtime/core/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/pom.xml?rev=1471456&r1=1471455&r2=1471456&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/pom.xml (original)
+++ felix/trunk/ipojo/runtime/core/pom.xml Wed Apr 24 15:06:07 2013
@@ -116,11 +116,14 @@
</IPOJO-Extension>
<Import-Package>
org.osgi.framework;version=1.3, <!-- To support KF 2 -->
+ org.osgi.framework.wiring;resolution:=optional,
org.osgi.service.cm,
org.osgi.service.log,
org.osgi.util.tracker;version=1.3,
!sun.io,
- !net.sourceforge.cobertura.* <!-- To support code coverage -->
+ !net.sourceforge.cobertura.*, <!-- To support code coverage -->
+ !org.objectweb.asm.signature,
+ !org.objectweb.asm.tree
</Import-Package>
<Private-Package>
org.apache.felix.ipojo.handlers.architecture,
@@ -128,6 +131,7 @@
org.apache.felix.ipojo.handlers.lifecycle.controller,
org.apache.felix.ipojo.extender.internal*,
org.objectweb.asm;-split-package:=merge-last,
+ org.objectweb.asm.commons;-split-package:=merge-last,
org.apache.felix.ipojo.metadata,
<!-- Compendium packages -->
org.osgi.service.cm,
@@ -135,6 +139,7 @@
</Private-Package>
<Export-Package>
org.apache.felix.ipojo; version="${ipojo.package.version}",
+ org.apache.felix.ipojo.configuration; version="${ipojo.package.version}",
org.apache.felix.ipojo.metadata; version="${ipojo.package.version}",
org.apache.felix.ipojo.architecture; version="${ipojo.package.version}",
org.apache.felix.ipojo.extender;
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Configuration.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Configuration.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Configuration.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Configuration.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,32 @@
+/*
+ * 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.configuration;
+
+/**
+ * A marker interface to detect configurations
+ */
+public @interface Configuration {
+
+ /**
+ * An optional name
+ * @return the optional configuration name
+ */
+ String value() default "";
+}
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,173 @@
+/*
+ * 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.configuration;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+
+import java.util.*;
+
+/**
+ * Instance Builder
+ */
+public class Instance {
+
+ private String factory;
+ private String name;
+ private List<Property> configuration;
+
+ public static Instance instance() {
+ return new Instance();
+ }
+
+ public static <T> FluentList<T> list(T... items) {
+ return new FluentList<T>(items);
+ }
+
+ public static <K, T> FluentMap<K, T> map(Pair<K, T>... pairs) {
+ return new FluentMap<K, T>(pairs);
+ }
+
+ public static <K, T> Pair<K, T> pair(K k, T v) {
+ return new Pair<K, T>(k, v);
+ }
+
+ public String factory() {
+ return factory;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ public Dictionary<String, Object> configuration() {
+ Hashtable<String, Object> configuration = new Hashtable<String, Object>();
+ for (Property property : this.configuration) {
+ configuration.put(property.name, property.value);
+ }
+
+ if (name != null) {
+ configuration.put(Factory.INSTANCE_NAME_PROPERTY, name);
+ }
+
+ return configuration;
+ }
+
+ public Instance of(String factory) {
+ this.factory = factory;
+ return this;
+ }
+
+ public Instance of(Class clazz) {
+ this.factory = clazz.getName();
+ return this;
+ }
+
+ public Instance named(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Instance.Property<Object> with(String property) {
+ if (this.configuration == null) {
+ this.configuration = new ArrayList<Property>();
+ }
+ Property<Object> prop = new Property<Object>(property);
+ this.configuration.add(prop);
+ return prop;
+ }
+
+ public Instance nameIfUnnamed(String name) {
+ if (this.name == null) {
+ this.name = name;
+ }
+ return this;
+ }
+
+ public static class FluentList<T> extends ArrayList<T> {
+
+ public FluentList() {
+ super(new ArrayList<T>());
+ }
+
+ public FluentList(T... items) {
+ this();
+ addAll(Arrays.asList(items));
+ }
+
+ public FluentList<T> with(T o) {
+ add(o);
+ return this;
+ }
+ }
+
+ public static class FluentMap<K,T> extends LinkedHashMap<K, T> {
+
+ public FluentMap() {
+ super(new LinkedHashMap<K, T>());
+ }
+
+ public FluentMap(Pair<? extends K, ? extends T>... pairs) {
+ this();
+ with(pairs);
+ }
+
+ public FluentMap<K, T> with(Pair<? extends K, ? extends T>... pairs) {
+ for (Pair<? extends K, ? extends T> pair : pairs) {
+ this.put(pair.key, pair.value);
+ }
+ return this;
+ }
+
+ public FluentMap<K, T> putAt(K k, T value) {
+ this.put(k, value);
+ return this;
+ }
+ }
+
+ public static class Pair<K, V> {
+ private final K key;
+ private final V value;
+
+ Pair(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+ }
+
+ public class Property<T> {
+
+ private final String name;
+ private T value;
+
+ Property(String name) {
+ this.name = name;
+ }
+
+ public Instance setto(T value) {
+ this.value = value;
+ return Instance.this;
+ }
+
+ public T get() {
+ return value;
+ }
+ }
+}
Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java?rev=1471456&r1=1471455&r2=1471456&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java Wed Apr 24 15:06:07 2013
@@ -21,10 +21,7 @@ package org.apache.felix.ipojo.extender.
import org.apache.felix.ipojo.EventDispatcher;
import org.apache.felix.ipojo.extender.internal.linker.DeclarationLinker;
-import org.apache.felix.ipojo.extender.internal.processor.ChainedBundleProcessor;
-import org.apache.felix.ipojo.extender.internal.processor.ComponentsBundleProcessor;
-import org.apache.felix.ipojo.extender.internal.processor.ExtensionBundleProcessor;
-import org.apache.felix.ipojo.extender.internal.processor.QueuingActivationProcessor;
+import org.apache.felix.ipojo.extender.internal.processor.*;
import org.apache.felix.ipojo.extender.internal.queue.ExecutorQueueService;
import org.apache.felix.ipojo.extender.internal.queue.PrefixedThreadFactory;
import org.apache.felix.ipojo.extender.internal.queue.SynchronousQueueService;
@@ -120,6 +117,7 @@ public class Extender implements BundleA
BundleProcessor extensionBundleProcessor = new ExtensionBundleProcessor(m_logger);
BundleProcessor componentsProcessor = new ComponentsBundleProcessor(m_logger);
+ BundleProcessor configurationProcessor = new ConfigurationProcessor(m_logger);
if (SYNCHRONOUS_PROCESSING_ENABLED) {
m_queueService = new EnforcedQueueService(
new HeaderPreferenceSelection(),
@@ -133,6 +131,7 @@ public class Extender implements BundleA
extensionBundleProcessor = new QueuingActivationProcessor(extensionBundleProcessor, m_queueService);
componentsProcessor = new QueuingActivationProcessor(componentsProcessor, m_queueService);
+ configurationProcessor = new QueuingActivationProcessor(configurationProcessor, m_queueService);
}
m_queueService.start();
@@ -140,7 +139,7 @@ public class Extender implements BundleA
m_linker = new DeclarationLinker(context, m_queueService);
m_linker.start();
- m_processor = ChainedBundleProcessor.create(extensionBundleProcessor, componentsProcessor);
+ m_processor = ChainedBundleProcessor.create(extensionBundleProcessor, componentsProcessor, configurationProcessor);
m_processor.start();
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ConfigurationAnnotationScanner.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ConfigurationAnnotationScanner.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ConfigurationAnnotationScanner.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ConfigurationAnnotationScanner.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,67 @@
+/*
+ * 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.extender.internal.processor;
+
+import org.apache.felix.ipojo.configuration.Configuration;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+/**
+ * Class visitor detecting @Configuration annotation.
+ * <p/>
+ * After the visit, two state variables are set:
+ * {@literal isConfiguration} is set to true if the class contained the @Configuration annotation
+ * {@literal parent} is set to the parent class if and only if it's not a java.* class (which don't contain the
+ * Configuration annotation) and {@literal isConfiguration} is set to false
+ */
+public class ConfigurationAnnotationScanner extends EmptyVisitor implements Opcodes {
+
+ private static final String CONFIGURATION_ANNOTATION_DESCRIPTOR = Type.getType(Configuration.class)
+ .getDescriptor();
+ private boolean m_isConfiguration = false;
+ private String m_super;
+
+
+ @Override
+ public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+ m_super = superName; // This is the internal class name.
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String desc, boolean vis) {
+ if (desc.equals(CONFIGURATION_ANNOTATION_DESCRIPTOR)) {
+ m_isConfiguration = true;
+ }
+ return null;
+ }
+
+ public boolean isConfiguration() {
+ return m_isConfiguration;
+ }
+
+ public String getParent() {
+ if (m_super == null || m_super.startsWith("java/") || m_isConfiguration) {
+ return null;
+ }
+ return m_super.replace("/", ".");
+ }
+}
Copied: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ConfigurationProcessor.java (from r1465972, felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ComponentsBundleProcessor.java)
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ConfigurationProcessor.java?p2=felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ConfigurationProcessor.java&p1=felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ComponentsBundleProcessor.java&r1=1465972&r2=1471456&rev=1471456&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ComponentsBundleProcessor.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/processor/ConfigurationProcessor.java Wed Apr 24 15:06:07 2013
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -19,60 +19,72 @@
package org.apache.felix.ipojo.extender.internal.processor;
+import org.apache.felix.ipojo.configuration.Instance;
import org.apache.felix.ipojo.extender.internal.BundleProcessor;
import org.apache.felix.ipojo.extender.internal.declaration.DefaultInstanceDeclaration;
import org.apache.felix.ipojo.extender.internal.declaration.DefaultTypeDeclaration;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.parser.ManifestMetadataParser;
-import org.apache.felix.ipojo.parser.ParseException;
+import org.apache.felix.ipojo.util.InvocationResult;
import org.apache.felix.ipojo.util.Log;
-import org.apache.felix.ipojo.util.Logger;
+import org.objectweb.asm.ClassReader;
import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.wiring.BundleWiring;
import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.URL;
import java.util.*;
+import static org.apache.felix.ipojo.util.Reflection.fields;
+import static org.apache.felix.ipojo.util.Reflection.methods;
+
/**
- * Processor handling the {@link #IPOJO_HEADER} and {@link #IPOJO_HEADER_ALT}
- * header from the bundle manifest.
+ * Processor looking for classes annotated with @Configuration and creating the corresponding instance declaration.
*/
-public class ComponentsBundleProcessor implements BundleProcessor {
-
- /**
- * iPOJO Component Type and Instance declaration header.
- */
- public static final String IPOJO_HEADER = "iPOJO-Components";
-
- /**
- * iPOJO Component Type and Instance declaration header
- * (alternative).
- * This header was introduced because of BND supporting only header
- * starting with an uppercase.
- */
- public static final String IPOJO_HEADER_ALT = "IPOJO-Components";
-
- /**
- * The attribute used in instance configuration specifying the targeted component (i.e. factory).
- */
- public static final String COMPONENT_INSTANCE_ATTRIBUTE = "component";
+public class ConfigurationProcessor implements BundleProcessor {
/**
* The logger.
*/
private final Log m_logger;
-
/**
* Registry storing the bundle to components and instances declared within this bundle.
+ * Only instances are expected.
*/
private final Map<Bundle, ComponentsAndInstances> m_registry = new HashMap<Bundle, ComponentsAndInstances>();
+ private final boolean m_enabled;
/**
- * Creates the component bundle processor.
+ * Creates the configuration processor.
*
* @param logger the logger.
*/
- public ComponentsBundleProcessor(Log logger) {
+ public ConfigurationProcessor(Log logger) {
+
m_logger = logger;
+
+ // org.osgi.framework.wiring may not be available, in this case, disable us.
+ try {
+ this.getClass().getClassLoader().loadClass("org.osgi.framework.wiring.BundleWiring");
+ } catch (ClassNotFoundException e) {
+ m_logger.log(Log.ERROR, "The org.osgi.framework.wiring.BundleWiring class is not provided by the " +
+ "framework, configuration processor disabled.");
+ m_enabled = false;
+ return;
+ }
+ // Check ok.
+ m_enabled = true;
+ }
+
+ public static String getClassNameFromResource(String resource) {
+ String res = resource;
+ if (resource.startsWith("/")) {
+ res = resource.substring(1); // Remove the first /
+ }
+ res = res.substring(0, res.length() - ".class".length()); // Remove the .class
+ return res.replace("/", ".");
}
/**
@@ -81,24 +93,28 @@ public class ComponentsBundleProcessor i
* @param bundle the bundle
*/
public void activate(Bundle bundle) {
- Dictionary dict = bundle.getHeaders();
- // Check bundle
- String header = (String) dict.get(IPOJO_HEADER);
- // Check the alternative header
- if (header == null) {
- header = (String) dict.get(IPOJO_HEADER_ALT);
- }
+ if (! m_enabled) { return; }
- if (header != null) {
- try {
- parse(bundle, header);
- } catch (IOException e) {
- m_logger.log(Logger.ERROR, "An exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);
- } catch (ParseException e) {
- m_logger.log(Logger.ERROR, "A parse exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);
- }
+ // TODO - optimization, ignore all bundles that do not import org.apache.felix.ipojo.configuration
+
+ BundleWiring wiring = bundle.adapt(BundleWiring.class);
+ if (wiring == null) {
+ // Invalid state.
+ m_logger.log(Log.ERROR, "The bundle " + bundle.getBundleId() + " (" + bundle.getSymbolicName() + ") " +
+ "cannot be adapted to BundleWiring, state: " + bundle.getState());
+ return;
}
+ // Only lookup for local classes, parent classes will be analyzed on demand.
+ Collection<String> resources = wiring.listResources("/", "*.class",
+ BundleWiring.FINDENTRIES_RECURSE + BundleWiring.LISTRESOURCES_LOCAL);
+ if (resources == null) {
+ m_logger.log(Log.ERROR, "The bundle " + bundle.getBundleId() + " (" + bundle.getSymbolicName() + ") " +
+ " does not have any classes to be analyzed");
+ return;
+ }
+ m_logger.log(Log.DEBUG, resources.size() + " classes found");
+ handleResources(bundle, resources, wiring.getClassLoader());
}
/**
@@ -107,6 +123,8 @@ public class ComponentsBundleProcessor i
* @param bundle the bundle
*/
public void deactivate(Bundle bundle) {
+ if (! m_enabled) { return; }
+
ComponentsAndInstances cai = m_registry.remove(bundle);
if (cai != null) {
cai.stop();
@@ -129,64 +147,119 @@ public class ComponentsBundleProcessor i
// Ignored, for a simple ordered shutdown, use ReverseBundleProcessor
}
- /**
- * Parses the internal metadata (from the manifest
- * (in the iPOJO-Components property)). This methods
- * creates factories and add instances to the instance creator.
- *
- * @param bundle the owner bundle.
- * @param components The iPOJO Header String.
- * @throws IOException if the manifest can not be found
- * @throws ParseException if the parsing process failed
- */
- private void parse(Bundle bundle, String components) throws IOException, ParseException {
- ManifestMetadataParser parser = new ManifestMetadataParser();
- parser.parseHeader(components);
+ private void handleResources(Bundle bundle, Collection<String> resources, ClassLoader classLoader) {
+ for (String resource : resources) {
+ handleResource(bundle, resource, classLoader);
+ }
+ }
- // Get the component type declaration
- Element[] metadata = parser.getComponentsMetadata();
- for (int i = 0; i < metadata.length; i++) {
- handleTypeDeclaration(bundle, metadata[i]);
+ private void handleResource(Bundle bundle, String resource, ClassLoader classLoader) {
+ URL url = classLoader.getResource(resource);
+ if (url == null) {
+ m_logger.log(Log.ERROR, "The resource " + resource + " cannot be loaded by " + bundle.getBundleId() + " " +
+ "(" + bundle.getSymbolicName() + ")");
+ return;
}
- Dictionary[] instances = parser.getInstances();
- for (int i = 0; instances != null && i < instances.length; i++) {
- handleInstanceDeclaration(bundle, instances[i]);
+ try {
+ if (hasConfigurationAnnotation(bundle, url, classLoader)) {
+ instantiateAndDeclareInstances(bundle, resource, classLoader);
+ }
+ } catch (IOException e) {
+ m_logger.log(Log.ERROR, "The resource " + resource + " cannot be loaded by " + bundle.getBundleId() + " " +
+ "(" + bundle.getSymbolicName() + ")", e);
}
- }
- /**
- * Extracts and builds the declaration attached to an instance.
- *
- * @param bundle the bundle declaring the instance
- * @param instance the instance configuration (parsed from the header)
- */
- private void handleInstanceDeclaration(Bundle bundle, Dictionary instance) {
+ }
- String component = (String) instance.get(COMPONENT_INSTANCE_ATTRIBUTE);
- //String v = (String) instance.get(Factory.FACTORY_VERSION_PROPERTY); //TODO CES to GSA, why this is commented ?
+ private void instantiateAndDeclareInstances(Bundle bundle, String resource, ClassLoader classLoader) {
+ String classname = getClassNameFromResource(resource);
+ List<Instance> instances = new ArrayList<Instance>();
+ try {
+ Class clazz = classLoader.loadClass(classname);
+ Object configuration = clazz.newInstance();
+
+ // Collect fields
+ Map<Field, Instance> fields =
+ fields().ofType(Instance.class).in(configuration).map();
+ for (Map.Entry<Field, Instance> entry : fields.entrySet()) {
+ Instance instance = entry.getValue();
+ instance.nameIfUnnamed(entry.getKey().getName());
+ instances.add(instance);
+ }
- DefaultInstanceDeclaration declaration = new DefaultInstanceDeclaration(bundle.getBundleContext(),
- component, instance);
- declaration.start();
+ // Collect methods with Bundle Context as argument
+ Map<Method, InvocationResult<Instance>> methods =
+ methods().in(configuration).ofReturnType(Instance.class).withParameter(BundleContext.class)
+ .map(bundle.getBundleContext());
+
+ // Collect methods without arguments
+ methods.putAll(methods().in(configuration).ofReturnType(Instance.class).map());
+
+ for (Map.Entry<Method, InvocationResult<Instance>> entry : methods.entrySet()) {
+ Instance instance = entry.getValue().get();
+ if (instance == null) {
+ m_logger.log(Log.ERROR, "The Instance declaration creation failed because the method " + entry
+ .getKey().getName() + " of class " + entry.getKey().getDeclaringClass() + " threw an " +
+ "exception", entry.getValue().error());
+ } else {
+ instance.nameIfUnnamed(entry.getKey().getName());
+ instances.add(instance);
+ }
+ }
- getComponentsAndInstances(bundle).m_instances.add(declaration);
+ } catch (ClassNotFoundException e) {
+ m_logger.log(Log.ERROR, "Cannot load class " + classname + " despite it was considered as a " +
+ "configuration", e);
+ return;
+ } catch (InstantiationException e) {
+ m_logger.log(Log.ERROR, "Cannot instantiate class " + classname + " despite it was considered as a " +
+ "configuration", e);
+ return;
+ } catch (IllegalAccessException e) {
+ m_logger.log(Log.ERROR, "Cannot instantiate class " + classname + " despite it was considered as a " +
+ "configuration", e);
+ return;
+ }
+ m_logger.log(Log.WARNING, instances.size() + " instances found in class " + classname);
+ //Build and enqueue declaration
+ for (Instance instance : instances) {
+ DefaultInstanceDeclaration declaration = new DefaultInstanceDeclaration(bundle.getBundleContext(),
+ instance.factory(), instance.configuration());
+ declaration.start();
+ getComponentsAndInstances(bundle).m_instances.add(declaration);
+ }
}
- /**
- * Adds a component factory to the factory list.
- *
- * @param metadata the new component metadata.
- * @param bundle the bundle.
- */
- private void handleTypeDeclaration(Bundle bundle, Element metadata) {
-
- DefaultTypeDeclaration declaration = new DefaultTypeDeclaration(bundle.getBundleContext(), metadata);
- declaration.start();
-
- getComponentsAndInstances(bundle).m_types.add(declaration);
-
+ private boolean hasConfigurationAnnotation(Bundle bundle, URL url, ClassLoader classLoader) throws IOException {
+ InputStream is = url.openStream();
+ try {
+ ClassReader reader = new ClassReader(is);
+ ConfigurationAnnotationScanner scanner = new ConfigurationAnnotationScanner();
+ reader.accept(scanner, 0);
+
+ // Only class with the @Configuration are considered, parent classes are not analyzed.
+ // Indeed, we have to detect when the parent must be considered independently,
+ // or when only the daughter needs too (to avoid creating the instances twice).
+
+ return scanner.isConfiguration();
+
+ // The following code would traverse the whole class hierarchy.
+// if (scanner.isConfiguration()) {
+// return true;
+// } else if (scanner.getParent() != null) {
+// URL parentUrl = classLoader.getResource("/" + scanner.getParent().replace(".", "/") + ".class");
+// if (parentUrl == null) {
+// m_logger.log(Log.DEBUG, "Cannot load the parent class " + scanner.getParent() + " - stopping " +
+// "scan");
+// return false;
+// }
+// return hasConfigurationAnnotation(bundle, parentUrl, classLoader);
+// }
+ } finally {
+ is.close();
+ }
}
/**
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Fields.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Fields.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Fields.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Fields.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,134 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+* Fluent API to retrieve fields of a given type.
+*/
+public class Fields<T> {
+
+ private Class<? extends T> type;
+ private Class<?> clazz;
+ private Object object;
+ private Map<String, Field> fields;
+
+ public Collection<T> get() {
+ return map().values();
+ }
+
+ public Map<Field, T> map(Object o) {
+ this.object = o;
+ return map();
+ }
+
+ public Map<Field, T> map() {
+ Collection<Field> set = retrieve();
+ Map<Field, T> results = new LinkedHashMap<Field, T>();
+ for (Field field : set) {
+ if (!field.isAccessible()) {
+ field.setAccessible(true);
+ }
+
+ try {
+ results.put(field, (T) field.get(object));
+ } catch (IllegalAccessException e) {
+ // Hopefully should not happen.
+ }
+ }
+ return results;
+ }
+
+ public Collection<T> get(Object o) {
+ this.object = o;
+ return get();
+ }
+
+ public Fields ofType(Class<? extends T> clazz) {
+ this.type = clazz;
+ return this;
+ }
+
+ public Fields in(Object o) {
+ this.object = o;
+ this.clazz = o.getClass();
+ return this;
+ }
+
+ public Fields in(Class<?> c) {
+ this.clazz = c;
+ return this;
+ }
+
+ private Collection<Field> retrieve() {
+ if (fields != null) {
+ return fields.values();
+ }
+
+ if (clazz == null) {
+ throw new NullPointerException("Cannot retrieve field, class not set");
+ }
+
+
+ fields = new LinkedHashMap<String, Field>();
+
+ // First the class itself
+ Field[] list = clazz.getDeclaredFields();
+ for (Field field : list) {
+ if (type == null || type.isAssignableFrom(field.getType())) {
+ fields.put(field.getName(), field);
+ }
+ }
+
+ // Traverse class hierarchy
+ if (clazz.getSuperclass() != null) {
+ traverse(fields, clazz.getSuperclass());
+ }
+
+ return fields.values();
+ }
+
+ private void traverse(Map<String, Field> fields, Class<?> clazz) {
+ // First the given class
+ Field[] list = clazz.getDeclaredFields();
+ for (Field field : list) {
+ if (type == null || type.isAssignableFrom(field.getType())) {
+ // Already defined by a daughter class
+ if (!fields.containsKey(field.getName())) {
+ // Check visibility if must be either public or protected.
+ if (Modifier.isPublic(field.getModifiers()) || Modifier.isProtected(field.getModifiers())) {
+ fields.put(field.getName(), field);
+ }
+ }
+ }
+ }
+
+ // If we have a parent class, traverse it
+ if (clazz.getSuperclass() != null) {
+ traverse(fields, clazz.getSuperclass());
+ }
+ }
+
+}
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/InvocationResult.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/InvocationResult.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/InvocationResult.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/InvocationResult.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,76 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Wraps the result of a method invocation
+ */
+public class InvocationResult<T> {
+
+ private final Method method;
+ private final Object target;
+ private final T result;
+ private final Throwable error;
+
+ public InvocationResult(Method method, Object target, T result, Throwable error) {
+ this.method = method;
+ this.target = target;
+ this.result = result;
+ this.error = error;
+ }
+
+ public Method getMethod() {
+ return method;
+ }
+
+ public Object getTarget() {
+ return target;
+ }
+
+ public Throwable error() {
+ return error;
+ }
+
+ public T get() {
+ return result;
+ }
+
+ public T getOrElse(T def) {
+ if (error == null) {
+ return def;
+ } else {
+ return result;
+ }
+ }
+
+ public static <T> InvocationResult<T> fromInvocation(Method method, Object target, Object[] args) {
+ try {
+ T result = (T) method.invoke(target, args);
+ return new InvocationResult<T>(method, target, result, null);
+ } catch (IllegalAccessException e) {
+ return new InvocationResult<T>(method, target, null, e);
+ } catch (InvocationTargetException e) {
+ return new InvocationResult<T>(method, target, null, e);
+ }
+ }
+}
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Methods.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Methods.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Methods.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Methods.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,189 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+/**
+ * Fluent API to retrieve methods.
+ */
+public class Methods<T> {
+
+ private Class<? extends T> returnType;
+ private List<Class<?>> argumentTypes = new ArrayList<Class<?>>();
+ private Class<?> clazz;
+ private Object object;
+ private List<Method> methods;
+
+ public Map<Method, InvocationResult<T>> map(Object... args) {
+ Collection<Method> set = retrieve();
+ Map<Method, InvocationResult<T>> results = new LinkedHashMap<Method, InvocationResult<T>>();
+ for (Method method : set) {
+ if (!method.isAccessible()) {
+ method.setAccessible(true);
+ }
+
+ results.put(method, InvocationResult.<T>fromInvocation(method, object, args));
+
+ }
+ return results;
+ }
+
+ public Collection<InvocationResult<T>> invoke(Object... args) {
+ return map(args).values();
+ }
+
+ public Methods ofReturnType(Class<? extends T> clazz) {
+ this.returnType = clazz;
+ return this;
+ }
+
+ public Methods withParameter(Class<?>... type) {
+ argumentTypes.addAll(Arrays.asList(type));
+ return this;
+ }
+
+ public Methods in(Object o) {
+ this.object = o;
+ this.clazz = o.getClass();
+ return this;
+ }
+
+ public Methods in(Class<?> c) {
+ this.clazz = c;
+ this.object = null;
+ return this;
+ }
+
+ private Collection<Method> retrieve() {
+ if (methods != null) {
+ return methods;
+ }
+
+ if (clazz == null) {
+ throw new NullPointerException("Cannot retrieve method, class not set");
+ }
+
+
+ methods = new ArrayList<Method>();
+
+ // First the class itself
+ Method[] list = clazz.getDeclaredMethods();
+ for (Method method : list) {
+ // Two criteria : the return type and the argument type
+ if (matchReturnType(method)
+ && matchArgumentTypes(method)) {
+ // The method matches
+ methods.add(method);
+ }
+ }
+
+ // Traverse class hierarchy
+ if (clazz.getSuperclass() != null) {
+ traverse(methods, clazz.getSuperclass());
+ }
+
+ return methods;
+ }
+
+ private boolean matchReturnType(Method method) {
+ if (returnType == null) { // Void.
+ return method.getReturnType() == null;
+ }
+
+ return !(method.getReturnType() == null || !returnType.isAssignableFrom(method.getReturnType()));
+ }
+
+ private boolean matchArgumentTypes(Method method) {
+ // Fast check, the size must be the same.
+ if (argumentTypes.size() != method.getParameterTypes().length) {
+ return false;
+ }
+
+ // We have the same size.
+ for (int i = 0; i < argumentTypes.size(); i++) {
+ Class<?> argType = method.getParameterTypes()[i];
+ if (!argumentTypes.get(i).isAssignableFrom(argType)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean matchInheritanceVisibility(Method method) {
+ return Modifier.isPublic(method.getModifiers()) || Modifier.isProtected(method.getModifiers());
+ }
+
+ private boolean matchNotOverridden(Method method, List<Method> methods) {
+ for (Method meth : methods) {
+ if (methodEquality(meth, method)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Compares this <code>Method</code> against the specified object. Returns
+ * true if the objects are the same. Two <code>Methods</code> are the same if
+ * they were declared by the same class and have the same name
+ * and formal parameter types and return type.
+ */
+ private boolean methodEquality(Method method1, Method method2) {
+ if (method1.getName().equals(method2.getName())) {
+ if (!method1.getReturnType().equals(method2.getReturnType())) {
+ return false;
+ }
+
+ Class[] params1 = method1.getParameterTypes();
+ Class[] params2 = method2.getParameterTypes();
+ if (params1.length == params2.length) {
+ for (int i = 0; i < params1.length; i++) {
+ if (params1[i] != params2[i])
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ return false;
+ }
+
+ private void traverse(List<Method> methods, Class<?> clazz) {
+ // First the given class
+ Method[] list = clazz.getDeclaredMethods();
+ for (Method method : list) {
+ if (matchReturnType(method) && matchArgumentTypes(method) && matchInheritanceVisibility(method)
+ && matchNotOverridden(method, methods)) {
+ methods.add(method);
+ }
+ }
+
+ // If we have a parent class, traverse it
+ if (clazz.getSuperclass() != null) {
+ traverse(methods, clazz.getSuperclass());
+ }
+ }
+
+}
Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Reflection.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Reflection.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Reflection.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Reflection.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,35 @@
+/*
+ * 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.util;
+
+/**
+ * Class containing utility method helping reflection
+ */
+public class Reflection {
+
+ public static <T> Fields<T> fields() {
+ return new Fields<T>();
+ }
+
+ public static <T> Methods<T> methods() {
+ return new Methods<T>();
+ }
+
+}
Added: felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/configuration/InstanceDSLTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/configuration/InstanceDSLTest.java?rev=1471456&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/configuration/InstanceDSLTest.java (added)
+++ felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/configuration/InstanceDSLTest.java Wed Apr 24 15:06:07 2013
@@ -0,0 +1,54 @@
+/*
+ * 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.configuration;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.extender.internal.processor.ConfigurationProcessor;
+
+import static org.apache.felix.ipojo.configuration.Instance.*;
+
+/**
+ * Check the instance DSL.
+ */
+public class InstanceDSLTest extends TestCase {
+
+
+ public void testInstance() {
+ instance().of("my.factory")
+ .with("simple").setto("simple");
+
+ instance()
+ .of("my.factory")
+ .with("simple").setto("simple")
+
+ .with("list").setto(list(1, 2, 3))
+ .with("list2").setto(list().with(1).with(2).with(3))
+
+ .with("map").setto(map().with(pair("entry", "value")))
+ .with("map").setto(map()
+ .with(pair("entry2", list("aaa", "bbb"))));
+ }
+
+ public void testClassnameExtraction() {
+ String cn = ConfigurationProcessor.getClassNameFromResource("/org/apache/felix/ipojo/Pojo.class");
+ Assert.assertEquals(cn, "org.apache.felix.ipojo.Pojo");
+ }
+}