/* * 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.tuscany.sca.implementation.java.introspect.impl; import static org.apache.tuscany.sca.implementation.java.introspect.impl.ModelHelper.getProperty; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.lang.reflect.Constructor; import org.apache.tuscany.sca.assembly.AssemblyFactory; import org.apache.tuscany.sca.assembly.DefaultAssemblyFactory; import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.implementation.java.DefaultJavaImplementationFactory; import org.apache.tuscany.sca.implementation.java.IntrospectionException; import org.apache.tuscany.sca.implementation.java.JavaElementImpl; import org.apache.tuscany.sca.implementation.java.JavaImplementation; import org.apache.tuscany.sca.implementation.java.JavaImplementationFactory; import org.apache.tuscany.sca.interfacedef.java.DefaultJavaInterfaceFactory; import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; import org.junit.Test; import org.oasisopen.sca.annotation.Property; import org.oasisopen.sca.annotation.Reference; import org.oasisopen.sca.annotation.Remotable; /** * @version $Rev$ $Date$ */ public class HeuristicConstructorTestCase extends AbstractProcessorTest { private AssemblyFactory factory; private JavaInterfaceFactory javaFactory; private HeuristicPojoProcessor processor; private JavaImplementationFactory javaImplementationFactory; public HeuristicConstructorTestCase() { ExtensionPointRegistry registry = new DefaultExtensionPointRegistry(); factory = new DefaultAssemblyFactory(registry); javaFactory = new DefaultJavaInterfaceFactory(registry); javaImplementationFactory = new DefaultJavaImplementationFactory(); processor = new HeuristicPojoProcessor(factory, javaFactory); } private <T> void visitEnd(Class<T> clazz, JavaImplementation type) throws IntrospectionException { for (Constructor<?> constructor : clazz.getConstructors()) { visitConstructor(constructor, type); } processor.visitEnd(clazz, type); } /** * Verifies a single constructor is chosen with a parameter as the type */ @Test public void testSingleConstructorWithParam() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); org.apache.tuscany.sca.assembly.Property prop = factory.createProperty(); prop.setName("foo"); type.getProperties().add(prop); // Hack to add a property member JavaElementImpl element = new JavaElementImpl("foo", String.class, null); type.getPropertyMembers().put("foo", element); visitEnd(Foo1.class, type); assertNotNull(type.getConstructor().getConstructor()); assertEquals("foo", type.getConstructor().getParameters()[0].getName()); } /** * Verifies a single constructor is chosen with a reference as the type */ @Test public void testSingleConstructorWithRef() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); org.apache.tuscany.sca.assembly.Reference ref = factory.createReference(); ref.setName("foo"); type.getReferences().add(ref); type.getReferenceMembers().put("foo", new JavaElementImpl("foo", String.class, null)); visitEnd(Foo1.class, type); assertNotNull(type.getConstructor().getConstructor()); assertEquals("foo", type.getConstructor().getParameters()[0].getName()); } /** * Verifies a single constructor is chosen with a property and a reference * as the type */ @Test public void testSingleConstructorWithPropRef() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); org.apache.tuscany.sca.assembly.Property prop = factory.createProperty(); prop.setName("foo"); type.getProperties().add(prop); // Hack to add a property member JavaElementImpl element = new JavaElementImpl("foo", String.class, null); type.getPropertyMembers().put("foo", element); org.apache.tuscany.sca.assembly.Reference ref = ModelHelper.createReference(factory, javaFactory, "ref", Foo1.class); type.getReferences().add(ref); type.getReferenceMembers().put("ref", new JavaElementImpl("ref", Foo1.class, null)); visitEnd(Foo2.class, type); assertNotNull(type.getConstructor().getConstructor()); assertEquals(2, type.getConstructor().getParameters().length); } @Test public void testSingleConstructorResolvableParam() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); visitEnd(Foo5.class, type); assertEquals(String.class, type.getPropertyMembers().get("string").getType()); } @Test public void testSingleConstructorResolvableRef() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); visitEnd(Foo6.class, type); assertTrue(ModelHelper.matches(ModelHelper.getReference(type, "ref"), Ref.class)); } @Test public void testSingleConstructorAmbiguousRef() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); org.apache.tuscany.sca.assembly.Reference ref = ModelHelper.createReference(factory, javaFactory, "ref", Foo1.class); type.getReferences().add(ref); type.getReferenceMembers().put("ref", new JavaElementImpl("ref", Foo1.class, null)); org.apache.tuscany.sca.assembly.Reference ref2 = ModelHelper.createReference(factory, javaFactory, "ref2", Foo1.class); type.getReferences().add(ref2); type.getReferenceMembers().put("ref2", new JavaElementImpl("ref2", Foo1.class, null)); try { visitEnd(Foo4.class, type); fail(); } catch (AmbiguousConstructorException e) { // expected } } @Test public void testConstructorPropertyAnnotatedParamsOnly() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); visitEnd(Foo7.class, type); assertNotNull(getProperty(type, "myProp")); } @Test public void testConstructorReferenceAnnotatedParamsOnly() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); visitEnd(Foo8.class, type); assertNotNull(ModelHelper.getReference(type, "myRef")); } @Test public void testDefaultConstructor() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); visitEnd(Foo3.class, type); assertNotNull(type.getConstructor().getConstructor()); } @Test public void testSameTypesButAnnotated() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); visitEnd(Foo12.class, type); assertEquals(2, type.getProperties().size()); assertNotNull(getProperty(type, "prop1")); assertNotNull(getProperty(type, "prop2")); } /** * Verifies processing executes with additional extension annotations */ @Test public void testRandomAnnotation() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); visitEnd(Foo11.class, type); assertEquals(1, type.getProperties().size()); assertNotNull(getProperty(type, "prop1")); } @Test public void testPrivateConstructor() throws Exception { JavaImplementation type = javaImplementationFactory.createJavaImplementation(); try { visitEnd(Foo14.class, type); fail(); } catch (NoConstructorException e) { // expected } } @Test public void testMultipleConstructors() throws Exception { // throw new UnsupportedOperationException("Finish heuristic multiple // constructors - Foo10"); } public static class Foo1 { public Foo1(String val) { } } public static class Foo2 { public Foo2(String val, Foo1 ref) { } } public static class Foo3 { } public static class Foo4 { public Foo4(Foo1 ref) { } } public static class Prop { } @Remotable public static interface Ref { } public static class Foo5 { public Foo5(String val) { } } public static class Foo6 { public Foo6(Ref ref) { } } public static class Foo7 { public Foo7(@Property(name = "myProp") String prop) { } } public static class Foo8 { public Foo8(@Reference(name = "myRef") String ref) { } } public static class Foo9 { public Foo9(@Reference(name = "myRef") String ref) { } } public static class Foo10 { public Foo10() { } public Foo10(String prop) { } public Foo10(@Property(name = "prop1") String prop1, @Property(name = "prop2") String prop2) { } } public static class Foo11 { public Foo11(@Property(name = "prop1") String prop, @Baz String baz) { } } public static class Foo12 { public Foo12(@Property(name = "prop1") String prop, @Property(name = "prop2") String baz) { } } public @interface Baz { } public static class Foo13 { public Foo13(@Reference String foo) { } } public static final class Foo14 { private Foo14() { } } public static final class Foo15 { public Foo15(@Reference String param1, @Reference String param2) { } } public static final class Foo16 { public Foo16(@Reference String param1, @Property(name = "foo") String param2, @Reference(name = "bar") String param3) { } } }