summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation')
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/BaseJavaImplementation.java68
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/DefaultJavaImplementationFactory.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/IntrospectionException.java60
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaConstructorImpl.java56
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaElementImpl.java223
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementation.java164
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementationFactory.java75
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaParameterImpl.java36
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaResourceImpl.java95
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaScopeImpl.java62
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/ResourceHost.java47
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/ResourceResolutionException.java43
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/BaseJavaImplementationImpl.java102
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaClassIntrospectorImpl.java125
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationFactoryImpl.java135
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationImpl.java144
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/BaseJavaClassVisitor.java74
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/JavaClassVisitor.java126
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/JavaIntrospectionHelper.java648
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AbstractPropertyProcessor.java257
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AllowsPassByReferenceProcessor.java57
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AmbiguousConstructorException.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ComponentNameProcessor.java87
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ConstructorProcessor.java102
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ContextProcessor.java89
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DestroyProcessor.java63
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateConstructorException.java41
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateDestructorException.java35
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateInitException.java35
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicatePropertyException.java34
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateReferenceException.java35
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateResourceException.java36
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/EagerInitProcessor.java63
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/HeuristicPojoProcessor.java765
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalCallbackReferenceException.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalContextException.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalDestructorException.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalInitException.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalPropertyException.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalReferenceException.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalResourceException.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalServiceDefinitionException.java35
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InitProcessor.java67
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidConstructorException.java36
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidConversationalImplementationException.java39
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidPropertyException.java35
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidReferenceException.java42
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidResourceException.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidServiceTypeException.java48
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JAXWSProcessor.java337
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/NoConstructorException.java37
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/PolicyProcessor.java307
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/PropertyProcessor.java50
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java300
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/Resource.java49
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ResourceProcessor.java153
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ScopeProcessor.java68
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java264
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceTypeNotFoundException.java35
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/UnknownContextTypeException.java33
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/package.html29
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationConstants.java35
-rw-r--r--sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationProcessor.java398
63 files changed, 6779 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/BaseJavaImplementation.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/BaseJavaImplementation.java
new file mode 100644
index 0000000000..a3b0343d51
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/BaseJavaImplementation.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.Extensible;
+import org.apache.tuscany.sca.assembly.Implementation;
+
+/**
+ * Represents a Java implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface BaseJavaImplementation extends Implementation, Extensible {
+
+ /**
+ * Returns the name of the Java implementation class.
+ *
+ * @return the name of the Java implementation class
+ */
+ String getName();
+
+ /**
+ * Sets the name of the Java implementation class.
+ *
+ * @param className the name of the Java implementation class
+ */
+ void setName(String className);
+
+ /**
+ * Returns the Java implementation class.
+ *
+ * @return the Java implementation class
+ */
+ Class<?> getJavaClass();
+
+ /**
+ * Sets the Java implementation class.
+ *
+ * @param javaClass the Java implementation class
+ */
+ void setJavaClass(Class<?> javaClass);
+
+ /**
+ * Customize the implementation type so that components are implemented using Java based framework such as
+ * implementation.spring or implementation.jaxrs can leverage the introspection
+ * @param type
+ */
+ void setType(QName type);
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/DefaultJavaImplementationFactory.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/DefaultJavaImplementationFactory.java
new file mode 100644
index 0000000000..f98a617925
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/DefaultJavaImplementationFactory.java
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+/**
+ * A factory for the Java model.
+ *
+ * @version $Rev$ $Date$
+ */
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.implementation.java.impl.JavaImplementationFactoryImpl;
+
+public class DefaultJavaImplementationFactory extends JavaImplementationFactoryImpl implements JavaImplementationFactory {
+
+ public DefaultJavaImplementationFactory(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ // For UNIT test only
+ public DefaultJavaImplementationFactory() {
+ super(new DefaultExtensionPointRegistry());
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/IntrospectionException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/IntrospectionException.java
new file mode 100644
index 0000000000..2198a632c0
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/IntrospectionException.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import java.lang.reflect.Member;
+
+/**
+ * Denotes a problem processing annotations on a POJO implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class IntrospectionException extends Exception {
+ private static final long serialVersionUID = -361025119035104470L;
+ private Member member;
+
+ public IntrospectionException() {
+ }
+
+ public IntrospectionException(String message) {
+ super(message);
+ }
+
+ public IntrospectionException(String message, Member member) {
+ super(message);
+ this.member = member;
+ }
+
+ public IntrospectionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public IntrospectionException(Throwable cause) {
+ super(cause);
+ }
+
+ public Member getMember() {
+ return member;
+ }
+
+ public void setMember(Member member) {
+ this.member = member;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaConstructorImpl.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaConstructorImpl.java
new file mode 100644
index 0000000000..df76d3ea4e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaConstructorImpl.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+import java.lang.reflect.Constructor;
+
+
+/**
+ * Hold injection information for the constructor used to instantiate a
+ * component implementation instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaConstructorImpl<T> {
+ private Constructor<T> constructor;
+ private JavaParameterImpl[] parameters;
+
+ public JavaConstructorImpl(Constructor<T> constructor) {
+ this.constructor = constructor;
+ int size = constructor.getParameterTypes().length;
+ parameters = new JavaParameterImpl[size];
+ for (int i = 0; i < size; i++) {
+ parameters[i] = new JavaParameterImpl(constructor, i);
+ }
+ }
+
+ /**
+ * @return the constructor
+ */
+ public Constructor<T> getConstructor() {
+ return constructor;
+ }
+
+ /**
+ * @return the parameters
+ */
+ public JavaParameterImpl[] getParameters() {
+ return parameters;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaElementImpl.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaElementImpl.java
new file mode 100644
index 0000000000..44dec0376a
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaElementImpl.java
@@ -0,0 +1,223 @@
+/*
+ * 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;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+/**
+ * This class represents a java element such as a Package, Class, Constructor,
+ * Field, Method or Parameter.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaElementImpl {
+ private AnnotatedElement anchor;
+ private ElementType elementType;
+ private WeakReference<Class<?>> type;
+ private WeakReference<Type> genericType;
+ private int index = -1;
+ private String name;
+ private Class<? extends Annotation> classifer;
+
+ public JavaElementImpl(Class<?> cls) {
+ this.anchor = cls;
+ this.elementType = ElementType.TYPE;
+ this.type = new WeakReference<Class<?>>(cls);
+ this.genericType = new WeakReference<Type>(cls);
+ this.name = cls.getName();
+ }
+
+ public JavaElementImpl(Field field) {
+ this.anchor = field;
+ this.elementType = ElementType.FIELD;
+ this.type = new WeakReference<Class<?>>(field.getType());
+ this.genericType = new WeakReference<Type>(field.getGenericType());
+ this.name = field.getName();
+ }
+
+ public JavaElementImpl(Constructor<?> constructor, int index) {
+ this.anchor = constructor;
+ this.elementType = ElementType.PARAMETER;
+ this.type = new WeakReference<Class<?>>(constructor.getParameterTypes()[index]);
+ this.genericType = new WeakReference<Type>(constructor.getGenericParameterTypes()[index]);
+ this.index = index;
+ this.name = "";
+ }
+
+ public JavaElementImpl(Method method, int index) {
+ this.anchor = method;
+ this.elementType = ElementType.PARAMETER;
+ this.type = new WeakReference<Class<?>>(method.getParameterTypes()[index]);
+ this.genericType = new WeakReference<Type>(method.getGenericParameterTypes()[index]);
+ this.index = index;
+ this.name = "";
+ }
+
+ /**
+ * For testing purpose
+ *
+ * @param name
+ * @param type
+ * @param classifer TODO
+ * @param elementType
+ */
+ public JavaElementImpl(String name, Class<?> type, Class<? extends Annotation> classifer) {
+ super();
+ this.type = new WeakReference<Class<?>>(type);
+ this.name = name;
+ this.classifer = classifer;
+ }
+
+ /**
+ * @return the anchor
+ */
+ public AnnotatedElement getAnchor() {
+ return anchor;
+ }
+
+ /**
+ * @return the elementType
+ */
+ public ElementType getElementType() {
+ return elementType;
+ }
+
+ /**
+ * @return the genericType
+ */
+ public Type getGenericType() {
+ return genericType.get();
+ }
+
+ /**
+ * @return the index
+ */
+ public int getIndex() {
+ return index;
+ }
+
+ /**
+ * @return the type
+ */
+ public Class<?> getType() {
+ return type.get();
+ }
+
+ /**
+ * @return the annotations
+ */
+ public Annotation[] getAnnotations() {
+ if (elementType == ElementType.PARAMETER) {
+ if (anchor instanceof Method) {
+ // We only care about the method-level annotations
+ return ((Method)anchor).getAnnotations();
+ }
+ if (anchor instanceof Constructor) {
+ return ((Constructor<?>)anchor).getParameterAnnotations()[index];
+ }
+ }
+ return anchor.getAnnotations();
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ for (Annotation a : getAnnotations()) {
+ if (a.annotationType() == annotationType) {
+ return annotationType.cast(a);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the classifier
+ */
+ public Class<? extends Annotation> getClassifer() {
+ return classifer;
+ }
+
+ /**
+ * @param classifer the classifier to set
+ */
+ public void setClassifer(Class<? extends Annotation> classifer) {
+ this.classifer = classifer;
+ }
+
+
+ @Override
+ public String toString() {
+ return anchor.toString() + (elementType == ElementType.PARAMETER ? "[" + index + "]" : "");
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((anchor == null) ? 0 : anchor.hashCode());
+ result = PRIME * result + index;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final JavaElementImpl other = (JavaElementImpl)obj;
+ if (anchor == null) {
+ if (other.anchor != null) {
+ return false;
+ }
+ } else if (!anchor.equals(other.anchor)) {
+ return false;
+ }
+ if (index != other.index) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementation.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementation.java
new file mode 100644
index 0000000000..60649eb5d6
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementation.java
@@ -0,0 +1,164 @@
+/*
+ * 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;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Represents a Java implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface JavaImplementation extends BaseJavaImplementation {
+ QName TYPE = new QName(SCA11_NS, "implementation.java");
+ /**
+ * Returns the constructor used to instantiate implementation instances.
+ *
+ * @return the constructor used to instantiate implementation instances
+ */
+ JavaConstructorImpl<?> getConstructor();
+
+ /**
+ * Sets the constructor used to instantiate implementation instances
+ *
+ * @param definition the constructor used to instantiate implementation instances
+ */
+ void setConstructor(JavaConstructorImpl<?> definition);
+
+ /**
+ * Returns the component initializer method.
+ *
+ * @return the component initializer method
+ */
+ Method getInitMethod();
+
+ /**
+ * Sets the component initializer method.
+ *
+ * @param initMethod the component initializer method
+ */
+ void setInitMethod(Method initMethod);
+
+ /**
+ * Returns the component destructor method.
+ *
+ * @return the component destructor method
+ */
+ Method getDestroyMethod();
+
+ /**
+ * Sets the component destructor method.
+ *
+ * @param destroyMethod the component destructor method
+ */
+ void setDestroyMethod(Method destroyMethod);
+
+ /**
+ * Returns the resources injected into this implementation.
+ *
+ * @return
+ */
+ Map<String, JavaResourceImpl> getResources();
+
+ /**
+ * Returns the Java member used to inject a conversation ID.
+ *
+ * @return
+ */
+ List<Member> getConversationIDMembers();
+
+ /**
+ * Sets the Java member used to inject a conversation ID.
+ *
+ * @param conversationIDMember
+ */
+ void addConversationIDMember(Member conversationIDMember);
+
+ /**
+ * Returns true if AllowsPassReference is set.
+ *
+ * @return true if AllowsPassByReference is set
+ */
+ boolean isAllowsPassByReference();
+
+ /**
+ * @param allowsPassByReference the allowsPassByReference to set
+ */
+ void setAllowsPassByReference(boolean allowsPassByReference);
+
+ /**
+ * @return the allowsPassByReferenceMethods
+ */
+ List<Method> getAllowsPassByReferenceMethods();
+
+ /**
+ * @param method
+ * @return
+ */
+ boolean isAllowsPassByReference(Method method);
+
+ /**
+ * @return the constructors
+ */
+ Map<Constructor, JavaConstructorImpl> getConstructors();
+
+ /**
+ * @return the eagerInit
+ */
+ boolean isEagerInit();
+
+ /**
+ * @param eagerInit the eagerInit to set
+ */
+ void setEagerInit(boolean eagerInit);
+
+ /**
+ * @return the callbacks
+ */
+ Map<String, Collection<JavaElementImpl>> getCallbackMembers();
+
+ /**
+ * @return the properties
+ */
+ Map<String, JavaElementImpl> getPropertyMembers();
+
+ /**
+ * @return the references
+ */
+ Map<String, JavaElementImpl> getReferenceMembers();
+
+ /**
+ * @return the scope
+ */
+ JavaScopeImpl getJavaScope();
+
+ /**
+ * @param scope the scope to set
+ */
+ void setJavaScope(JavaScopeImpl scope);
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementationFactory.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementationFactory.java
new file mode 100644
index 0000000000..8228c80372
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementationFactory.java
@@ -0,0 +1,75 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor;
+
+
+/**
+ * Factory for the Java model
+ *
+ * @version $Rev$ $Date$
+ */
+public interface JavaImplementationFactory {
+
+ /**
+ * Creates a new Java implementation model.
+ *
+ * @return
+ */
+ JavaImplementation createJavaImplementation();
+
+ /**
+ * Creates a new Java implementation model from an implementation class.
+ *
+ * @param implementationClass The implementation class to introspect.
+ * @return
+ */
+ JavaImplementation createJavaImplementation(Class<?> implementationClass) throws IntrospectionException;
+
+ /**
+ * Creates the contents of a Java implementation model from an implementation class.
+ *
+ * @param implementationClass The implementation class to introspect.
+ * @return
+ */
+ void createJavaImplementation(JavaImplementation javaImplementation, Class<?> implementationClass) throws IntrospectionException;
+
+ /**
+ * Registers the given visitor.
+ *
+ * @param visitor
+ */
+ void addClassVisitor(JavaClassVisitor visitor);
+
+ /**
+ * Deregisters the given visitor.
+ */
+ void removeClassVisitor(JavaClassVisitor visitor);
+
+ /**
+ * Returns the list of visitors.
+ *
+ * @return
+ */
+ List<JavaClassVisitor> getClassVisitors();
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaParameterImpl.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaParameterImpl.java
new file mode 100644
index 0000000000..80911a9552
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaParameterImpl.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import java.lang.reflect.Constructor;
+
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaParameterImpl extends JavaElementImpl {
+ /**
+ * @param constructor
+ * @param index
+ */
+ public JavaParameterImpl(Constructor<?> constructor, int index) {
+ super(constructor, index);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaResourceImpl.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaResourceImpl.java
new file mode 100644
index 0000000000..90aef45e94
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaResourceImpl.java
@@ -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.tuscany.sca.implementation.java;
+
+/**
+ * A resource dependency declared by a Java component implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaResourceImpl {
+ private JavaElementImpl element;
+ private String mappedName;
+ private boolean optional;
+ private ResourceHost resourceHost;
+
+ public JavaResourceImpl(JavaElementImpl element) {
+ this.element = element;
+ }
+
+ public JavaResourceImpl(JavaElementImpl element, ResourceHost resourceHost) {
+ this.element = element;
+ this.resourceHost = resourceHost;
+ }
+
+ /**
+ * The name of the resource
+ *
+ * @return the name of the resource
+ */
+ public String getName() {
+ return element.getName();
+ }
+
+ /**
+ * Returns the URI of the resource
+ *
+ * @return the URI of the resource
+ */
+ public String getMappedName() {
+ return mappedName;
+ }
+
+ /**
+ * Sets the resource URI
+ */
+ public void setMappedName(String mappedName) {
+ this.mappedName = mappedName;
+ }
+
+ /**
+ * If true, the resource is optional
+ *
+ * @return true if the resource is optional
+ */
+ public boolean isOptional() {
+ return optional;
+ }
+
+ /**
+ * Sets whether the resource is optional
+ */
+ public void setOptional(boolean optional) {
+ this.optional = optional;
+ }
+
+ /**
+ * @return the element
+ */
+ public JavaElementImpl getElement() {
+ return element;
+ }
+
+ /**
+ * @return the resourceHost
+ */
+ public ResourceHost getResourceHost() {
+ return resourceHost;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaScopeImpl.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaScopeImpl.java
new file mode 100644
index 0000000000..c977736630
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaScopeImpl.java
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+/**
+ * The default implementation scopes supported by assemblies.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaScopeImpl {
+ public static final JavaScopeImpl STATELESS = new JavaScopeImpl("STATELESS");
+ public static final JavaScopeImpl COMPOSITE = new JavaScopeImpl("COMPOSITE");
+ public static final JavaScopeImpl INVALID = new JavaScopeImpl("INVALID");
+
+ private String scope;
+
+ public JavaScopeImpl(String scope) {
+ this.scope = scope.toUpperCase().intern();
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ final JavaScopeImpl scope1 = (JavaScopeImpl) o;
+ return !(scope != null ? scope != scope1.scope.intern() : scope1.scope != null);
+ }
+
+ @Override
+ public int hashCode() {
+ return scope != null ? scope.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ return scope;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/ResourceHost.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/ResourceHost.java
new file mode 100644
index 0000000000..4882391087
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/ResourceHost.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+
+/**
+ * Interface implemented by host environments that allow for resolution of component implementation resources, e.g.
+ * items bound in a JNDI tree.
+ *
+ * @version $Rev: 537424 $ $Date: 2007-05-12 14:47:18 +0100 (Sat, 12 May 2007) $
+ */
+public interface ResourceHost {
+
+ /**
+ * Resolve a resource matching the given type
+ *
+ * @param type the type of the resources
+ * @throws ResourceResolutionException if an error is encountered during resolution
+ */
+ <T> T resolveResource(Class<T> type) throws ResourceResolutionException;
+
+ /**
+ * Resolve a resource matching the given type and name
+ *
+ * @param type the type of the resources
+ * @param mappedName the mapped name of the resource
+ * @throws ResourceResolutionException if an error is encountered during resolution
+ */
+ <T> T resolveResource(Class<T> type, String mappedName) throws ResourceResolutionException;
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/ResourceResolutionException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/ResourceResolutionException.java
new file mode 100644
index 0000000000..36b9ab8c99
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/ResourceResolutionException.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.tuscany.sca.implementation.java;
+
+
+/**
+ * @version $Rev: 537424 $ $Date: 2007-05-12 14:47:18 +0100 (Sat, 12 May 2007) $
+ */
+public class ResourceResolutionException extends Exception {
+ private static final long serialVersionUID = 13421352711315479L;
+
+ public ResourceResolutionException() {
+ super();
+ }
+
+ public ResourceResolutionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ResourceResolutionException(String message) {
+ super(message);
+ }
+
+ public ResourceResolutionException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/BaseJavaImplementationImpl.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/BaseJavaImplementationImpl.java
new file mode 100644
index 0000000000..a5dd89f75a
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/BaseJavaImplementationImpl.java
@@ -0,0 +1,102 @@
+/*
+ * 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.impl;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.impl.ImplementationImpl;
+import org.apache.tuscany.sca.implementation.java.BaseJavaImplementation;
+
+/**
+ * Represents a Java implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+abstract class BaseJavaImplementationImpl extends ImplementationImpl implements BaseJavaImplementation {
+
+ private String className;
+ private Class<?> javaClass;
+
+ protected BaseJavaImplementationImpl(QName type) {
+ super(type);
+ }
+
+ public String getName() {
+ if (isUnresolved()) {
+ return className;
+ } else if (javaClass != null) {
+ return javaClass.getName();
+ } else {
+ return null;
+ }
+ }
+
+ public void setName(String className) {
+ if (!isUnresolved()) {
+ throw new IllegalStateException();
+ }
+ this.className = className;
+ }
+
+ public Class<?> getJavaClass() {
+ return javaClass;
+ }
+
+ public void setJavaClass(Class<?> javaClass) {
+ this.javaClass = javaClass;
+ if (this.className == null) {
+ this.className = javaClass.getName();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getType() + " (class=" + getName() + ")";
+ }
+
+/* TUSCANY-3876 - disable implementation model sharing so that
+ * we can get implementation policy modelled on an
+ * impementation by implementation basis rather than
+ * storing it on the component
+ @Override
+ public int hashCode() {
+ return String.valueOf(getName()).hashCode();
+ }
+*/
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ } else if (obj instanceof BaseJavaImplementation) {
+ if (getName() != null) {
+ return getName().equals(((BaseJavaImplementation)obj).getName());
+ } else {
+ return ((BaseJavaImplementation)obj).getName() == null;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public void setType(QName type) {
+ this.type = type;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaClassIntrospectorImpl.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaClassIntrospectorImpl.java
new file mode 100644
index 0000000000..491408098e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaClassIntrospectorImpl.java
@@ -0,0 +1,125 @@
+/*
+ * 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.impl;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaParameterImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+
+/**
+ * An extensible Java class introspector implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaClassIntrospectorImpl {
+
+ private List<JavaClassVisitor> visitors;
+
+ public JavaClassIntrospectorImpl(List<JavaClassVisitor> visitors) {
+ this.visitors = visitors;
+ }
+
+ /**
+ * JSR-250 PFD recommends the following guidelines for how annotations
+ * interact with inheritance in order to keep the resulting complexity in
+ * control:
+ * <ol>
+ * <li>Class-level annotations only affect the class they annotate and
+ * their members, that is, its methods and fields. They never affect a
+ * member declared by a superclass, even if it is not hidden or overridden
+ * by the class in question.
+ * <li>In addition to affecting the annotated class, class-level
+ * annotations may act as a shorthand for member-level annotations. If a
+ * member carries a specific member-level annotation, any annotations of the
+ * same type implied by a class-level annotation are ignored. In other
+ * words, explicit member-level annotations have priority over member-level
+ * annotations implied by a class-level annotation.
+ * <li>The interfaces implemented by a class never contribute annotations
+ * to the class itself or any of its members.
+ * <li>Members inherited from a superclass and which are not hidden or
+ * overridden maintain the annotations they had in the class that declared
+ * them, including member-level annotations implied by class-level ones.
+ * <li>Member-level annotations on a hidden or overridden member are always
+ * ignored.
+ * </ol>
+ */
+ public void introspectClass(JavaImplementation type, Class<?> clazz)
+ throws IntrospectionException {
+ for (JavaClassVisitor visitor : visitors) {
+ visitor.visitClass(clazz, type);
+ for (Constructor<?> constructor : clazz.getConstructors()) {
+ visitor.visitConstructor(constructor, type);
+ // Assuming the visitClass or visitConstructor will populate the
+ // type.getConstructors
+ JavaConstructorImpl<?> definition = type.getConstructors().get(constructor);
+ if (definition != null) {
+ for (JavaParameterImpl p : definition.getParameters()) {
+ visitor.visitConstructorParameter(p, type);
+ }
+ }
+ }
+
+ Set<Field> fields = JavaIntrospectionHelper.getInjectableFields(clazz, true);
+ for (Field field : fields) {
+ visitor.visitField(field, type);
+ }
+
+ Set<Method> methods = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(clazz, true);
+ for (Method method : methods) {
+ visitor.visitMethod(method, type);
+ }
+
+ // Check if any private methods have illegal annotations that should be raised as errors
+ Set<Method> privateMethods = JavaIntrospectionHelper.getPrivateMethods(clazz);
+ for (Method method : privateMethods) {
+ visitor.visitMethod(method, type);
+ }
+
+ Class<?> superClass = clazz.getSuperclass();
+ if (superClass != null) {
+ visitSuperClass(superClass, type, visitor);
+ }
+
+ visitor.visitEnd(clazz, type);
+
+ }
+
+ }
+
+ private void visitSuperClass(Class<?> clazz, JavaImplementation type, JavaClassVisitor visitor)
+ throws IntrospectionException {
+ if (!Object.class.equals(clazz)) {
+ visitor.visitSuperClass(clazz, type);
+ clazz = clazz.getSuperclass();
+ if (clazz != null) {
+ visitSuperClass(clazz, type, visitor);
+ }
+ }
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationFactoryImpl.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationFactoryImpl.java
new file mode 100644
index 0000000000..a579a6719c
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationFactoryImpl.java
@@ -0,0 +1,135 @@
+/*
+ * 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.impl;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.extensibility.ServiceDeclaration;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaImplementationFactory;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor;
+
+
+/**
+ * A factory for the Java model.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class JavaImplementationFactoryImpl implements JavaImplementationFactory {
+
+ private List<JavaClassVisitor> visitors = new ArrayList<JavaClassVisitor>();
+ private JavaClassIntrospectorImpl introspector;
+ private boolean loaded;
+ protected ExtensionPointRegistry registry;
+
+ public JavaImplementationFactoryImpl(ExtensionPointRegistry registry) {
+ this.registry = registry;
+ }
+
+ public JavaImplementation createJavaImplementation() {
+ JavaImplementation javaImplementation = new JavaImplementationImpl();
+ return javaImplementation;
+ }
+
+ public JavaImplementation createJavaImplementation(Class<?> implementationClass) throws IntrospectionException {
+ JavaImplementation javaImplementation = createJavaImplementation();
+ getIntrospector().introspectClass(javaImplementation, implementationClass);
+ return javaImplementation;
+ }
+
+ public void createJavaImplementation(JavaImplementation javaImplementation, Class<?> implementationClass) throws IntrospectionException {
+ getIntrospector().introspectClass(javaImplementation, implementationClass);
+ }
+
+ public void addClassVisitor(JavaClassVisitor visitor) {
+ for (JavaClassVisitor tmpVisitor : visitors){
+ if (tmpVisitor.getClass() == visitor.getClass()){
+ // trying to add a duplicate visitor so
+ // ignore it
+ return;
+ }
+ }
+ visitors.add(visitor);
+ }
+
+ public void removeClassVisitor(JavaClassVisitor visitor) {
+ visitors.remove(visitor);
+ }
+
+ public List<JavaClassVisitor> getClassVisitors() {
+ loadVisitors();
+ return visitors;
+ }
+
+ /**
+ * Load visitors declared under META-INF/services
+ */
+ @SuppressWarnings("unchecked")
+ private synchronized void loadVisitors() {
+ if (loaded)
+ return;
+
+ // Get the databinding service declarations
+ Collection<ServiceDeclaration> visitorDeclarations;
+ try {
+ visitorDeclarations = registry.getServiceDiscovery().getServiceDeclarations(JavaClassVisitor.class, true);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+
+ // Load data bindings
+ for (ServiceDeclaration visitorDeclaration: visitorDeclarations) {
+ JavaClassVisitor visitor = null;
+ try {
+ Class<JavaClassVisitor> visitorClass = (Class<JavaClassVisitor>)visitorDeclaration.loadClass();
+
+ try {
+ Constructor<JavaClassVisitor> constructor = visitorClass.getConstructor(ExtensionPointRegistry.class);
+ visitor = constructor.newInstance(registry);
+ } catch (NoSuchMethodException e) {
+ visitor = visitorClass.newInstance();
+ }
+
+
+ } catch (Exception e) {
+ IllegalStateException ie = new IllegalStateException(e);
+ throw ie;
+ }
+
+ addClassVisitor(visitor);
+ }
+
+ loaded = true;
+ }
+
+ private synchronized JavaClassIntrospectorImpl getIntrospector() {
+ if (introspector != null) {
+ return introspector;
+ }
+ introspector = new JavaClassIntrospectorImpl(getClassVisitors());
+ return introspector;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationImpl.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationImpl.java
new file mode 100644
index 0000000000..5f7885ed5d
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationImpl.java
@@ -0,0 +1,144 @@
+/*
+ * 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.impl;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl;
+import org.apache.tuscany.sca.implementation.java.JavaElementImpl;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaResourceImpl;
+import org.apache.tuscany.sca.implementation.java.JavaScopeImpl;
+
+/**
+ * A component type specialization for POJO implementations
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaImplementationImpl extends BaseJavaImplementationImpl implements JavaImplementation {
+ private JavaConstructorImpl<?> constructorDefinition;
+ private Map<Constructor, JavaConstructorImpl> constructors = new HashMap<Constructor, JavaConstructorImpl>();
+ private Method initMethod;
+ private Method destroyMethod;
+ private final Map<String, JavaResourceImpl> resources = new HashMap<String, JavaResourceImpl>();
+ private final Map<String, JavaElementImpl> propertyMembers = new HashMap<String, JavaElementImpl>();
+ private final Map<String, JavaElementImpl> referenceMembers = new HashMap<String, JavaElementImpl>();
+ private final Map<String, Collection<JavaElementImpl>> callbackMembers = new HashMap<String, Collection<JavaElementImpl>>();
+ private List<Member> conversationIDMember = new ArrayList<Member>();
+ private boolean eagerInit;
+ private boolean allowsPassByReference;
+ private List<Method> allowsPassByReferenceMethods = new ArrayList<Method>();
+ private JavaScopeImpl scope = JavaScopeImpl.STATELESS;
+
+ protected JavaImplementationImpl() {
+ super(TYPE);
+ }
+
+ public JavaConstructorImpl<?> getConstructor() {
+ return constructorDefinition;
+ }
+
+ public void setConstructor(JavaConstructorImpl<?> definition) {
+ this.constructorDefinition = definition;
+ }
+
+ public Method getInitMethod() {
+ return initMethod;
+ }
+
+ public void setInitMethod(Method initMethod) {
+ this.initMethod = initMethod;
+ }
+
+ public Method getDestroyMethod() {
+ return destroyMethod;
+ }
+
+ public void setDestroyMethod(Method destroyMethod) {
+ this.destroyMethod = destroyMethod;
+ }
+
+ public Map<String, JavaResourceImpl> getResources() {
+ return resources;
+ }
+
+ public List<Member> getConversationIDMembers() {
+ return this.conversationIDMember;
+ }
+
+ public void addConversationIDMember(Member conversationIDMember) {
+ this.conversationIDMember.add(conversationIDMember);
+ }
+
+ public boolean isAllowsPassByReference() {
+ return allowsPassByReference;
+ }
+
+ public void setAllowsPassByReference(boolean allowsPassByReference) {
+ this.allowsPassByReference = allowsPassByReference;
+ }
+
+ public List<Method> getAllowsPassByReferenceMethods() {
+ return allowsPassByReferenceMethods;
+ }
+
+ public boolean isAllowsPassByReference(Method method) {
+ return allowsPassByReference || allowsPassByReferenceMethods.contains(method);
+ }
+
+ public Map<Constructor, JavaConstructorImpl> getConstructors() {
+ return constructors;
+ }
+
+ public boolean isEagerInit() {
+ return eagerInit;
+ }
+
+ public void setEagerInit(boolean eagerInit) {
+ this.eagerInit = eagerInit;
+ }
+
+ public Map<String, Collection<JavaElementImpl>> getCallbackMembers() {
+ return callbackMembers;
+ }
+
+ public Map<String, JavaElementImpl> getPropertyMembers() {
+ return propertyMembers;
+ }
+
+ public Map<String, JavaElementImpl> getReferenceMembers() {
+ return referenceMembers;
+ }
+
+ public JavaScopeImpl getJavaScope() {
+ return scope;
+ }
+
+ public void setJavaScope(JavaScopeImpl scope) {
+ this.scope = scope;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/BaseJavaClassVisitor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/BaseJavaClassVisitor.java
new file mode 100644
index 0000000000..26ca54df88
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/BaseJavaClassVisitor.java
@@ -0,0 +1,74 @@
+/*
+ * 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;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaParameterImpl;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+
+/**
+ * A convenience class for annotation processors which alleviates the need to
+ * implement unused callbacks
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class BaseJavaClassVisitor implements JavaClassVisitor {
+ protected AssemblyFactory assemblyFactory;
+ protected JavaInterfaceFactory javaInterfaceFactory;
+
+ protected BaseJavaClassVisitor(AssemblyFactory factory) {
+ this.assemblyFactory = factory;
+ }
+
+ protected BaseJavaClassVisitor(ExtensionPointRegistry registry) {
+ super();
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.assemblyFactory = factories.getFactory(AssemblyFactory.class);
+ this.javaInterfaceFactory = factories.getFactory(JavaInterfaceFactory.class);
+ }
+
+ public <T> void visitClass(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+ }
+
+ public <T> void visitSuperClass(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+ }
+
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+ }
+
+ public <T> void visitConstructor(Constructor<T> constructor, JavaImplementation type) throws IntrospectionException {
+ }
+
+ public void visitField(Field field, JavaImplementation type) throws IntrospectionException {
+ }
+
+ public <T> void visitEnd(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+ }
+
+ public void visitConstructorParameter(JavaParameterImpl parameter, JavaImplementation type) throws IntrospectionException {
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/JavaClassVisitor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/JavaClassVisitor.java
new file mode 100644
index 0000000000..4b0f5bea55
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/JavaClassVisitor.java
@@ -0,0 +1,126 @@
+/*
+ * 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;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaParameterImpl;
+
+/**
+ * Implementations process class-level metadata, typically parsing annotations
+ * and updating the corresponding <code>ComponentType</code>. A processor
+ * may, for example, create a Property which is responsible for injecting a
+ * complex type on a component implementation instance when it is instantiated.
+ * <p/> Processors will receive callbacks as the implementation class is walked
+ * while evaluating an assembly. It is the responsibility of the parser to
+ * determine whether to perform an action during the callback.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface JavaClassVisitor {
+
+ /**
+ * A callback received when the component implementation class is first
+ * loaded
+ *
+ * @param clazz the component implementation class
+ * @param type the incomplete component type associated with the
+ * implementation class
+ * @throws IntrospectionException if an error is encountered while processing
+ * metadata
+ */
+ <T> void visitClass(Class<T> clazz, JavaImplementation type) throws IntrospectionException;
+
+ /**
+ * A callback received as the component implementation class hierarchy is
+ * evaluated
+ *
+ * @param clazz the superclass in the component implmentation's class
+ * hierarchy
+ * @param type the incomplete component type associated with the
+ * implementation class
+ * @throws IntrospectionException if an error is encountered while processing
+ * metadata
+ */
+ <T> void visitSuperClass(Class<T> clazz, JavaImplementation type) throws IntrospectionException;
+
+ /**
+ * A callback received as the component implementation's public and
+ * protected methods are evaluated
+ *
+ * @param method the current public or protected method being evaluated
+ * @param type the incomplete component type associated with the
+ * implementation class
+ * @throws IntrospectionException if an error is encountered while processing
+ * metadata
+ */
+ void visitMethod(Method method, JavaImplementation type) throws IntrospectionException;
+
+ /**
+ * A callback received as the component implementation's constructor used
+ * for instantiation by the runtime is evaluated. If an implementation
+ * contains more than one constructor, the constructor passed to the
+ * callback will be chosen according to the algorithm described in the SCA
+ * Java Client and Implementation Model Specification.
+ *
+ * @param constructor the constructor used for instantiating component
+ * implementation instances
+ * @param type the incomplete component type associated with the
+ * implementation class
+ * @throws IntrospectionException if an error is encountered while processing
+ * metadata
+ */
+ <T> void visitConstructor(Constructor<T> constructor, JavaImplementation type) throws IntrospectionException;
+
+ /**
+ * @param parameter
+ * @param type
+ * @throws IntrospectionException
+ */
+ void visitConstructorParameter(JavaParameterImpl parameter, JavaImplementation type) throws IntrospectionException;
+
+ /**
+ * A callback received as the component implementation's public and
+ * protected fields are evaluated
+ *
+ * @param field the current public or protected field being evaluated
+ * @param type the incomplete component type associated with the
+ * implementation class
+ * @throws IntrospectionException if an error is encountered while processing
+ * metadata
+ */
+ void visitField(Field field, JavaImplementation type) throws IntrospectionException;
+
+ /**
+ * The final callback received when all other callbacks during evaluation of
+ * the component implementation have been issued
+ *
+ * @param clazz the component implementation class
+ * @param type the incomplete component type associated with the
+ * implementation class
+ * @throws IntrospectionException if an error is encountered while processing
+ * metadata
+ */
+ <T> void visitEnd(Class<T> clazz, JavaImplementation type) throws IntrospectionException;
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/JavaIntrospectionHelper.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/JavaIntrospectionHelper.java
new file mode 100644
index 0000000000..a04ad3721a
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/JavaIntrospectionHelper.java
@@ -0,0 +1,648 @@
+/*
+ * 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;
+
+import java.beans.Introspector;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.oasisopen.sca.ServiceReference;
+
+/**
+ * Implements various reflection-related operations
+ *
+ * @version $Rev$ $Date$
+ */
+public final class JavaIntrospectionHelper {
+ private static final Logger logger = Logger.getLogger(JavaIntrospectionHelper.class.getName());
+ private static final Class<?>[] EMPTY_CLASS_ARRY = new Class[0];
+
+ /**
+ * Hide the constructor
+ */
+ private JavaIntrospectionHelper() {
+ }
+
+ /**
+ * Returns a collection of public, and protected fields declared by a class
+ * or one of its supertypes
+ */
+ public static Set<Field> getAllPublicAndProtectedFields(Class<?> clazz, boolean validating) {
+ return getAllPublicAndProtectedFields(clazz, new HashSet<Field>(), validating);
+ }
+
+ private static void checkInvalidAnnotations(AnnotatedElement element) {
+ for (Annotation a : element.getAnnotations()) {
+ if (a.annotationType().getName().startsWith("org.oasisopen.sca.annotation.")) {
+ logger.warning("Invalid annotation " + a + " is found on " + element);
+ }
+ }
+ }
+
+ /**
+ * Recursively evaluates the type hierarchy to return all fields that are
+ * public or protected
+ */
+ private static Set<Field> getAllPublicAndProtectedFields(Class<?> clazz, Set<Field> fields, boolean validating) {
+ if (clazz == null || clazz.isArray() || Object.class.equals(clazz)) {
+ return fields;
+ }
+ fields = getAllPublicAndProtectedFields(clazz.getSuperclass(), fields, validating);
+
+ Field[] declaredFields = null;
+
+ try {
+ declaredFields = clazz.getDeclaredFields();
+ } catch(Throwable t) {
+ //TUSCANY-3667 - clazz.getDeclaredFields might fail in GAE environment (log and ignore)
+ logger.log(Level.WARNING, "Error retrieving declared fields from class : " + t.getMessage());
+ }
+
+ if( declaredFields != null ) {
+ for (final Field field : declaredFields) {
+ int modifiers = field.getModifiers();
+ // The field should be non-final and non-static
+ if ((Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) && !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
+ // Allow privileged access to set accessibility. Requires ReflectPermission
+ // in security policy.
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ field.setAccessible(true); // ignore Java accessibility
+ return null;
+ }
+ });
+ fields.add(field);
+ } /*else {
+ if (validating) {
+ checkInvalidAnnotations(field);
+ }
+ }*/
+ }
+ }
+ return fields;
+ }
+
+ /**
+ * Returns a collection of injectable fields declared by a class
+ * or one of its supertypes
+ *
+ * For now we will include final or static fields so that validation problems can be reported
+ */
+ public static Set<Field> getInjectableFields(Class<?> clazz, boolean validating) {
+ return getInjectableFields(clazz, new HashSet<Field>(), validating);
+ }
+
+ /**
+ * Recursively evaluates the type hierarchy to return all fields
+ */
+ private static Set<Field> getInjectableFields(Class<?> clazz, Set<Field> fields, boolean validating) {
+ if (clazz == null || clazz.isArray() || Object.class.equals(clazz)) {
+ return fields;
+ }
+
+ fields = getInjectableFields(clazz.getSuperclass(), fields, validating);
+
+ Field[] declaredFields = null;
+
+ try {
+ declaredFields = clazz.getDeclaredFields();
+ } catch(Throwable t) {
+ //TUSCANY-3667 - clazz.getDeclaredFields might fail in GAE environment (log and ignore)
+ logger.log(Level.WARNING, "Error retrieving declared fields from class : " + t.getMessage());
+ }
+
+ if( declaredFields != null ) {
+ for (final Field field : declaredFields) {
+ int modifiers = field.getModifiers();
+ // The field should be non-final and non-static
+ if (!Modifier.isStatic(modifiers)
+ // && !Modifier.isFinal(modifiers)
+ ) {
+
+ // Allow privileged access to set accessibility. Requires ReflectPermission
+ // in security policy.
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ field.setAccessible(true); // ignore Java accessibility
+ return null;
+ }
+ });
+ fields.add(field);
+ } else {
+ if (validating) {
+ checkInvalidAnnotations(field);
+ }
+ }
+ }
+ }
+
+
+ return fields;
+ }
+
+ /**
+ * Returns a collection of public and protected methods declared by a class
+ * or one of its supertypes. Note that overridden methods will not be
+ * returned in the collection (i.e. only the method override will be). <p/>
+ * This method can potentially be expensive as reflection information is not
+ * cached. It is assumed that this method will be used during a
+ * configuration phase.
+ */
+ public static Set<Method> getAllUniquePublicProtectedMethods(Class<?> clazz, boolean validating) {
+ return getAllUniqueMethods(clazz, new HashSet<Method>(), validating);
+ }
+
+ /**
+ * Recursively evaluates the type hierarchy to return all unique methods
+ */
+ private static Set<Method> getAllUniqueMethods(Class<?> pClass, Set<Method> methods, boolean validating) {
+ if (pClass == null || pClass.isArray() || Object.class.equals(pClass)) {
+ return methods;
+ }
+ // we first evaluate methods of the subclass and then move to the parent
+ Method[] declaredMethods = pClass.getDeclaredMethods();
+ for (final Method declaredMethod : declaredMethods) {
+ int modifiers = declaredMethod.getModifiers();
+ if ((!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) || Modifier.isStatic(modifiers)) {
+ if (validating) {
+ checkInvalidAnnotations(declaredMethod);
+ }
+ continue;
+ }
+ if (methods.size() == 0) {
+ methods.add(declaredMethod);
+ } else {
+ List<Method> temp = new ArrayList<Method>();
+ boolean matched = false;
+ for (Method method : methods) {
+ // only add if not already in the set from a superclass (i.e.
+ // the method is not overridden)
+ if (exactMethodMatch(declaredMethod, method)) {
+ matched = true;
+ break;
+ }
+ }
+ if (!matched) {
+ // Allow privileged access to set accessibility. Requires ReflectPermission
+ // in security policy.
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ declaredMethod.setAccessible(true);
+ return null;
+ }
+ });
+ temp.add(declaredMethod);
+ }
+ methods.addAll(temp);
+ temp.clear();
+ }
+ }
+ // evaluate class hierarchy - this is done last to track inherited
+ // methods
+ methods = getAllUniqueMethods(pClass.getSuperclass(), methods, validating);
+ return methods;
+ }
+
+ /**
+ * Finds the closest matching field with the given name, that is, a field of
+ * the exact specified type or, alternately, of a supertype.
+ *
+ * @param name the name of the field
+ * @param type the field type
+ * @param fields the collection of fields to search
+ * @return the matching field or null if not found
+ */
+ public static Field findClosestMatchingField(String name, Class type, Set<Field> fields) {
+ Field candidate = null;
+ for (Field field : fields) {
+ if (field.getName().equals(name)) {
+ if (field.getType().equals(type)) {
+ return field; // exact match
+ } else if (field.getType().isAssignableFrom(type) || (field.getType().isPrimitive() && primitiveAssignable(field
+ .getType(),
+ type))) {
+ // We could have the situation where a field parameter is a
+ // primitive and the demarshalled value is
+ // an object counterpart (e.g. Integer and int)
+ // @spec issue
+ // either an interface or super class, so keep a reference
+ // until
+ // we know there are no closer types
+ candidate = field;
+ }
+ }
+ }
+ if (candidate != null) {
+ return candidate;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Finds the closest matching method with the given name, that is, a method
+ * taking the exact parameter types or, alternately, parameter supertypes.
+ *
+ * @param name the name of the method
+ * @param types the method parameter types
+ * @param methods the collection of methods to search
+ * @return the matching method or null if not found
+ */
+ public static Method findClosestMatchingMethod(String name, Class[] types, Set<Method> methods) {
+ if (types == null) {
+ types = EMPTY_CLASS_ARRY;
+ }
+ Method candidate = null;
+ for (Method method : methods) {
+ if (method.getName().equals(name) && method.getParameterTypes().length == types.length) {
+ Class<?>[] params = method.getParameterTypes();
+ boolean disqualify = false;
+ boolean exactMatch = true;
+ for (int i = 0; i < params.length; i++) {
+ if (!params[i].equals(types[i]) && !params[i].isAssignableFrom(types[i])) {
+ // no match
+ disqualify = true;
+ exactMatch = false;
+ break;
+ } else if (!params[i].equals(types[i]) && params[i].isAssignableFrom(types[i])) {
+ // not exact match
+ exactMatch = false;
+ }
+ }
+ if (disqualify) {
+ continue;
+ } else if (exactMatch) {
+ return method;
+ } else {
+ candidate = method;
+ }
+ }
+ }
+ if (candidate != null) {
+ return candidate;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Determines if two methods "match" - that is, they have the same method
+ * names and exact parameter types (one is not a supertype of the other)
+ */
+ public static boolean exactMethodMatch(Method method1, Method method2) {
+ if (!method1.getName().equals(method2.getName())) {
+ return false;
+ }
+ Class<?>[] types1 = method1.getParameterTypes();
+ Class<?>[] types2 = method2.getParameterTypes();
+ if (types1.length != types2.length) {
+ return false;
+ }
+ boolean matched = true;
+ for (int i = 0; i < types1.length; i++) {
+ if (types1[i] != types2[i]) {
+ matched = false;
+ break;
+ }
+ }
+ return matched;
+ }
+
+ public static <T> Constructor<T> getDefaultConstructor(Class<T> clazz) throws NoSuchMethodException {
+ return clazz.getConstructor((Class[])null);
+ }
+
+ /**
+ * Returns the simple name of a class - i.e. the class name devoid of its
+ * package qualifier
+ *
+ * @param implClass the implementation class
+ */
+ public static String getBaseName(Class<?> implClass) {
+ return implClass.getSimpleName();
+ }
+
+ public static boolean isImmutable(Class<?> clazz) {
+ return String.class == clazz || clazz.isPrimitive()
+ || Number.class.isAssignableFrom(clazz)
+ || Boolean.class.isAssignableFrom(clazz)
+ || Character.class.isAssignableFrom(clazz)
+ || Byte.class.isAssignableFrom(clazz);
+ }
+
+ /**
+ * Takes a property name and converts it to a getter method name according
+ * to JavaBean conventions. For example, property
+ * <code>foo<code> is returned as <code>getFoo</code>
+ */
+ public static String toGetter(String name) {
+ return "get" + name.toUpperCase().substring(0, 1) + name.substring(1);
+ }
+
+ /**
+ * Takes a setter or getter method name and converts it to a property name
+ * according to JavaBean conventions. For example, <code>setFoo(var)</code>
+ * is returned as property <code>foo<code>
+ */
+ public static String toPropertyName(String name) {
+ if (!name.startsWith("set")) {
+ return name;
+ }
+ return Introspector.decapitalize(name.substring(3));
+ }
+
+ public static Class<?> getErasure(Type type) {
+ if (type instanceof Class) {
+ return (Class<?>)type;
+ } else if (type instanceof GenericArrayType) {
+ // FIXME: How to deal with the []?
+ GenericArrayType arrayType = (GenericArrayType)type;
+ return getErasure(arrayType.getGenericComponentType());
+ } else if (type instanceof ParameterizedType) {
+ ParameterizedType pType = (ParameterizedType)type;
+ return getErasure(pType.getRawType());
+ } else if (type instanceof WildcardType) {
+ WildcardType wType = (WildcardType)type;
+ Type[] types = wType.getUpperBounds();
+ return getErasure(types[0]);
+ } else if (type instanceof TypeVariable) {
+ TypeVariable var = (TypeVariable)type;
+ Type[] types = var.getBounds();
+ return getErasure(types[0]);
+ }
+ return null;
+ }
+
+ public static Class<?> getBaseType(Class<?> cls, Type genericType) {
+ if (cls.isArray()) {
+ return cls.getComponentType();
+ } else if (Collection.class.isAssignableFrom(cls)) {
+ if (genericType instanceof ParameterizedType) {
+ // Collection<BaseType>
+ ParameterizedType parameterizedType = (ParameterizedType)genericType;
+ Type baseType = parameterizedType.getActualTypeArguments()[0];
+ if (baseType instanceof GenericArrayType) {
+ // Base is array
+ return cls;
+ } else {
+ return getErasure(baseType);
+ }
+ } else {
+ return cls;
+ }
+ } else {
+ return cls;
+ }
+ }
+
+ public static Type getParameterType(Type type) {
+ if (type instanceof ParameterizedType) {
+ // Collection<BaseType>
+ ParameterizedType parameterizedType = (ParameterizedType)type;
+ Type baseType = parameterizedType.getActualTypeArguments()[0];
+ return baseType;
+ } else {
+ return Object.class;
+ }
+ }
+
+ public static Class<?> getBusinessInterface(Class<?> cls, Type callableReferenceType) {
+ if (ServiceReference.class.isAssignableFrom(cls) && callableReferenceType instanceof ParameterizedType) {
+ // Collection<BaseType>
+ ParameterizedType parameterizedType = (ParameterizedType)callableReferenceType;
+ Type baseType = parameterizedType.getActualTypeArguments()[0];
+ if (baseType instanceof GenericArrayType) {
+ // Base is array
+ return cls;
+ } else {
+ return getErasure(baseType);
+ }
+ }
+ return Object.class;
+ }
+
+ /**
+ * Takes a property name and converts it to a setter method name according
+ * to JavaBean conventions. For example, the property
+ * <code>foo<code> is returned as <code>setFoo(var)</code>
+ */
+ public static String toSetter(String name) {
+ return "set" + name.toUpperCase().substring(0, 1) + name.substring(1);
+ }
+
+ /**
+ * Compares a two types, assuming one is a primitive, to determine if the
+ * other is its object counterpart
+ */
+ private static boolean primitiveAssignable(Class<?> memberType, Class<?> param) {
+ if (memberType == Integer.class) {
+ return param == Integer.TYPE;
+ } else if (memberType == Double.class) {
+ return param == Double.TYPE;
+ } else if (memberType == Float.class) {
+ return param == Float.TYPE;
+ } else if (memberType == Short.class) {
+ return param == Short.TYPE;
+ } else if (memberType == Character.class) {
+ return param == Character.TYPE;
+ } else if (memberType == Boolean.class) {
+ return param == Boolean.TYPE;
+ } else if (memberType == Byte.class) {
+ return param == Byte.TYPE;
+ } else if (param == Integer.class) {
+ return memberType == Integer.TYPE;
+ } else if (param == Double.class) {
+ return memberType == Double.TYPE;
+ } else if (param == Float.class) {
+ return memberType == Float.TYPE;
+ } else if (param == Short.class) {
+ return memberType == Short.TYPE;
+ } else if (param == Character.class) {
+ return memberType == Character.TYPE;
+ } else if (param == Boolean.class) {
+ return memberType == Boolean.TYPE;
+ } else if (param == Byte.class) {
+ return memberType == Byte.TYPE;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the generic types represented in the given type. Usage as
+ * follows: <code>
+ * JavaIntrospectionHelper.getGenerics(field.getGenericType());
+ * <p/>
+ * JavaIntrospectionHelper.getGenerics(m.getGenericParameterTypes()[0];); </code>
+ *
+ * @return the generic types in order of declaration or an empty array if
+ * the type is not genericized
+ */
+ public static List<? extends Type> getGenerics(Type genericType) {
+ List<Type> classes = new ArrayList<Type>();
+ if (genericType instanceof ParameterizedType) {
+ ParameterizedType ptype = (ParameterizedType)genericType;
+ // get the type arguments
+ Type[] targs = ptype.getActualTypeArguments();
+ for (Type targ : targs) {
+ classes.add(targ);
+ }
+ }
+ return classes;
+ }
+
+ /**
+ * Returns the generic type specified by the class at the given position as
+ * in: <p/> <code> public class Foo<Bar,Baz>{ //.. }
+ * <p/>
+ * JavaIntrospectionHelper.introspectGeneric(Foo.class,1); <code>
+ * <p/>
+ * will return Baz.
+ */
+ public static Class introspectGeneric(Class<?> clazz, int pos) {
+ assert clazz != null : "No class specified";
+ Type type = clazz.getGenericSuperclass();
+ if (type instanceof ParameterizedType) {
+ Type[] args = ((ParameterizedType)type).getActualTypeArguments();
+ if (args.length <= pos) {
+ throw new IllegalArgumentException("Invalid index value for generic class " + clazz.getName());
+ }
+ return (Class)((ParameterizedType)type).getActualTypeArguments()[pos];
+ } else {
+ Type[] interfaces = clazz.getGenericInterfaces();
+ for (Type itype : interfaces) {
+ if (!(itype instanceof ParameterizedType)) {
+ continue;
+ }
+ ParameterizedType interfaceType = (ParameterizedType)itype;
+ return (Class)interfaceType.getActualTypeArguments()[0];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the set of interfaces implemented by the given class and its
+ * ancestors or a blank set if none
+ */
+ public static Set<Class<?>> getAllInterfaces(Class<?> clazz) {
+ Set<Class<?>> implemented = new HashSet<Class<?>>();
+ getAllInterfaces(clazz, implemented);
+ return implemented;
+ }
+
+ private static void getAllInterfaces(Class<?> clazz, Set<Class<?>> implemented) {
+ Class<?>[] interfaces = clazz.getInterfaces();
+ for (Class<?> interfaze : interfaces) {
+ implemented.add(interfaze);
+ }
+ Class<?> superClass = clazz.getSuperclass();
+ // Object has no superclass so check for null
+ if (superClass != null && !superClass.equals(Object.class)) {
+ getAllInterfaces(superClass, implemented);
+ }
+ }
+
+ public static boolean isSetter(Method method) {
+ return (void.class == method.getReturnType() && method.getParameterTypes().length == 1 && method.getName()
+ .startsWith("set"));
+ }
+
+ public static boolean isGetter(Method method) {
+ return (void.class != method.getReturnType() && method.getParameterTypes().length == 0 && method.getName()
+ .startsWith("get"));
+ }
+
+ private final static Map<Class<?>, String> signatures = new HashMap<Class<?>, String>();
+ static {
+ signatures.put(boolean.class, "Z");
+ signatures.put(byte.class, "B");
+ signatures.put(char.class, "C");
+ signatures.put(short.class, "S");
+ signatures.put(int.class, "I");
+ signatures.put(long.class, "J");
+ signatures.put(float.class, "F");
+ signatures.put(double.class, "D");
+ };
+
+ public static String getSignature(Class<?> cls) {
+ if (cls.isPrimitive()) {
+ return signatures.get(cls);
+ }
+ if (cls.isArray()) {
+ return "[" + getSignature(cls.getComponentType());
+ }
+ return "L" + cls.getName().replace('.', '/') + ";";
+ }
+
+ public static Class<?> getArrayType(Class<?> componentType, int dims) throws ClassNotFoundException {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < dims; i++) {
+ buf.append('[');
+ }
+ buf.append(getSignature(componentType));
+ return Class.forName(buf.toString(), false, componentType.getClassLoader());
+ }
+
+ public static Set<Method> getPrivateMethods(Class<?> clazz) {
+ Set<Method> methods = new HashSet<Method>();
+ Method[] declaredMethods = clazz.getDeclaredMethods();
+ for (final Method declaredMethod : declaredMethods) {
+ int modifiers = declaredMethod.getModifiers();
+ if(Modifier.isPrivate(modifiers)) {
+ methods.add(declaredMethod);
+ }
+ }
+
+ return methods;
+ }
+
+ public static Set<Field> getPrivateFields(Class<?> clazz) {
+ Set<Field> fields = new HashSet<Field>();
+ Field[] declaredFields = clazz.getDeclaredFields();
+ for (final Field declaredField : declaredFields) {
+ int modifiers = declaredField.getModifiers();
+ if(Modifier.isPrivate(modifiers)) {
+ fields.add(declaredField);
+ }
+ }
+
+ return fields;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AbstractPropertyProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AbstractPropertyProcessor.java
new file mode 100644
index 0000000000..ff70fb89eb
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AbstractPropertyProcessor.java
@@ -0,0 +1,257 @@
+/*
+ * 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 java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+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.JavaParameterImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+
+/**
+ * Base class for ImplementationProcessors that handle annotations that add
+ * Properties.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractPropertyProcessor<A extends Annotation> extends BaseJavaClassVisitor {
+ private final Class<A> annotationClass;
+
+ protected AbstractPropertyProcessor(ExtensionPointRegistry registry, Class<A> annotationClass) {
+ super(registry);
+ this.annotationClass = annotationClass;
+ }
+
+ private static boolean removeProperty(JavaElementImpl prop, JavaImplementation type) {
+ if(prop==null) {
+ return false;
+ }
+ List<Property> props = type.getProperties();
+ for(int i=0;i<props.size();i++) {
+ if(props.get(i).getName().equals(prop.getName())) {
+ props.remove(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+ A annotation = method.getAnnotation(annotationClass);
+ if (annotation != null) {
+
+ if (!JavaIntrospectionHelper.isSetter(method)) {
+ throw new IllegalPropertyException("Annotated method is not a setter: " + method, method);
+ }
+
+ if(Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalPropertyException("Static method " + method.getName() +" in class " + method.getDeclaringClass().getName() + " can not be annotated as a Property");
+ }
+
+ String name = getName(annotation);
+ if (name == null || "".equals(name)) {
+ name = method.getName();
+ if (name.startsWith("set")) {
+ name = JavaIntrospectionHelper.toPropertyName(method.getName());
+ }
+ }
+
+ Map<String, JavaElementImpl> properties = type.getPropertyMembers();
+ JavaElementImpl prop = properties.get(name);
+ // Setter override field
+ if (prop != null && prop.getElementType() != ElementType.FIELD) {
+ throw new DuplicatePropertyException(name);
+ }
+
+ removeProperty(prop, type);
+
+ JavaElementImpl element = new JavaElementImpl(method, 0);
+ Property property = createProperty(name, element);
+
+ // add databinding available as annotations, as extensions
+
+ initProperty(property, annotation);
+ type.getProperties().add(property);
+ properties.put(name, element);
+ }
+
+ // enforce the constraint that an ordinary method's argument can not be a Property
+ Annotation paramsAnnotations[][] = method.getParameterAnnotations();
+ for (int i = 0; i < paramsAnnotations.length; i++) {
+ Annotation argAnnotations[] = paramsAnnotations[i];
+ for (int j = 0; j < argAnnotations.length; j++) {
+ if(argAnnotations[j].annotationType() == org.oasisopen.sca.annotation.Property.class) {
+ throw new IllegalPropertyException("[JCA90001] Argument " + (i+1) + " of method " + method.getName() + " in class " + method.getDeclaringClass() + " can not be a Property");
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public void visitField(Field field, JavaImplementation type) throws IntrospectionException {
+
+ A annotation = field.getAnnotation(annotationClass);
+ if (annotation == null) {
+ return;
+ }
+
+ if(Modifier.isStatic(field.getModifiers())) {
+ throw new IllegalPropertyException("Static field " + field.getName() +" in class " + field.getDeclaringClass().getName() + " can not be annotated as a Property");
+ }
+
+ if(Modifier.isFinal(field.getModifiers())) {
+ throw new IllegalPropertyException("[JCA90011] Final field " + field.getName() +" in class " + field.getDeclaringClass().getName() + " can not be annotated as a Property");
+ }
+
+ String name = getName(annotation);
+ if (name == null) {
+ name = "";
+ }
+ if ("".equals(name) || name.equals(field.getType().getName())) {
+ name = field.getName();
+ }
+
+ Map<String, JavaElementImpl> properties = type.getPropertyMembers();
+ JavaElementImpl prop = properties.get(name);
+ // Setter override field
+ if (prop != null && prop.getElementType() == ElementType.FIELD) {
+ throw new DuplicatePropertyException(name);
+ }
+
+ if (prop == null) {
+ JavaElementImpl element = new JavaElementImpl(field);
+ Property property = createProperty(name, element);
+ initProperty(property, annotation);
+ type.getProperties().add(property);
+ properties.put(name, element);
+ }
+ }
+
+ @Override
+ public void visitConstructorParameter(JavaParameterImpl parameter, JavaImplementation type)
+ throws IntrospectionException {
+
+ Map<String, JavaElementImpl> properties = type.getPropertyMembers();
+ A annotation = parameter.getAnnotation(annotationClass);
+ if (annotation != null) {
+ String name = getName(annotation);
+ if (name == null) {
+ name = parameter.getType().getName();
+ }
+ if (!"".equals(name) && !"".equals(parameter.getName()) && !name.equals(parameter.getName())) {
+ throw new InvalidConstructorException("Mismatched property name: " + parameter);
+ }
+ if ("".equals(name) && "".equals(parameter.getName())) {
+ throw new InvalidPropertyException("[JCA90013] Missing property name: " + parameter);
+ }
+ if ("".equals(name)) {
+ name = parameter.getName();
+ }
+
+ if (!getRequired(annotation)) {
+ throw new InvalidPropertyException("[JCA90014] Constructor property must not have required=false: " + type.getName());
+ }
+
+ JavaElementImpl prop = properties.get(name);
+ // Setter override field
+ if (prop != null && prop.getElementType() != ElementType.FIELD) {
+ throw new DuplicatePropertyException(name);
+ }
+ removeProperty(prop, type);
+
+ parameter.setName(name);
+ parameter.setClassifer(annotationClass);
+ Property property = createProperty(name, parameter);
+ initProperty(property, annotation);
+ type.getProperties().add(property);
+ properties.put(name, parameter);
+ }
+ }
+
+ protected Property createProperty(String name, JavaElementImpl element) throws IntrospectionException {
+
+ Type type = element.getGenericType();
+ Class<?> javaType = element.getType();
+
+ return createProperty(assemblyFactory, name, javaType, type);
+
+ }
+
+ public static Property createProperty(AssemblyFactory assemblyFactory, String name, Class<?> javaClass, Type genericType) {
+ Property property = assemblyFactory.createProperty();
+ property.setName(name);
+
+ if (javaClass.isArray() || Collection.class.isAssignableFrom(javaClass)) {
+ property.setMany(true);
+ if (javaClass.isArray()) {
+ Class<?> propType = javaClass.getComponentType();
+ Type genericPropType = propType;
+ if (genericType instanceof GenericArrayType) {
+ genericPropType = ((GenericArrayType)genericType).getGenericComponentType();
+ }
+ DataType dt = new DataTypeImpl(null, propType, genericPropType, XMLType.UNKNOWN);
+ property.setDataType(dt);
+ } else {
+ if (genericType instanceof ParameterizedType) {
+ // Collection<BaseType> property;
+ Type genericPropType = ((ParameterizedType)genericType).getActualTypeArguments()[0];
+ Class<?> propType = JavaIntrospectionHelper.getErasure(genericPropType);
+ DataType dt = new DataTypeImpl(null, propType, genericPropType, XMLType.UNKNOWN);
+ property.setDataType(dt);
+ } else {
+ // Collection property;
+ DataType dt = new DataTypeImpl(null, Object.class, Object.class, XMLType.UNKNOWN);
+ property.setDataType(dt);
+ }
+ }
+ } else {
+ DataType dt = new DataTypeImpl(null, javaClass, genericType, XMLType.UNKNOWN);
+ property.setDataType(dt);
+ }
+ return property;
+ }
+
+ protected abstract String getName(A annotation);
+ protected abstract boolean getRequired(A annotation);
+
+ protected abstract void initProperty(Property property, A annotation) throws IntrospectionException;
+
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AllowsPassByReferenceProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AllowsPassByReferenceProcessor.java
new file mode 100644
index 0000000000..4aa29d3b91
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AllowsPassByReferenceProcessor.java
@@ -0,0 +1,57 @@
+/*
+ * 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 java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.oasisopen.sca.annotation.AllowsPassByReference;
+
+/**
+ * Processes {@link AllowsPassByReference} on an implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class AllowsPassByReferenceProcessor extends BaseJavaClassVisitor {
+
+ public AllowsPassByReferenceProcessor(AssemblyFactory factory) {
+ super(factory);
+ }
+
+ public AllowsPassByReferenceProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public <T> void visitClass(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+ type.setAllowsPassByReference(clazz.isAnnotationPresent(AllowsPassByReference.class));
+ }
+
+ @Override
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+ boolean pbr = method.isAnnotationPresent(AllowsPassByReference.class);
+ if (pbr) {
+ type.getAllowsPassByReferenceMethods().add(method);
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AmbiguousConstructorException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AmbiguousConstructorException.java
new file mode 100644
index 0000000000..c6e6b6e4d6
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AmbiguousConstructorException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 java.lang.reflect.Member;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Thrown when constructor parameters cannot be unambiguously resolved to a property or reference
+ *
+ * @version $Rev$ $Date$
+ */
+public class AmbiguousConstructorException extends IntrospectionException {
+ private static final long serialVersionUID = 3662860753837091880L;
+
+ public AmbiguousConstructorException(String message) {
+ super(message);
+ }
+
+ public AmbiguousConstructorException(String message, Member member) {
+ super(message, member);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ComponentNameProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ComponentNameProcessor.java
new file mode 100644
index 0000000000..1813a177b4
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ComponentNameProcessor.java
@@ -0,0 +1,87 @@
+/*
+ * 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 java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+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.JavaResourceImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.oasisopen.sca.annotation.ComponentName;
+
+/**
+ * Processes {@link @ComponentName} annotations on a component implementation and adds
+ * a {@link JavaMappedProperty} to the component type which will be used to
+ * inject the appropriate component name.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ComponentNameProcessor extends BaseJavaClassVisitor {
+
+ public ComponentNameProcessor(AssemblyFactory factory) {
+ super(factory);
+ }
+
+ public ComponentNameProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+ if (method.getAnnotation(ComponentName.class) == null) {
+ return;
+ }
+ if (method.getParameterTypes().length != 1) {
+ throw new IllegalContextException("ComponentName setter must have one parameter", method);
+ }
+ Class<?> paramType = method.getParameterTypes()[0];
+ String name = JavaIntrospectionHelper.toPropertyName(method.getName());
+ if (String.class.equals(paramType)) {
+ JavaElementImpl element = new JavaElementImpl(method, 0);
+ element.setName(name);
+ element.setClassifer(org.apache.tuscany.sca.implementation.java.introspect.impl.Resource.class);
+ JavaResourceImpl resource = new JavaResourceImpl(element);
+ type.getResources().put(resource.getName(), resource);
+ } else {
+ throw new IllegalContextException(paramType.getName());
+ }
+ }
+
+ @Override
+ public void visitField(Field field, JavaImplementation type) throws IntrospectionException {
+ if (field.getAnnotation(ComponentName.class) == null) {
+ return;
+ }
+ Class<?> paramType = field.getType();
+ if (String.class.equals(paramType)) {
+ JavaElementImpl element = new JavaElementImpl(field);
+ element.setClassifer(Resource.class);
+ JavaResourceImpl resource = new JavaResourceImpl(element);
+ type.getResources().put(resource.getName(), resource);
+ } else {
+ throw new IllegalContextException(paramType.getName());
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ConstructorProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ConstructorProcessor.java
new file mode 100644
index 0000000000..2017a9d75e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ConstructorProcessor.java
@@ -0,0 +1,102 @@
+/*
+ * 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 java.lang.reflect.Constructor;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaParameterImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+
+/**
+ * Handles processing of a constructor decorated with
+ * {@link org.oasisopen.sca.annotation.Constructor}
+ *
+ * @version $Rev$ $Date$
+ */
+@SuppressWarnings("unchecked")
+public class ConstructorProcessor extends BaseJavaClassVisitor {
+
+ public ConstructorProcessor(AssemblyFactory factory) {
+ super(factory);
+ }
+
+ public ConstructorProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public <T> void visitClass(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+ Constructor[] ctors = clazz.getConstructors();
+ boolean found = false;
+ for (Constructor constructor : ctors) {
+ JavaConstructorImpl<?> definition = new JavaConstructorImpl(constructor);
+ type.getConstructors().put(constructor, definition);
+ if (constructor.getAnnotation(org.oasisopen.sca.annotation.Constructor.class) != null) {
+ if (found) {
+ throw new DuplicateConstructorException("[JCI50002] Multiple constructors marked with @Constructor", constructor);
+ }
+ found = true;
+ type.setConstructor(definition);
+ }
+ }
+ }
+
+ @Override
+ public <T> void visitConstructor(Constructor<T> constructor, JavaImplementation type)
+ throws IntrospectionException {
+ org.oasisopen.sca.annotation.Constructor annotation = constructor
+ .getAnnotation(org.oasisopen.sca.annotation.Constructor.class);
+ if (annotation == null) {
+ return;
+ }
+ JavaConstructorImpl<?> definition = type.getConstructor();
+ if (definition == null) {
+ definition = new JavaConstructorImpl(constructor);
+ type.setConstructor(definition);
+ }
+ JavaParameterImpl[] parameters = definition.getParameters();
+
+ for (JavaParameterImpl p : parameters) {
+ if (!hasAnnotation(p)) {
+ throw new InvalidConstructorException("JCA90003 constructor parameters for class " + type.getName() + " must have @Property or @Reference annotation");
+ }
+ }
+
+ type.setConstructor(definition);
+ }
+
+ private boolean hasAnnotation(JavaParameterImpl p) {
+ if (p.getAnnotations() != null && p.getAnnotations().length > 0) {
+ return true;
+ }
+// TODO: need to verify JCA90003 as it seems like any annotation should be ok not just SCA ref or prop
+// if (p.getAnnotation(Reference.class) != null) {
+// return true;
+// }
+// if (p.getAnnotation(Property.class) != null) {
+// return true;
+// }
+ return false;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ContextProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ContextProcessor.java
new file mode 100644
index 0000000000..bf57fbc9fe
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ContextProcessor.java
@@ -0,0 +1,89 @@
+/*
+ * 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 java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+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.JavaResourceImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.oasisopen.sca.ComponentContext;
+import org.oasisopen.sca.RequestContext;
+import org.oasisopen.sca.annotation.Context;
+
+/**
+ * Processes {@link @Context} annotations on a component implementation and adds
+ * a {@link JavaMappedProperty} to the component type which will be used to
+ * inject the appropriate context
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContextProcessor extends BaseJavaClassVisitor {
+
+ public ContextProcessor(AssemblyFactory factory) {
+ super(factory);
+ }
+
+ public ContextProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+ if (method.getAnnotation(Context.class) == null) {
+ return;
+ }
+ if (method.getParameterTypes().length != 1) {
+ throw new IllegalContextException("Context setter must have one parameter", method);
+ }
+ Class<?> paramType = method.getParameterTypes()[0];
+ String name = JavaIntrospectionHelper.toPropertyName(method.getName());
+ if (ComponentContext.class.isAssignableFrom(paramType) || RequestContext.class.equals(paramType)) {
+ JavaElementImpl element = new JavaElementImpl(method, 0);
+ element.setName(name);
+ element.setClassifer(org.apache.tuscany.sca.implementation.java.introspect.impl.Resource.class);
+ JavaResourceImpl resource = new JavaResourceImpl(element);
+ type.getResources().put(resource.getName(), resource);
+ } else {
+ throw new UnknownContextTypeException(paramType.getName());
+ }
+ }
+
+ @Override
+ public void visitField(Field field, JavaImplementation type) throws IntrospectionException {
+ if (field.getAnnotation(Context.class) == null) {
+ return;
+ }
+ Class<?> paramType = field.getType();
+ if (ComponentContext.class.isAssignableFrom(paramType) || RequestContext.class.equals(paramType)) {
+ JavaElementImpl element = new JavaElementImpl(field);
+ element.setClassifer(Resource.class);
+ JavaResourceImpl resource = new JavaResourceImpl(element);
+ type.getResources().put(resource.getName(), resource);
+ } else {
+ throw new UnknownContextTypeException(paramType.getName());
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DestroyProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DestroyProcessor.java
new file mode 100644
index 0000000000..a4b760760c
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DestroyProcessor.java
@@ -0,0 +1,63 @@
+/*
+ * 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 java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.oasisopen.sca.annotation.Destroy;
+
+/**
+ * Processes the {@link @Destroy} annotation on a component implementation and
+ * updates the component type with the decorated destructor method
+ *
+ * @version $Rev$ $Date$
+ */
+public class DestroyProcessor extends BaseJavaClassVisitor {
+
+ public DestroyProcessor(AssemblyFactory factory) {
+ super(factory);
+ }
+
+ public DestroyProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+ Destroy annotation = method.getAnnotation(Destroy.class);
+ if (annotation == null) {
+ return;
+ }
+ if (method.getParameterTypes().length != 0) {
+ throw new IllegalDestructorException("[JCA90004] Destructor must not have arguments", method);
+ }
+ if(!method.getReturnType().equals(void.class)) {
+ throw new IllegalDestructorException("Destructor must return void.", method);
+ }
+ if (type.getDestroyMethod() != null) {
+ throw new DuplicateDestructorException("More than one destructor found on implementation");
+ }
+ type.setDestroyMethod(method);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateConstructorException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateConstructorException.java
new file mode 100644
index 0000000000..d6494e3845
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateConstructorException.java
@@ -0,0 +1,41 @@
+/*
+ * 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 java.lang.reflect.Member;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Thrown when more than one component implementation constructor is annotated with {@link
+ * org.oasisopen.sca.annotation.Constructor}
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateConstructorException extends IntrospectionException {
+ private static final long serialVersionUID = -5926763756570552986L;
+
+ public DuplicateConstructorException(String message) {
+ super(message);
+ }
+
+ public DuplicateConstructorException(String message, Member member) {
+ super(message, member);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateDestructorException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateDestructorException.java
new file mode 100644
index 0000000000..8bfae89162
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateDestructorException.java
@@ -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.tuscany.sca.implementation.java.introspect.impl;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Thrown when an implementation is annotated multiple times with {@link org.oasisopen.sca.annotation.Destroy}
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateDestructorException extends IntrospectionException {
+ private static final long serialVersionUID = -7474912510114895203L;
+
+ public DuplicateDestructorException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateInitException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateInitException.java
new file mode 100644
index 0000000000..38f6478531
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateInitException.java
@@ -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.tuscany.sca.implementation.java.introspect.impl;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Thrown when an implementation is annotated multiple times with {@link @org.oasisopen.sca.annotation.Init}
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateInitException extends IntrospectionException {
+ private static final long serialVersionUID = -6282935288115512057L;
+
+ public DuplicateInitException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicatePropertyException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicatePropertyException.java
new file mode 100644
index 0000000000..b9e1923e73
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicatePropertyException.java
@@ -0,0 +1,34 @@
+/*
+ * 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 org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Thrown when an implementation has more than one property injection site with the same name
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicatePropertyException extends IntrospectionException {
+ private static final long serialVersionUID = 5536415875694904037L;
+
+ public DuplicatePropertyException(String message) {
+ super(message);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateReferenceException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateReferenceException.java
new file mode 100644
index 0000000000..300ad6817e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateReferenceException.java
@@ -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.tuscany.sca.implementation.java.introspect.impl;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Thrown when an implementation has more than one reference injection site with the same name
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateReferenceException extends IntrospectionException {
+ private static final long serialVersionUID = 907910648213477158L;
+
+ public DuplicateReferenceException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateResourceException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateResourceException.java
new file mode 100644
index 0000000000..2d177b3f76
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/DuplicateResourceException.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Thrown when an implementation has more than one resource injection site with the same name
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateResourceException extends IntrospectionException {
+
+ private static final long serialVersionUID = 1619276459330463299L;
+
+ public DuplicateResourceException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/EagerInitProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/EagerInitProcessor.java
new file mode 100644
index 0000000000..5c0e2c1397
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/EagerInitProcessor.java
@@ -0,0 +1,63 @@
+/*
+ * 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 org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.oasisopen.sca.annotation.EagerInit;
+
+/**
+ * Handles processing of {@link org.oasisopen.sca.annotation.EagerInit}
+ *
+ * @version $Rev$ $Date$
+ */
+public class EagerInitProcessor extends BaseJavaClassVisitor {
+
+ public EagerInitProcessor(AssemblyFactory factory) {
+ super(factory);
+ }
+
+ public EagerInitProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public <T> void visitClass(Class<T> clazz,
+ JavaImplementation type) throws IntrospectionException {
+ super.visitClass(clazz, type);
+ EagerInit annotation = clazz.getAnnotation(EagerInit.class);
+ if (annotation == null) {
+ Class<?> superClass = clazz.getSuperclass();
+ while (superClass != null && !Object.class.equals(superClass)) {
+ annotation = superClass.getAnnotation(EagerInit.class);
+ if (annotation != null) {
+ break;
+ }
+ superClass = superClass.getSuperclass();
+ }
+ if (annotation == null) {
+ return;
+ }
+ }
+ type.setEagerInit(true);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/HeuristicPojoProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/HeuristicPojoProcessor.java
new file mode 100644
index 0000000000..43cdeb319d
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/HeuristicPojoProcessor.java
@@ -0,0 +1,765 @@
+/*
+ * 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.JavaIntrospectionHelper.getAllInterfaces;
+import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllPublicAndProtectedFields;
+import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllUniquePublicProtectedMethods;
+import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getBaseType;
+import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.toPropertyName;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jws.WebService;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.Multiplicity;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl;
+import org.apache.tuscany.sca.implementation.java.JavaElementImpl;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaParameterImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.oasisopen.sca.ServiceReference;
+import org.oasisopen.sca.annotation.Callback;
+import org.oasisopen.sca.annotation.ComponentName;
+import org.oasisopen.sca.annotation.Context;
+import org.oasisopen.sca.annotation.Property;
+import org.oasisopen.sca.annotation.Reference;
+import org.oasisopen.sca.annotation.Remotable;
+
+/**
+ * Heuristically evaluates an un-annotated Java implementation type to determine
+ * services, references, and properties according to the algorithm described in
+ * the SCA Java Client and Implementation Model Specification <p/> TODO
+ * Implement: <p/> When no service interface is annotated, need to calculate a
+ * single service comprising all public methods that are not reference or
+ * property injection sites. If that service can be exactly mapped to an
+ * interface implemented by the class then the service interface will be defined
+ * in terms of that interface.
+ *
+ * @version $Rev$ $Date$
+ */
+public class HeuristicPojoProcessor extends BaseJavaClassVisitor {
+
+ public HeuristicPojoProcessor(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) {
+ super(assemblyFactory);
+ this.javaInterfaceFactory = javaFactory;
+ }
+
+ public HeuristicPojoProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public <T> void visitEnd(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+ List<org.apache.tuscany.sca.assembly.Service> services = type.getServices();
+
+ if (services.isEmpty()) {
+ // heuristically determine the service
+ /**
+ * The following is quoted from Java Specification 1.2.1.3. Introspecting services offered by a Java implementation
+ * In the cases described below, the services offered by a Java implementation class may be determined
+ * through introspection, eliding the need to specify them using @Service. The following algorithm is used
+ * to determine how services are introspected from an implementation class:
+ *
+ * If the interfaces of the SCA services are not specified with the @Service annotation on the
+ * implementation class, it is assumed that all implemented interfaces that have been annotated
+ * as @Remotable are the service interfaces provided by the component. If none of the implemented
+ * interfaces is remotable, then by default the implementation offers a single service whose type
+ * is the implementation class.
+ */
+ Set<Class<?>> interfaces = getAllInterfaces(clazz);
+ for (Class<?> i : interfaces) {
+ if (i.isAnnotationPresent(Remotable.class) || i.isAnnotationPresent(WebService.class)) {
+ addService(type, i);
+ }
+ }
+ if (services.isEmpty()) {
+ // class is the interface
+ addService(type, clazz);
+ }
+ }
+
+ // TUSCANY-3965 - The OSASIS JCI spec (section 8) now provides an explicit algorithm
+ // for property and reference introspection. It's only performed if no @Service, @Reference
+ // or @Property annotation is present
+ if (clazz.getAnnotation(org.oasisopen.sca.annotation.Service.class) == null &&
+ type.getReferenceMembers().isEmpty() &&
+ type.getPropertyMembers().isEmpty()){
+ Set<Method> methods = getAllUniquePublicProtectedMethods(clazz, false);
+ calcPropRefs(methods, services, type, clazz);
+ }
+
+ evaluateConstructor(type, clazz);
+ }
+
+ // Check if the implementation is implementation.java
+ private boolean isImplementationJava(JavaImplementation type) {
+ return JavaImplementation.TYPE.equals(type.getType());
+ }
+
+ private void addService(JavaImplementation type, Class<?> clazz) throws IntrospectionException {
+ try {
+ org.apache.tuscany.sca.assembly.Service service = createService(clazz);
+ type.getServices().add(service);
+ } catch (InvalidInterfaceException e) {
+ throw new IntrospectionException(e);
+ }
+ }
+
+ private static boolean isAnnotatedWithSCA(AnnotatedElement element) {
+ for (Annotation a : element.getAnnotations()) {
+ // JCI_8023
+ // policy annotations can be added to reference fields that
+ // don't have @Reference annotations so we need to allow
+ // for the fields to be detected as references
+ if (isSCAPolicyAnnotation(a)){
+ continue;
+ } else if (isSCAAnnotation(a)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean isAnnotated(AnnotatedElement element) {
+ for (Annotation a : element.getAnnotations()) {
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean isSCAAnnotation(Annotation a) {
+ return a.annotationType().getName().startsWith("org.oasisopen.sca.annotation.");
+ }
+
+ private static boolean isSCAPolicyAnnotation(Annotation a) {
+ if (a.annotationType().getName().startsWith("org.oasisopen.sca.annotation.PolicySets") ){
+ return true;
+ } else if (a.annotationType().getName().startsWith("org.oasisopen.sca.annotation.Intent") ){
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private <T> void calcPropRefs(Set<Method> methods,
+ List<org.apache.tuscany.sca.assembly.Service> services,
+ JavaImplementation type,
+ Class<T> clazz) throws IntrospectionException {
+ // heuristically determine the properties references
+ // make a first pass through all public methods with one param
+ Set<String> setters = new HashSet<String>();
+ Set<String> others = new HashSet<String>();
+ for (Method method : methods) {
+ if (!isPublicSetter(method)) {
+ continue;
+ }
+ if (isAnnotatedWithSCA(method)) {
+ // Add the property name as others
+ others.add(toPropertyName(method.getName()));
+ continue;
+ }
+ if (!isInServiceInterface(method, services)) {
+ // Not part of the service interface
+ String name = toPropertyName(method.getName());
+ setters.add(name);
+ // avoid duplicate property or ref names
+ if (!type.getPropertyMembers().containsKey(name) && !type.getReferenceMembers().containsKey(name)) {
+ Class<?> param = method.getParameterTypes()[0];
+ Type genericType = method.getGenericParameterTypes()[0];
+ if (isReferenceType(param, genericType)) {
+ type.getReferences().add(createReference(name, param, genericType));
+ type.getReferenceMembers().put(name, new JavaElementImpl(method, 0));
+ } else {
+ type.getProperties().add(createProperty(name, param, genericType));
+ type.getPropertyMembers().put(name, new JavaElementImpl(method, 0));
+ }
+ }
+ }
+ }
+ // second pass for protected methods with one param
+ for (Method method : methods) {
+ if (!isProtectedSetter(method)) {
+ continue;
+ }
+ if (isAnnotatedWithSCA(method)) {
+ // Add the property name as others
+ others.add(toPropertyName(method.getName()));
+ continue;
+ }
+ Class<?> param = method.getParameterTypes()[0];
+ Type paramType = method.getGenericParameterTypes()[0];
+
+ String name = toPropertyName(method.getName());
+ setters.add(name);
+ // avoid duplicate property or ref names
+ if (isReferenceType(param, method.getGenericParameterTypes()[0])) {
+ if (!type.getReferenceMembers().containsKey(name)) {
+ type.getReferences().add(createReference(name, param, paramType));
+ type.getReferenceMembers().put(name, new JavaElementImpl(method, 0));
+ }
+ } else {
+ if (!type.getPropertyMembers().containsKey(name)) {
+ type.getProperties().add(createProperty(name, param, paramType));
+ type.getPropertyMembers().put(name, new JavaElementImpl(method, 0));
+ }
+ }
+ }
+
+ // Public or protected fields unless there is a public or protected
+ // setter method
+ // for the same name
+ Set<Field> fields = getAllPublicAndProtectedFields(clazz, false);
+ for (Field field : fields) {
+ if (isAnnotatedWithSCA(field)) {
+ continue;
+ }
+ if (setters.contains(field.getName()) || others.contains(field.getName())) {
+ continue;
+ }
+ String name = field.getName();
+ Class<?> paramType = field.getType();
+ Type genericType = field.getGenericType();
+ if (isReferenceType(paramType, field.getGenericType())) {
+ if (!type.getReferenceMembers().containsKey(name)) {
+ type.getReferences().add(createReference(name, paramType, genericType));
+ type.getReferenceMembers().put(name, new JavaElementImpl(field));
+ }
+ } else {
+ if (!type.getPropertyMembers().containsKey(name)) {
+ if (!isAnnotated(field)) { // if the field has an annotation then its not a property
+ type.getProperties().add(createProperty(name, paramType, genericType));
+ type.getPropertyMembers().put(name, new JavaElementImpl(field));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Determines the constructor to use based on the component type's
+ * references and properties
+ *
+ * @param type the component type
+ * @param clazz the implementation class corresponding to the component type
+ * @throws NoConstructorException if no suitable constructor is found
+ * @throws AmbiguousConstructorException if the parameters of a constructor
+ * cannot be unambiguously mapped to references and properties
+ */
+ @SuppressWarnings("unchecked")
+ private <T> void evaluateConstructor(JavaImplementation type, Class<T> clazz) throws IntrospectionException {
+ // determine constructor if one is not annotated
+ JavaConstructorImpl<?> definition = type.getConstructor();
+ Constructor constructor;
+ boolean explict = false;
+ if (definition != null && definition.getConstructor()
+ .isAnnotationPresent(org.oasisopen.sca.annotation.Constructor.class)) {
+ // the constructor was already defined explicitly
+ return;
+ } else if (definition != null) {
+ explict = true;
+ constructor = definition.getConstructor();
+ } else {
+ if (!isImplementationJava(type)) {
+ // FIXME: [rfeng] Don't process the constructors for non implementation.java types
+ return;
+ }
+ // no definition, heuristically determine constructor
+ Constructor[] constructors = clazz.getConstructors();
+ if (constructors.length == 0) {
+ throw new NoConstructorException("[JCI50001] No public constructor for class :" + type.getName());
+ } else if (constructors.length == 1) {
+ // Only one constructor, take it
+ constructor = constructors[0];
+ } else {
+ Constructor<T> selected = null;
+ for (Constructor<T> ctor : constructors) {
+ if (allArgsAnnotated(ctor)) {
+ selected = ctor;
+ for (Constructor<T> ctor2 : constructors) {
+ if (selected != ctor2 && allArgsAnnotated(ctor2)) {
+ throw new InvalidConstructorException("[JCI50005] Multiple annotated constructors for class :" + type.getName());
+ }
+ }
+ }
+ }
+ if (selected == null) {
+ for (Constructor<T> ctor : constructors) {
+ if (ctor.getParameterTypes().length == 0) {
+ selected = ctor;
+ break;
+ }
+ }
+ }
+ if (selected == null) {
+ throw new NoConstructorException();
+ }
+ constructor = selected;
+ definition = type.getConstructors().get(selected);
+ type.setConstructor(definition);
+ }
+ definition = type.getConstructors().get(constructor);
+ type.setConstructor(definition);
+ }
+ JavaParameterImpl[] parameters = definition.getParameters();
+ if (parameters.length == 0) {
+ return;
+ }
+ Map<String, JavaElementImpl> props = type.getPropertyMembers();
+ Map<String, JavaElementImpl> refs = type.getReferenceMembers();
+ Annotation[][] annotations = constructor.getParameterAnnotations();
+ if (!explict) {
+ // the constructor wasn't defined by an annotation, so check to see
+ // if any of the params have an annotation
+ // which we can impute as explicitly defining the constructor, e.g.
+ // @Property, @Reference, or @Autowire
+ explict = injectionAnnotationsPresent(annotations);
+ }
+ if (explict) {
+ for (int i = 0; i < parameters.length; i++) {
+ if (isAnnotated(parameters[i])) {
+ continue;
+ } else if (!findReferenceOrProperty(parameters[i], props, refs)) {
+ throw new AmbiguousConstructorException(parameters[i].toString());
+ }
+ }
+ } else {
+ if (!areUnique(parameters)) {
+ throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor");
+ }
+ if (!calcPropRefUniqueness(props.values(), refs.values())) {
+ throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor");
+ }
+ if (!(props.isEmpty() && refs.isEmpty())) {
+ calcParamNames(parameters, props, refs);
+ } else {
+ heuristicParamNames(type, parameters);
+
+ }
+ }
+ }
+
+ private boolean allArgsAnnotated(Constructor<?> ctor) {
+ if (ctor.getParameterTypes().length < 1) {
+ return false;
+ }
+ for (Annotation[] as : ctor.getParameterAnnotations()) {
+ if (as.length < 1) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void calcParamNames(JavaParameterImpl[] parameters,
+ Map<String, JavaElementImpl> props,
+ Map<String, JavaElementImpl> refs) throws AmbiguousConstructorException {
+ // the constructor param types must unambiguously match defined
+ // reference or property types
+ for (JavaParameterImpl param : parameters) {
+ if (!findReferenceOrProperty(param, props, refs)) {
+ throw new AmbiguousConstructorException(param.getName());
+ }
+ }
+ }
+
+ private void heuristicParamNames(JavaImplementation type, JavaParameterImpl[] parameters)
+ throws IntrospectionException {
+ // heuristically determine refs and props from the parameter types
+ for (JavaParameterImpl p : parameters) {
+ String name = p.getType().getSimpleName().toLowerCase();
+ if (isReferenceType(p.getType(), p.getGenericType())) {
+ type.getReferences().add(createReference(name, p.getType(), p.getGenericType()));
+ p.setClassifer(Reference.class);
+ type.getReferenceMembers().put(name, p);
+ } else {
+ type.getProperties().add(createProperty(name, p.getType(), p.getGenericType()));
+ p.setClassifer(Property.class);
+ type.getPropertyMembers().put(name, p);
+ }
+ p.setName(name);
+ }
+ }
+
+
+
+ /**
+ * Returns true if the union of the given collections of properties and
+ * references have unique Java types
+ */
+ private boolean calcPropRefUniqueness(Collection<JavaElementImpl> props, Collection<JavaElementImpl> refs) {
+
+ Class<?>[] classes = new Class[props.size() + refs.size()];
+ int i = 0;
+ for (JavaElementImpl property : props) {
+ classes[i] = property.getType();
+ i++;
+ }
+ for (JavaElementImpl reference : refs) {
+ classes[i] = reference.getType();
+ i++;
+ }
+ return areUnique(classes);
+ }
+
+ /**
+ * Unambiguously finds the reference or property associated with the given
+ * type
+ *
+ * @return the name of the reference or property if found, null if not
+ * @throws AmbiguousConstructorException if the constructor parameter cannot
+ * be resolved to a property or reference
+ */
+ private boolean findReferenceOrProperty(JavaParameterImpl parameter,
+ Map<String, JavaElementImpl> props,
+ Map<String, JavaElementImpl> refs) throws AmbiguousConstructorException {
+
+ boolean found = false;
+ if (!"".equals(parameter.getName())) {
+ // Match by name
+ JavaElementImpl prop = props.get(parameter.getName());
+ if (prop != null && prop.getType() == parameter.getType()) {
+ parameter.setClassifer(Property.class);
+ return true;
+ }
+ JavaElementImpl ref = refs.get(parameter.getName());
+ if (ref != null && ref.getType() == parameter.getType()) {
+ parameter.setClassifer(Reference.class);
+ return true;
+ }
+ }
+ for (JavaElementImpl property : props.values()) {
+ if (property.getType() == parameter.getType()) {
+ if (found) {
+ throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type",
+ (Member)parameter.getAnchor());
+ }
+ parameter.setClassifer(Property.class);
+ parameter.setName(property.getName());
+ found = true;
+ // do not break since ambiguities must be checked, i.e. more
+ // than one prop or ref of the same type
+ }
+ }
+ for (JavaElementImpl reference : refs.values()) {
+ if (reference.getType() == parameter.getType()) {
+ if (found) {
+ throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type",
+ (Member)parameter.getAnchor());
+ }
+ parameter.setClassifer(Reference.class);
+ parameter.setName(reference.getName());
+ found = true;
+ // do not break since ambiguities must be checked, i.e. more
+ // than one prop or ref of the same type
+ }
+ }
+ return found;
+ }
+
+ /**
+ * Creates a mapped property.
+ *
+ * @param name the property name
+ * @param paramType the property type
+ */
+ private org.apache.tuscany.sca.assembly.Property createProperty(String name, Class<?> javaClass, Type genericType) {
+ return AbstractPropertyProcessor.createProperty(assemblyFactory, name, javaClass, genericType);
+ }
+
+ private org.apache.tuscany.sca.assembly.Reference createReference(String name, Class<?> paramType,
+ Type genericType )
+ throws IntrospectionException {
+ org.apache.tuscany.sca.assembly.Reference reference = assemblyFactory.createReference();
+ reference.setName(name);
+ JavaInterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
+ reference.setInterfaceContract(interfaceContract);
+ // Compute the interface type dealing with array/Collection types and with Generic types
+ Class<?> baseType = getBaseType(paramType, genericType);
+ if (ServiceReference.class.isAssignableFrom(baseType)) {
+ if (Collection.class.isAssignableFrom(paramType)) {
+ genericType = JavaIntrospectionHelper.getParameterType(genericType);
+ }
+ baseType = JavaIntrospectionHelper.getBusinessInterface(baseType, genericType);
+ } // end if
+ try {
+ JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(baseType);
+
+ reference.getInterfaceContract().setInterface(callInterface);
+ if (callInterface.getCallbackClass() != null) {
+ JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(callInterface.getCallbackClass());
+ reference.getInterfaceContract().setCallbackInterface(callbackInterface);
+ }
+ // Multiplicity of an implicit reference is 1..1 for a simple interface type
+ // and 1..n for an array of interface or Collection of interface type
+ // as defined in the OASIS SCA Java POJO specification, section 8.1 : TUSCANY-3636
+ if( isCollectionType( paramType ) || isArrayType( paramType )) {
+ reference.setMultiplicity(Multiplicity.ONE_N);
+ } else {
+ reference.setMultiplicity(Multiplicity.ONE_ONE);
+ } // end if
+ } catch (InvalidInterfaceException e1) {
+ throw new IntrospectionException(e1);
+ } // end try
+
+ // FIXME: This part seems to have already been taken care above!!
+ try {
+ processCallback(paramType, reference);
+ } catch (InvalidServiceTypeException e) {
+ throw new IntrospectionException(e);
+ }
+ return reference;
+ }
+
+ /**
+ * Reports if a parameter type is a form of java.util.Collection
+ * @param paramType
+ * @return true if paramType is a form of java.util.Collection, false otherwise
+ */
+ private boolean isCollectionType( Class<?> paramType ) {
+ if( Collection.class.isAssignableFrom(paramType) ) return true;
+ return false;
+ }
+
+ /**
+ * Reports if a parameter type is an array
+ * @param paramType
+ * @return true if paramType is an array
+ */
+ private boolean isArrayType( Class<?> paramType ) {
+ if( paramType.isArray() ) return true;
+ return false;
+ }
+
+ private org.apache.tuscany.sca.assembly.Service createService(Class<?> interfaze) throws InvalidInterfaceException {
+ org.apache.tuscany.sca.assembly.Service service = assemblyFactory.createService();
+ service.setName(interfaze.getSimpleName());
+
+ JavaInterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
+ service.setInterfaceContract(interfaceContract);
+
+ JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(interfaze);
+ service.getInterfaceContract().setInterface(callInterface);
+ if (callInterface.getCallbackClass() != null) {
+ JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(callInterface.getCallbackClass());
+ service.getInterfaceContract().setCallbackInterface(callbackInterface);
+ }
+
+ Interface javaInterface = service.getInterfaceContract().getInterface();
+ javaInterface.setRemotable(interfaze.getAnnotation(Remotable.class) != null);
+ service.getInterfaceContract().setInterface(javaInterface);
+ return service;
+ }
+
+ private void processCallback(Class<?> interfaze, Contract contract) throws InvalidServiceTypeException {
+ Callback callback = interfaze.getAnnotation(Callback.class);
+ if (callback != null && !Void.class.equals(callback.value())) {
+ Class<?> callbackClass = callback.value();
+ JavaInterface javaInterface;
+ try {
+ javaInterface = javaInterfaceFactory.createJavaInterface(callbackClass);
+ contract.getInterfaceContract().setCallbackInterface(javaInterface);
+ } catch (InvalidInterfaceException e) {
+ throw new InvalidServiceTypeException("Invalid callback interface "+callbackClass, interfaze);
+ }
+ } else if (callback != null && Void.class.equals(callback.value())) {
+ throw new InvalidServiceTypeException("No callback interface specified on annotation", interfaze);
+ }
+ }
+
+
+ /**
+ * Utility methods
+ */
+
+
+ /**
+ * Verify if the method is a public setter
+ * @param method
+ * @return
+ */
+ private static boolean isPublicSetter(Method method) {
+ return method.getParameterTypes().length == 1 && Modifier.isPublic(method.getModifiers())
+ && method.getName().startsWith("set")
+ && method.getReturnType() == void.class;
+ }
+
+ /**
+ * Verify if the method is a protected setter
+ * @param method
+ * @return
+ */
+ private static boolean isProtectedSetter(Method method) {
+ return method.getParameterTypes().length == 1 && Modifier.isProtected(method.getModifiers())
+ && method.getName().startsWith("set")
+ && method.getReturnType() == void.class;
+ }
+
+ /**
+ * @param collection
+ * @return
+ */
+ private static boolean areUnique(Class<?>[] collection) {
+ Set<Class<?>> set = new HashSet<Class<?>>(Arrays.asList(collection));
+ return set.size() == collection.length;
+ }
+
+ /**
+ * Returns true if a given type is reference according to the SCA
+ * specification rules for determining reference types The following rules
+ * are used to determine whether an unannotated field or setter method is a
+ * property or reference:
+ * <ol>
+ * <li>If its type is simple, then it is a property.
+ * <li>If its type is complex, then if the type is an interface marked by
+ *
+ * @Remotable, then it is a reference; otherwise, it is a property.
+ * <li>Otherwise, if the type associated with the member is an
+ * array or a java.util.Collection, the basetype is the element
+ * type of the array or the parameterized type of the
+ * Collection; otherwise the basetype is the member type. If the
+ * basetype is an interface with an
+ * @Remotable or
+ * @Service annotation then the member is defined as a reference. Otherwise,
+ * it is defined as a property.
+ * </ol>
+ * <p>
+ * The name of the reference or of the property is derived from the
+ * name found on the setter method or on the field.
+ */
+ // FIXME: [rfeng] What if it's a collection of references?
+ private static boolean isReferenceType(Class<?> cls, Type genericType) {
+ Class<?> baseType = JavaIntrospectionHelper.getBaseType(cls, genericType);
+ return baseType.isInterface() && baseType.isAnnotationPresent(Remotable.class);
+ }
+
+ /**
+ * Returns true if the given operation is defined in the collection of
+ * service interfaces
+ * @param operation
+ * @param services
+ * @return
+ */
+ private static boolean isInServiceInterface(Method operation, List<org.apache.tuscany.sca.assembly.Service> services) {
+ for (org.apache.tuscany.sca.assembly.Service service : services) {
+ Interface interface1 = service.getInterfaceContract().getInterface();
+ if (interface1 instanceof JavaInterface) {
+ Class<?> clazz = ((JavaInterface)interface1).getJavaClass();
+ if (isMethodMatched(clazz, operation)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test if the class declares a method which matches the signature of the
+ * given method
+ *
+ * @param clazz
+ * @param method
+ * @return
+ */
+ private static boolean isMethodMatched(Class<?> clazz, Method method) {
+ if (method.getDeclaringClass() == clazz) {
+ return true;
+ }
+ Method[] methods = clazz.getMethods();
+ for (Method m : methods) {
+ if (JavaIntrospectionHelper.exactMethodMatch(method, m)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Verify if there is any SCA annotation on the parameter
+ * @param parameter
+ * @return
+ */
+ private static boolean isAnnotated(JavaParameterImpl parameter) {
+ for (Annotation annotation : parameter.getAnnotations()) {
+ if (isSCAAnnotation(annotation)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Verify if the parameters are unique
+ * @param parameters
+ * @return
+ */
+ private static boolean areUnique(JavaParameterImpl[] parameters) {
+ Set<Class<?>> set = new HashSet<Class<?>>(parameters.length);
+ for (JavaParameterImpl p : parameters) {
+ if (!set.add(p.getType())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Verify if the annotations are SCA annotation
+ * @param annots
+ * @return
+ */
+ private static boolean injectionAnnotationsPresent(Annotation[][] annots) {
+ for (Annotation[] annotations : annots) {
+ for (Annotation annotation : annotations) {
+ Class<? extends Annotation> annotType = annotation.annotationType();
+ if (annotType == Property.class || annotType == Reference.class
+ || annotType == Resource.class
+ || annotType == ComponentName.class
+ || annotType == Context.class
+ || annotType == Callback.class) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalCallbackReferenceException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalCallbackReferenceException.java
new file mode 100644
index 0000000000..badd41fbb9
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalCallbackReferenceException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 java.lang.reflect.Member;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an illegal use of {@link org.oasisopen.sca.annotation.Callback} on a reference
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalCallbackReferenceException extends IntrospectionException {
+ private static final long serialVersionUID = -8932525723147700591L;
+
+ public IllegalCallbackReferenceException(String message) {
+ super(message);
+ }
+
+ public IllegalCallbackReferenceException(String message, Member member) {
+ super(message, member);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalContextException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalContextException.java
new file mode 100644
index 0000000000..fa1e67a336
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalContextException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 java.lang.reflect.Member;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an illegal signature for a method decorated with {@link org.oasisopen.sca.annotation.Context}
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalContextException extends IntrospectionException {
+ private static final long serialVersionUID = -6946383136750117008L;
+
+ public IllegalContextException(String message) {
+ super(message);
+ }
+
+ public IllegalContextException(String message, Member member) {
+ super(message, member);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalDestructorException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalDestructorException.java
new file mode 100644
index 0000000000..0c4c3d5646
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalDestructorException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 java.lang.reflect.Member;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an illegal signature for a method decorated with {@link org.oasisopen.sca.annotation.Destroy}
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalDestructorException extends IntrospectionException {
+ private static final long serialVersionUID = 365719353107446326L;
+
+ public IllegalDestructorException(String message) {
+ super(message);
+ }
+
+ public IllegalDestructorException(String message, Member member) {
+ super(message, member);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalInitException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalInitException.java
new file mode 100644
index 0000000000..2956b60b65
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalInitException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 java.lang.reflect.Member;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an illegal signature for a method decorated with {@link @org.oasisopen.sca.annotation.Init}
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalInitException extends IntrospectionException {
+ private static final long serialVersionUID = -3690763271986854701L;
+
+ public IllegalInitException(String message) {
+ super(message);
+ }
+
+ public IllegalInitException(String message, Member member) {
+ super(message, member);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalPropertyException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalPropertyException.java
new file mode 100644
index 0000000000..54f7dfad1e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalPropertyException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 java.lang.reflect.Member;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an illegal property definition in a component type
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalPropertyException extends IntrospectionException {
+ private static final long serialVersionUID = -2836849110706758494L;
+
+ public IllegalPropertyException(String message) {
+ super(message);
+ }
+
+ public IllegalPropertyException(String message, Member member) {
+ super(message, member);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalReferenceException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalReferenceException.java
new file mode 100644
index 0000000000..25196c56e5
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalReferenceException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 java.lang.reflect.Member;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an illegal reference definition in a component type
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalReferenceException extends IntrospectionException {
+ private static final long serialVersionUID = 4612984122225271395L;
+
+ public IllegalReferenceException(String message) {
+ super(message);
+ }
+
+ public IllegalReferenceException(String message, Member member) {
+ super(message, member);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalResourceException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalResourceException.java
new file mode 100644
index 0000000000..ccfbaf0043
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalResourceException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 java.lang.reflect.Member;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an illegal resource definition in a component type
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalResourceException extends IntrospectionException {
+ private static final long serialVersionUID = -1100936539412435579L;
+
+ public IllegalResourceException(String message) {
+ super(message);
+ }
+
+ public IllegalResourceException(String message, Member member) {
+ super(message, member);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalServiceDefinitionException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalServiceDefinitionException.java
new file mode 100644
index 0000000000..e0f90779a1
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/IllegalServiceDefinitionException.java
@@ -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.tuscany.sca.implementation.java.introspect.impl;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an illegal use of the {@link @org.oasisopen.sca.annotation.Service} annotation
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalServiceDefinitionException extends IntrospectionException {
+ private static final long serialVersionUID = -7151534258405092548L;
+
+ public IllegalServiceDefinitionException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InitProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InitProcessor.java
new file mode 100644
index 0000000000..a5227fc4f5
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InitProcessor.java
@@ -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.tuscany.sca.implementation.java.introspect.impl;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.oasisopen.sca.annotation.Init;
+
+/**
+ * Processes the {@link @Init} annotation on a component implementation and
+ * updates the component type with the decorated initializer method
+ *
+ * @version $Rev$ $Date$
+ */
+public class InitProcessor extends BaseJavaClassVisitor {
+
+ public InitProcessor(AssemblyFactory factory) {
+ super(factory);
+ }
+
+ public InitProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+ Init annotation = method.getAnnotation(Init.class);
+ if (annotation == null) {
+ return;
+ }
+ if (method.getParameterTypes().length != 0) {
+ throw new IllegalInitException("[JCA90008] Initializer must not have argments", method);
+ }
+ if(!method.getReturnType().equals(void.class)) {
+ throw new IllegalInitException("Initializer must return void.", method);
+ }
+ if (type.getInitMethod() != null) {
+ throw new DuplicateInitException("More than one initializer found on implementaton");
+ }
+ if (!Modifier.isPublic(method.getModifiers())) {
+ throw new IllegalInitException("Initializer must be a public method. Invalid annotation @Init found on "+method);
+ }
+ type.setInitMethod(method);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidConstructorException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidConstructorException.java
new file mode 100644
index 0000000000..c75dfdaf46
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidConstructorException.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an invalid constructor definition, e.g. when the number of injection names specified in {@link
+ * org.oasisopen.sca.annotation.Constructor} do not match the number of actual constructor parameters
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidConstructorException extends IntrospectionException {
+ private static final long serialVersionUID = 1411492435210741512L;
+
+ public InvalidConstructorException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidConversationalImplementationException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidConversationalImplementationException.java
new file mode 100644
index 0000000000..079495e4db
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidConversationalImplementationException.java
@@ -0,0 +1,39 @@
+/*
+ * 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 org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Raised when an implementation specifies improper conversational metadata
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidConversationalImplementationException extends IntrospectionException {
+ private static final long serialVersionUID = -5487291552769408149L;
+
+ public InvalidConversationalImplementationException(String message) {
+ super(message);
+ }
+
+ public InvalidConversationalImplementationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidPropertyException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidPropertyException.java
new file mode 100644
index 0000000000..429b88aa1f
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidPropertyException.java
@@ -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.tuscany.sca.implementation.java.introspect.impl;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an invalid usage of {@link org.oasisopen.sca.annotation.Property}
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidPropertyException extends IntrospectionException {
+ private static final long serialVersionUID = -2682862652069727948L;
+
+ public InvalidPropertyException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidReferenceException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidReferenceException.java
new file mode 100644
index 0000000000..fbf3fc9ed3
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidReferenceException.java
@@ -0,0 +1,42 @@
+/*
+ * 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 org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an invalid usage of {@link org.oasisopen.sca.annotation.Reference}
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidReferenceException extends IntrospectionException {
+ private static final long serialVersionUID = -3285246635989254165L;
+
+ public InvalidReferenceException(String message) {
+ super(message);
+ }
+
+ public InvalidReferenceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidReferenceException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidResourceException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidResourceException.java
new file mode 100644
index 0000000000..debb5cbacc
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidResourceException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 java.lang.reflect.Member;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Denotes an invalid usage of {@link @org.apache.tuscany.api.annotation.Resource}
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidResourceException extends IntrospectionException {
+ private static final long serialVersionUID = 511728001735534934L;
+
+ public InvalidResourceException(String message) {
+ super(message);
+ }
+
+ public InvalidResourceException(String message, Member member) {
+ super(message, member);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidServiceTypeException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidServiceTypeException.java
new file mode 100644
index 0000000000..230c8c6fdd
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/InvalidServiceTypeException.java
@@ -0,0 +1,48 @@
+/*
+ * 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 org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Thrown when a service type specified by an {@link org.oasisopen.sca.annotation.Service} annotation is invalid, e.g. it is
+ * not an interface
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidServiceTypeException extends IntrospectionException {
+ private static final long serialVersionUID = -1076466639416644386L;
+ private Class<?> serviceType;
+
+ public InvalidServiceTypeException(String message) {
+ super(message);
+ }
+
+ public InvalidServiceTypeException(String message, Class<?> clazz) {
+ super(message);
+ this.serviceType = clazz;
+ }
+
+ /**
+ * @return the serviceType
+ */
+ public Class<?> getServiceType() {
+ return serviceType;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JAXWSProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JAXWSProcessor.java
new file mode 100644
index 0000000000..0db8a96229
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JAXWSProcessor.java
@@ -0,0 +1,337 @@
+/*
+ * 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 java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import javax.jws.WebParam;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.xml.ws.BindingType;
+import javax.xml.ws.ServiceMode;
+import javax.xml.ws.WebServiceProvider;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.xml.Constants;
+import org.apache.tuscany.sca.binding.ws.WebServiceBinding;
+import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory;
+import org.apache.tuscany.sca.binding.ws.xml.WebServiceConstants;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract;
+import org.apache.tuscany.sca.policy.ExtensionType;
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.PolicySubject;
+
+/**
+ * Process JAXWS annotations and updates the component type accordingly
+ *
+ */
+public class JAXWSProcessor extends BaseJavaClassVisitor {
+
+ private PolicyFactory policyFactory;
+ private WSDLFactory wsdlFactory;
+ private WebServiceBindingFactory wsBindingFactory;
+
+ public JAXWSProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.wsdlFactory = factories.getFactory(WSDLFactory.class);
+ this.assemblyFactory = factories.getFactory(AssemblyFactory.class);
+ this.policyFactory = factories.getFactory(PolicyFactory.class);
+ this.javaInterfaceFactory = factories.getFactory(JavaInterfaceFactory.class);
+ this.wsBindingFactory = factories.getFactory(WebServiceBindingFactory.class);
+ }
+
+ @Override
+ public <T> void visitClass(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+
+ boolean hasJaxwsAnnotation = false;
+
+ // Process @ServiceMode annotation - JCA 11013
+ if ( clazz.getAnnotation(ServiceMode.class) != null ) {
+ addSOAPIntent(type);
+ hasJaxwsAnnotation = true;
+ }
+
+ // Process @WebService annotation - POJO_8029, POJO_8030
+ WebService webServiceAnnotation = clazz.getAnnotation(WebService.class);
+ org.oasisopen.sca.annotation.Service serviceAnnotation = clazz.getAnnotation(org.oasisopen.sca.annotation.Service.class);
+
+ if (webServiceAnnotation != null &&
+ serviceAnnotation == null) {
+ String serviceName = clazz.getSimpleName();
+ serviceName = getValue(webServiceAnnotation.name(), serviceName);
+
+ String serviceInterfaceClassName = webServiceAnnotation.endpointInterface();
+
+ String wsdlLocation = webServiceAnnotation.wsdlLocation();
+
+ try {
+ createService(type, clazz, serviceName, serviceInterfaceClassName, wsdlLocation, false);
+ } catch (InvalidInterfaceException e) {
+ throw new IntrospectionException(e);
+ }
+ hasJaxwsAnnotation = true;
+ }
+
+ // Process @WebServiceProvider annotation - JCA_11015, POJO_8034
+ WebServiceProvider webServiceProviderAnnotation = clazz.getAnnotation(WebServiceProvider.class);
+ if (webServiceProviderAnnotation != null) {
+ // if the implmentation already has a service set, use it's name
+ // and the new service, which uses the implementation as an interface,
+ // will be replaced
+ String serviceName = clazz.getSimpleName();
+
+ if (type.getServices().size() > 0){
+ serviceName = ((Service)type.getServices().get(0)).getName();
+ }
+
+ // the annotation may specify a service name
+ serviceName = getValue(webServiceProviderAnnotation.serviceName(), serviceName);
+
+ String wsdlLocation = webServiceProviderAnnotation.wsdlLocation();
+
+ // Make sure that there is a service with an interface
+ // based on the implementation class and have it replace
+ // any service with the same name
+ try {
+ createService(type, clazz, serviceName, null, wsdlLocation, true);
+ } catch (InvalidInterfaceException e) {
+ throw new IntrospectionException(e);
+ }
+
+ // Make sure all service references are remotable
+ for ( Service service : type.getServices() ) {
+ service.getInterfaceContract().getInterface().setRemotable(true);
+ }
+
+ hasJaxwsAnnotation = true;
+ }
+
+ // Process @WebParam and @WebResult annotations - POJO_8031, POJO_8032
+ Class<?> interfaze = clazz;
+ Method[] implMethods = interfaze.getDeclaredMethods();
+ for ( Service service : type.getServices() ) {
+ JavaInterface javaInterface = (JavaInterface)service.getInterfaceContract().getInterface();
+ interfaze = javaInterface.getJavaClass();
+
+ if (interfaze == null){
+ // this interface has come from an @WebService enpointInterface annotation
+ // so hasn't been resolved. Use the implementation class as the interface
+ interfaze = clazz;
+ }
+
+ boolean hasHeaderParam = false;
+ for (Method method : interfaze.getDeclaredMethods()){
+ // find the impl method for this service method
+ for (int i = 0; i < implMethods.length; i++){
+ Method implMethod = implMethods[i];
+ if (implMethod.getName().equals(method.getName())){
+ for (int j = 0; j < implMethod.getParameterTypes().length; j++) {
+ WebParam webParamAnnotation = getParameterAnnotation(implMethod, j, WebParam.class);
+ if (webParamAnnotation != null &&
+ webParamAnnotation.header()) {
+ hasHeaderParam = true;
+ break;
+ }
+ }
+
+ WebResult webResultAnnotation = implMethod.getAnnotation(WebResult.class);
+ if (webResultAnnotation != null &&
+ webResultAnnotation.header()){
+ hasHeaderParam = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (hasHeaderParam){
+ // Add a SOAP intent to the service
+ addSOAPIntent(service);
+ hasJaxwsAnnotation = true;
+ }
+ }
+
+ // Process @SOAPBinding annotation - POJO_8033
+ if ( clazz.getAnnotation(SOAPBinding.class) != null ) {
+ // If the implementation is annotated with @SOAPBinding,
+ // give all services a SOAP intent
+ for ( Service service : type.getServices() ) {
+ addSOAPIntent(service);
+ }
+ hasJaxwsAnnotation = true;
+ }
+
+
+ // Process @BindingType annotation - POJO_8037
+ BindingType bindingType = clazz.getAnnotation(BindingType.class);
+
+ if ( bindingType != null ) {
+ String bindingTypeValue = bindingType.value();
+ for ( Service service : type.getServices() ) {
+ addBindingTypeIntent(service, bindingTypeValue);
+ }
+ hasJaxwsAnnotation = true;
+ }
+
+ if (hasJaxwsAnnotation == true){
+ // Note that services are based on JAXWS annotations in case
+ // we need to know later. Add a ws binding and a JAXWS annotation
+ // implies a WS binding
+ for ( Service service : type.getServices() ) {
+ service.setJAXWSService(true);
+ createWSBinding(type, service);
+ }
+ }
+
+
+
+ }
+
+ private void addBindingTypeIntent(PolicySubject subject,
+ String bindingTypeValue) {
+
+ Intent soapIntent = policyFactory.createIntent();
+ if ( javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING.equals(bindingTypeValue)) {
+ soapIntent.setName(Constants.SOAP11_INTENT);
+ } else if ( javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING.equals(bindingTypeValue)) {
+ soapIntent.setName(Constants.SOAP12_INTENT);
+ } else {
+ soapIntent.setName(Constants.SOAP11_INTENT);
+ }
+
+ subject.getRequiredIntents().add(soapIntent);
+
+ }
+
+ /**
+ * Utility methods
+ */
+
+ private static String getValue(String value, String defaultValue) {
+ return "".equals(value) ? defaultValue : value;
+ }
+
+ private Service createService(JavaImplementation type, Class<?> clazz, String serviceName, String javaInterfaceName, String wsdlFileName, boolean replace) throws InvalidInterfaceException, IntrospectionException {
+ Service service = assemblyFactory.createService();
+
+ if (serviceName != null) {
+ service.setName(serviceName);
+ } else if (javaInterfaceName != null){
+ service.setName(javaInterfaceName.substring(javaInterfaceName.lastIndexOf('.')));
+ }
+
+ // create the physical Java interface contract
+ JavaInterfaceContract javaInterfaceContract = javaInterfaceFactory.createJavaInterfaceContract();;
+ service.setInterfaceContract(javaInterfaceContract);
+
+ if (javaInterfaceName != null &&
+ javaInterfaceName.length() > 0){
+ JavaInterface callInterface = javaInterfaceFactory.createJavaInterface();
+ callInterface.setName(javaInterfaceName);
+ callInterface.setRemotable(true);
+ callInterface.setUnresolved(true);
+ javaInterfaceContract.setInterface(callInterface);
+ } else {
+ // we use the bean class as the service interface
+ JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(clazz);
+ callInterface.setRemotable(true);
+ callInterface.setUnresolved(false); // this will already be false but this makes it easy to follow the logic
+ javaInterfaceContract.setInterface(callInterface);
+ }
+
+ // create the logical WSDL interface if it's specified in
+ // the @WebService annotation
+ if (wsdlFileName != null &&
+ wsdlFileName.length() > 0){
+ WSDLInterface callInterface = wsdlFactory.createWSDLInterface();
+ callInterface.setUnresolved(true);
+ callInterface.setRemotable(true);
+
+ WSDLInterfaceContract wsdlInterfaceContract = wsdlFactory.createWSDLInterfaceContract();
+ wsdlInterfaceContract.setInterface(callInterface);
+ wsdlInterfaceContract.setLocation(wsdlFileName);
+ javaInterfaceContract.setNormalizedWSDLContract(wsdlInterfaceContract);
+ }
+
+ // add the service model into the implementation type
+ Service serviceAlreadyPresent = null;
+ for (Service typeService : type.getServices()){
+ if (typeService.getName().equals(service.getName())){
+ serviceAlreadyPresent = typeService;
+ break;
+ }
+ }
+
+ if (replace == true){
+ type.getServices().remove(serviceAlreadyPresent);
+ type.getServices().add(service);
+ } else {
+ if (serviceAlreadyPresent == null){
+ type.getServices().add(service);
+ }
+ }
+
+ return service;
+ }
+
+ private <T extends Annotation> T getParameterAnnotation(Method method, int index, Class<T> annotationType) {
+ Annotation[] annotations = method.getParameterAnnotations()[index];
+ for (Annotation annotation : annotations) {
+ if (annotation.annotationType() == annotationType) {
+ return annotationType.cast(annotation);
+ }
+ }
+ return null;
+ }
+
+ private void addSOAPIntent(PolicySubject policySubject){
+ Intent soapIntent = policyFactory.createIntent();
+ soapIntent.setName(Constants.SOAP_INTENT);
+ policySubject.getRequiredIntents().add(soapIntent);
+ }
+
+ private void createWSBinding(JavaImplementation javaImplementation, Service service){
+ if(service.getBindings().size() == 0){
+ WebServiceBinding wsBinding = wsBindingFactory.createWebServiceBinding();
+ wsBinding.setName(service.getName());
+ ExtensionType bindingType = policyFactory.createBindingType();
+ bindingType.setType(WebServiceConstants.BINDING_WS_QNAME);
+ bindingType.setUnresolved(true);
+ ((PolicySubject)wsBinding).setExtensionType(bindingType);
+ service.getBindings().add(wsBinding);
+ }
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/NoConstructorException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/NoConstructorException.java
new file mode 100644
index 0000000000..453cfa35fe
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/NoConstructorException.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.tuscany.sca.implementation.java.introspect.impl;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Thrown when a suitable constructor for a component implementation cannot be found
+ *
+ * @version $Rev$ $Date$
+ */
+public class NoConstructorException extends IntrospectionException {
+ private static final long serialVersionUID = 3086706387280694424L;
+
+ public NoConstructorException() {
+ }
+
+ public NoConstructorException(String message) {
+ super(message);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/PolicyProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/PolicyProcessor.java
new file mode 100644
index 0000000000..1c7ae6d0d7
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/PolicyProcessor.java
@@ -0,0 +1,307 @@
+/*
+ * 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 java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+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.JavaParameterImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.PolicySet;
+import org.apache.tuscany.sca.policy.PolicySubject;
+import org.oasisopen.sca.ServiceRuntimeException;
+import org.oasisopen.sca.annotation.PolicySets;
+import org.oasisopen.sca.annotation.Qualifier;
+import org.oasisopen.sca.annotation.Requires;
+
+/**
+ * Processes an {@link org.oasisopen.sca.annotation.Requires} annotation
+ *
+ * @version $Rev$ $Date$
+ */
+public class PolicyProcessor extends BaseJavaClassVisitor {
+
+ private PolicyFactory policyFactory;
+
+ public PolicyProcessor(AssemblyFactory assemblyFactory,
+ PolicyFactory policyFactory,
+ JavaInterfaceFactory javaInterfaceFactory) {
+ super(assemblyFactory);
+ this.policyFactory = policyFactory;
+ this.javaInterfaceFactory = javaInterfaceFactory;
+ }
+
+ public PolicyProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.policyFactory = factories.getFactory(PolicyFactory.class);
+ }
+
+ @Override
+ public <T> void visitClass(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+
+ // Read intents on the Java implementation class
+ readPolicySetAndIntents((PolicySubject)type, clazz);
+
+ // Find the business methods in the implementation class for all services
+ // this operation collection will have policy added to it relating to JSR250 annotations
+ Set<Method> methods = new HashSet<Method>();
+ for (Service service : type.getServices()) {
+ for (Operation op : service.getInterfaceContract().getInterface().getOperations()) {
+ Method method;
+ try {
+ method = JavaInterfaceUtil.findMethod(clazz, op);
+ } catch (NoSuchMethodException e1) {
+ throw new IntrospectionException(e1);
+ }
+ if (method != null) {
+ methods.add(method);
+ }
+ }
+ }
+ for (Method method : methods) {
+ JavaOperation op = javaInterfaceFactory.createJavaOperation(method);
+ type.getOperations().add(op);
+ }
+
+ /* In OASIS we don't generally read policy attached to arbitrary methods
+ * unless they relate to references
+ // Read the operation-level policy settings for the implementation
+ for (Operation op : type.getOperations()) {
+ JavaOperation operation = (JavaOperation)op;
+ PolicySubject subject = op;
+ Method method = operation.getJavaMethod();
+ if (subject != null) {
+ readPolicySetAndIntents(subject, method);
+ }
+ }
+ */
+
+ // Start to process annotations on the reference members
+ Map<String, Reference> referenceMap = new HashMap<String, Reference>();
+ for (Reference ref : type.getReferences()) {
+ referenceMap.put(ref.getName(), ref);
+ }
+ Map<String, JavaElementImpl> members = type.getReferenceMembers();
+ for (Map.Entry<String, JavaElementImpl> e : members.entrySet()) {
+ Reference reference = referenceMap.get(e.getKey());
+ readPolicySetAndIntents(reference, e.getValue().getAnchor());
+ }
+ }
+
+ private void readPolicySetAndIntents(PolicySubject subject, AnnotatedElement element) {
+ readIntents(element.getAnnotation(Requires.class), subject.getRequiredIntents());
+ readSpecificIntents(element.getAnnotations(), subject.getRequiredIntents());
+ readPolicySets(element.getAnnotation(PolicySets.class), subject.getPolicySets());
+ }
+
+ private void readPolicySetAndIntents(PolicySubject subject, JavaElementImpl element) {
+ readIntents(element.getAnnotation(Requires.class), subject.getRequiredIntents());
+ readSpecificIntents(element.getAnnotations(), subject.getRequiredIntents());
+ readPolicySets(element.getAnnotation(PolicySets.class), subject.getPolicySets());
+ }
+
+ private void readSpecificIntents(Annotation[] annotations, List<Intent> requiredIntents) {
+ for (Annotation a : annotations) {
+ org.oasisopen.sca.annotation.Intent intentAnnotation =
+ a.annotationType().getAnnotation(org.oasisopen.sca.annotation.Intent.class);
+ if (intentAnnotation == null) {
+ continue;
+ }
+ QName qname = null;
+ String value = intentAnnotation.value();
+ if (!value.equals("")) {
+ qname = getQName(value);
+ } else {
+ qname = new QName(intentAnnotation.targetNamespace(), intentAnnotation.localPart());
+ }
+ Set<String> qualifiers = new HashSet<String>();
+ for (Method m : a.annotationType().getMethods()) {
+ Qualifier qualifier = m.getAnnotation(Qualifier.class);
+ if (qualifier != null && m.getReturnType() == String[].class) {
+ try {
+ qualifiers.addAll(Arrays.asList((String[])m.invoke(a)));
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ qualifiers.remove("");
+ if (qualifiers.isEmpty()) {
+ Intent intent = policyFactory.createIntent();
+ intent.setUnresolved(true);
+ intent.setName(qname);
+ requiredIntents.add(intent);
+ } else {
+ for (String q : qualifiers) {
+ Intent intent = policyFactory.createIntent();
+ intent.setUnresolved(true);
+ qname = new QName(qname.getNamespaceURI(), qname.getLocalPart() + "." + q);
+ intent.setName(qname);
+ requiredIntents.add(intent);
+ }
+ }
+ }
+ }
+
+ /**
+ * Read intent annotations on the given interface or class
+ * @param intentAnnotation
+ * @param requiredIntents
+ */
+ private void readIntents(Requires intentAnnotation, List<Intent> requiredIntents) {
+ //Requires intentAnnotation = method.getAnnotation(Requires.class);
+ if (intentAnnotation != null) {
+ String[] intentNames = intentAnnotation.value();
+ if (intentNames.length != 0) {
+ //Operation operation = assemblyFactory.createOperation();
+ //operation.setName(method.getName());
+ //operation.setUnresolved(true);
+ for (String intentName : intentNames) {
+
+ // Add each intent to the list, associated with the
+ // operation corresponding to the annotated method
+ Intent intent = policyFactory.createIntent();
+ intent.setName(getQName(intentName));
+ //intent.getOperations().add(operation);
+ requiredIntents.add(intent);
+ }
+ }
+ }
+ }
+
+ /**
+ * Read policy set annotations on a given interface or class
+ * @param policySetAnnotation
+ * @param policySets
+ */
+ private void readPolicySets(PolicySets policySetAnnotation, List<PolicySet> policySets) {
+ if (policySetAnnotation != null) {
+ String[] policySetNames = policySetAnnotation.value();
+ if (policySetNames.length != 0) {
+ //Operation operation = assemblyFactory.createOperation();
+ //operation.setName(method.getName());
+ //operation.setUnresolved(true);
+ for (String policySetName : policySetNames) {
+ // Add each intent to the list, associated with the
+ // operation corresponding to the annotated method
+ PolicySet policySet = policyFactory.createPolicySet();
+ policySet.setName(getQName(policySetName));
+ //intent.getOperations().add(operation);
+ policySets.add(policySet);
+ }
+ }
+ }
+ }
+
+ /**
+ * Utility methods
+ */
+
+ /**
+ *
+ * @param intentName
+ * @return
+ */
+ private static QName getQName(String intentName) {
+ QName qname;
+ if (intentName.startsWith("{")) {
+ int i = intentName.indexOf('}');
+ if (i != -1) {
+ qname = new QName(intentName.substring(1, i), intentName.substring(i + 1));
+ } else {
+ qname = new QName("", intentName);
+ }
+ } else {
+ qname = new QName("", intentName);
+ }
+ return qname;
+ }
+
+ @Override
+ public void visitField(Field field, JavaImplementation type) throws IntrospectionException {
+ // Check if a field that is not an SCA reference has any policySet/intent annotations
+ JavaElementImpl element = new JavaElementImpl(field);
+ if (!type.getReferenceMembers().values().contains(element)) {
+ PolicySubject subject = assemblyFactory.createComponent();
+ readPolicySetAndIntents(subject, field);
+ if (subject.getPolicySets().isEmpty() && subject.getRequiredIntents().isEmpty()) {
+ return;
+ }
+ throw new ServiceRuntimeException(
+ "[JCA70002,JCA70005] Field that is not an SCA reference cannot have policySet/intent annotations: " + field);
+ }
+ }
+
+ @Override
+ public void visitConstructorParameter(JavaParameterImpl parameter, JavaImplementation type) {
+ if (!type.getReferenceMembers().values().contains(parameter)) {
+ PolicySubject subject = assemblyFactory.createComponent();
+ readPolicySetAndIntents(subject, parameter);
+ if (subject.getPolicySets().isEmpty() && subject.getRequiredIntents().isEmpty()) {
+ return;
+ }
+ throw new ServiceRuntimeException(
+ "[JCA70002,JCA70005] Constructor parameter that is not an SCA reference cannot have policySet/intent annotations: " + parameter);
+ }
+ }
+
+ @Override
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+ Set<AnnotatedElement> annotatedElements = new HashSet<AnnotatedElement>();
+ for (JavaElementImpl element : type.getReferenceMembers().values()) {
+ annotatedElements.add(element.getAnchor());
+ }
+ // Check if a field that is not an SCA reference has any policySet/intent annotations
+ if (!annotatedElements.contains(method)) {
+ PolicySubject subject = assemblyFactory.createComponent();
+ readPolicySetAndIntents(subject, method);
+ if (subject.getPolicySets().isEmpty() && subject.getRequiredIntents().isEmpty()) {
+ return;
+ }
+ throw new ServiceRuntimeException(
+ "[JCA70002,JCA70005] Method that is not an SCA reference cannot have policySet/intent annotations: " + method);
+ }
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/PropertyProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/PropertyProcessor.java
new file mode 100644
index 0000000000..ed68be20b4
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/PropertyProcessor.java
@@ -0,0 +1,50 @@
+/*
+ * 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 org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.oasisopen.sca.annotation.Property;
+
+/**
+ * Processes an {@link @Property} annotation, updating the component type with
+ * corresponding {@link JavaMappedProperty}
+ *
+ * @version $Rev$ $Date$
+ */
+public class PropertyProcessor extends AbstractPropertyProcessor<Property> {
+
+ public PropertyProcessor(ExtensionPointRegistry registry) {
+ super(registry, Property.class);
+ }
+
+ @Override
+ protected String getName(Property annotation) {
+ return annotation.name();
+ }
+
+ @Override
+ protected void initProperty(org.apache.tuscany.sca.assembly.Property property, Property annotation) {
+ property.setMustSupply(annotation.required());
+ }
+
+ @Override
+ protected boolean getRequired(Property annotation) {
+ return annotation.required();
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java
new file mode 100644
index 0000000000..cb612bd224
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java
@@ -0,0 +1,300 @@
+/*
+ * 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.JavaIntrospectionHelper.getBaseType;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Multiplicity;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+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.JavaParameterImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.oasisopen.sca.ServiceReference;
+import org.oasisopen.sca.annotation.AllowsPassByReference;
+import org.oasisopen.sca.annotation.Reference;
+import org.oasisopen.sca.annotation.Remotable;
+
+/**
+ * Processes an {@link @Reference} annotation, updating the component type with
+ * corresponding {@link
+ * org.apache.tuscany.spi.implementation.java.JavaMappedReference}
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReferenceProcessor extends BaseJavaClassVisitor {
+
+ public ReferenceProcessor(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) {
+ super(assemblyFactory);
+ this.javaInterfaceFactory = javaFactory;
+ }
+
+ public ReferenceProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+ Reference annotation = method.getAnnotation(Reference.class);
+ if (annotation != null) {
+
+ if (!JavaIntrospectionHelper.isSetter(method)) {
+ throw new IllegalReferenceException("Annotated method is not a setter: " + method, method);
+ }
+
+ if(Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalPropertyException("Static method " + method.getName() +" in class " + method.getDeclaringClass().getName() + " can not be annotated as a Reference");
+ }
+
+ String name = annotation.name();
+ if ("".equals(name)) {
+ name = JavaIntrospectionHelper.toPropertyName(method.getName());
+ }
+ JavaElementImpl ref = type.getReferenceMembers().get(name);
+ // Setter override field
+ if (ref != null && ref.getElementType() != ElementType.FIELD) {
+ throw new DuplicateReferenceException(name);
+ }
+ removeReference(ref, type);
+
+ JavaElementImpl element = new JavaElementImpl(method, 0);
+ org.apache.tuscany.sca.assembly.Reference reference = createReference(type, element, name);
+ type.getReferences().add(reference);
+ type.getReferenceMembers().put(name, element);
+ }
+
+ // enforce the constraint that an ordinary method's argument can not be a reference
+ Annotation paramsAnnotations[][] = method.getParameterAnnotations();
+ for (int i = 0; i < paramsAnnotations.length; i++) {
+ Annotation argAnnotations[] = paramsAnnotations[i];
+ for (int j = 0; j < argAnnotations.length; j++) {
+ if(argAnnotations[j].annotationType() == Reference.class) {
+ throw new IllegalReferenceException("Argument " + (i+1) + " of method " + method.getName() + " in class " + method.getDeclaringClass() + " can not be a Reference");
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public void visitField(Field field, JavaImplementation type) throws IntrospectionException {
+ Reference annotation = field.getAnnotation(Reference.class);
+ if (annotation == null) {
+ return;
+ }
+
+ if(Modifier.isStatic(field.getModifiers())) {
+ throw new IllegalReferenceException("Static field " + field.getName() +" in class " + field.getDeclaringClass().getName() + " can not be annotated as Reference");
+ }
+ String name = annotation.name();
+ if ("".equals(name)) {
+ name = field.getName();
+ }
+ JavaElementImpl ref = type.getReferenceMembers().get(name);
+ if (ref != null && ref.getElementType() == ElementType.FIELD) {
+ throw new DuplicateReferenceException(name);
+ }
+
+ // Setter method override field
+ if (ref == null) {
+ JavaElementImpl element = new JavaElementImpl(field);
+ org.apache.tuscany.sca.assembly.Reference reference = createReference(type, element, name);
+ type.getReferences().add(reference);
+ type.getReferenceMembers().put(name, element);
+ }
+ }
+
+ @Override
+ public void visitConstructorParameter(JavaParameterImpl parameter, JavaImplementation type)
+ throws IntrospectionException {
+ Reference refAnnotation = parameter.getAnnotation(Reference.class);
+ if (refAnnotation == null) {
+ return;
+ }
+
+ if (!refAnnotation.required()) {
+ throw new InvalidReferenceException("[JCA90016] Constructor has @Reference with required=false: " + type.getName());
+ }
+
+ if (refAnnotation.name() == null || refAnnotation.name().length() < 1) {
+ throw new InvalidReferenceException("[JCA90018] @Reference in a Constructor must have a name attribute" + type.getName());
+ }
+
+ String paramName = parameter.getName();
+ String name = getReferenceName(paramName, parameter.getIndex(), refAnnotation.name());
+ JavaElementImpl ref = type.getReferenceMembers().get(name);
+
+ // Setter override field
+ if (ref != null && ref.getElementType() != ElementType.FIELD) {
+ throw new DuplicateReferenceException(name);
+ }
+
+ removeReference(ref, type);
+ org.apache.tuscany.sca.assembly.Reference reference = createReference(type, parameter, name);
+ type.getReferences().add(reference);
+ type.getReferenceMembers().put(name, parameter);
+ parameter.setClassifer(Reference.class);
+ parameter.setName(name);
+ }
+
+ /**
+ * Create a SCA reference for a java Element
+ * @param implementation TODO
+ * @param element
+ * @param name
+ * @return
+ * @throws IntrospectionException
+ */
+ private org.apache.tuscany.sca.assembly.Reference createReference(JavaImplementation implementation, JavaElementImpl element, String name)
+ throws IntrospectionException {
+ org.apache.tuscany.sca.assembly.Reference reference = assemblyFactory.createReference();
+ JavaInterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
+ reference.setInterfaceContract(interfaceContract);
+
+ AllowsPassByReference pbr = element.getAnnotation(AllowsPassByReference.class);
+ if (pbr != null) {
+ reference.setAllowsPassByReference(true);
+ } else {
+ reference.setAllowsPassByReference(implementation.isAllowsPassByReference());
+ }
+
+ // reference.setMember((Member)element.getAnchor());
+ boolean required = true;
+ Reference ref = element.getAnnotation(Reference.class);
+ if (ref != null) {
+ required = ref.required();
+ }
+ // reference.setRequired(required);
+ reference.setName(name);
+ Class<?> rawType = element.getType();
+ if (rawType.isArray() || Collection.class.isAssignableFrom(rawType)) {
+ if (required) {
+ reference.setMultiplicity(Multiplicity.ONE_N);
+ } else {
+ reference.setMultiplicity(Multiplicity.ZERO_N);
+ }
+ } else {
+ if (required) {
+ reference.setMultiplicity(Multiplicity.ONE_ONE);
+ } else {
+ reference.setMultiplicity(Multiplicity.ZERO_ONE);
+ }
+ }
+ Type genericType = element.getGenericType();
+ Class<?> baseType = getBaseType(rawType, genericType);
+ if (ServiceReference.class.isAssignableFrom(baseType)) {
+ if (Collection.class.isAssignableFrom(rawType)) {
+ genericType = JavaIntrospectionHelper.getParameterType(genericType);
+ }
+ baseType = JavaIntrospectionHelper.getBusinessInterface(baseType, genericType);
+ }
+ // The reference can have a Remotable annotation. This forces the interface to be
+ // remotable even if the interface doesn't have a Remotable annotation.
+ boolean forceRemotable = element.getAnnotation(Remotable.class) != null;
+ // If the reference element is a setter method, element.getAnnotation() looks at
+ // the method-level annotations only. Compliance test POJO_8017 puts the
+ // Remotable annotation on the setter method's argument, so we need some special
+ // logic to look at the argument.
+ if (!forceRemotable && element.getElementType() == ElementType.PARAMETER && (element.getAnchor() instanceof Method)) {
+ Annotation argAnnotations[] = ((Method)element.getAnchor()).getParameterAnnotations()[0];
+ for (int j = 0; j < argAnnotations.length; j++) {
+ if (argAnnotations[j].annotationType() == Remotable.class) {
+ forceRemotable = true;
+ break;
+ }
+ }
+ }
+ try {
+ JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(baseType, forceRemotable);
+ reference.getInterfaceContract().setInterface(callInterface);
+ if (callInterface.getCallbackClass() != null) {
+ JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(callInterface.getCallbackClass(), forceRemotable);
+ reference.getInterfaceContract().setCallbackInterface(callbackInterface);
+ }
+ } catch (InvalidInterfaceException e) {
+ throw new IntrospectionException(e);
+ }
+ return reference;
+ }
+
+
+ /**
+ * Utility methods
+ */
+
+ /**
+ *
+ * @param paramName
+ * @param pos
+ * @param name
+ * @return
+ * @throws InvalidConstructorException
+ */
+ private static String getReferenceName(String paramName, int pos, String name) throws InvalidConstructorException {
+ if ("".equals(name)) {
+ name = paramName;
+ }
+ if ("".equals(name)) {
+ return "_ref" + pos;
+ }
+ if (!"".equals(paramName) && !name.equals(paramName)) {
+ throw new InvalidConstructorException("Mismatching names specified for reference parameter " + pos);
+ } else {
+ return name;
+ }
+ }
+
+ /**
+ *
+ * @param ref
+ * @param type
+ * @return
+ */
+ private static boolean removeReference(JavaElementImpl ref, JavaImplementation type) {
+ if (ref == null) {
+ return false;
+ }
+ List<org.apache.tuscany.sca.assembly.Reference> refs = type.getReferences();
+ for (int i = 0; i < refs.size(); i++) {
+ if (refs.get(i).getName().equals(ref.getName())) {
+ refs.remove(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/Resource.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/Resource.java
new file mode 100644
index 0000000000..3d43e39ce8
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/Resource.java
@@ -0,0 +1,49 @@
+/*
+ * 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 java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation used to indicate a resource should be provided to an implementation by the runtime.
+ *
+ * @version $Rev$ $Date$
+ */
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Resource {
+
+ /**
+ * Denotes the name of the resource declared by the implementation.
+ */
+ String name() default "";
+
+ /**
+ * Denotes if the resource is optional
+ */
+ boolean optional() default false;
+
+ /**
+ * Denotes the default name of the resource provided by the runtime environment.
+ */
+ String mappedName() default "";
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ResourceProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ResourceProcessor.java
new file mode 100644
index 0000000000..3abe832cb9
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ResourceProcessor.java
@@ -0,0 +1,153 @@
+/*
+ * 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 java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+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.JavaParameterImpl;
+import org.apache.tuscany.sca.implementation.java.JavaResourceImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+
+/**
+ * Processes an {@link @Resource} annotation, updating the component type with
+ * corresponding {@link org.apache.tuscany.spi.implementation.java.JavaResourceImpl}
+ *
+ * @version $Rev$ $Date$
+ */
+public class ResourceProcessor extends BaseJavaClassVisitor {
+
+ public ResourceProcessor(AssemblyFactory factory) {
+ super(factory);
+ }
+
+ public ResourceProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+ org.apache.tuscany.sca.implementation.java.introspect.impl.Resource annotation = method
+ .getAnnotation(org.apache.tuscany.sca.implementation.java.introspect.impl.Resource.class);
+ if (annotation == null) {
+ return;
+ }
+ if (method.getParameterTypes().length != 1) {
+ throw new IllegalResourceException("Resource setter must have one parameter", method);
+ }
+ String name = annotation.name();
+ if (name.length() < 1) {
+ name = JavaIntrospectionHelper.toPropertyName(method.getName());
+ }
+ if (type.getResources().get(name) != null) {
+ throw new DuplicateResourceException(name);
+ }
+
+ String mappedName = annotation.mappedName();
+ JavaResourceImpl resource = createResource(name, new JavaElementImpl(method, 0));
+ resource.setOptional(annotation.optional());
+ if (mappedName.length() > 0) {
+ resource.setMappedName(mappedName);
+ }
+ type.getResources().put(resource.getName(), resource);
+ }
+
+ @Override
+ public void visitField(Field field, JavaImplementation type) throws IntrospectionException {
+
+ org.apache.tuscany.sca.implementation.java.introspect.impl.Resource annotation = field
+ .getAnnotation(org.apache.tuscany.sca.implementation.java.introspect.impl.Resource.class);
+ if (annotation == null) {
+ return;
+ }
+ String name = annotation.name();
+ if (name.length() < 1) {
+ name = field.getName();
+ }
+ if (type.getResources().get(name) != null) {
+ throw new DuplicateResourceException(name);
+ }
+
+ String mappedName = annotation.mappedName();
+
+ JavaResourceImpl resource = createResource(name, new JavaElementImpl(field));
+ resource.setOptional(annotation.optional());
+ if (mappedName.length() > 0) {
+ resource.setMappedName(mappedName);
+ }
+ type.getResources().put(resource.getName(), resource);
+ }
+
+ @Override
+ public void visitConstructorParameter(JavaParameterImpl parameter, JavaImplementation type)
+ throws IntrospectionException {
+ org.apache.tuscany.sca.implementation.java.introspect.impl.Resource resourceAnnotation = parameter
+ .getAnnotation(org.apache.tuscany.sca.implementation.java.introspect.impl.Resource.class);
+ if (resourceAnnotation != null) {
+ String name = resourceAnnotation.name();
+ if ("".equals(name)) {
+ name = parameter.getName();
+ }
+ if ("".equals(name)) {
+ throw new InvalidResourceException("Missing resource name", (Member)parameter.getAnchor());
+ }
+
+ if (!"".equals(parameter.getName()) && !name.equals(parameter.getName())) {
+ throw new InvalidConstructorException("Mismatched resource name: " + parameter);
+ }
+
+ if (type.getResources().get(name) != null) {
+ throw new DuplicateResourceException(name);
+ }
+
+ String mappedName = resourceAnnotation.mappedName();
+
+ JavaResourceImpl resource = createResource(name, parameter);
+ resource.setOptional(resourceAnnotation.optional());
+ if (mappedName.length() > 0) {
+ resource.setMappedName(mappedName);
+ }
+ type.getResources().put(resource.getName(), resource);
+ }
+ }
+
+
+ /**
+ * Utility methods
+ */
+
+ /**
+ *
+ * @param name
+ * @param element
+ * @return
+ */
+ private static JavaResourceImpl createResource(String name, JavaElementImpl element) {
+ element.setClassifer(org.apache.tuscany.sca.implementation.java.introspect.impl.Resource.class);
+ element.setName(name);
+ return new JavaResourceImpl(element);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ScopeProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ScopeProcessor.java
new file mode 100644
index 0000000000..dfc122c715
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ScopeProcessor.java
@@ -0,0 +1,68 @@
+/*
+ * 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 org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaScopeImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+
+/**
+ * Processes the {@link JavaScopeImpl} annotation and updates the component type with the corresponding implmentation scope
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeProcessor extends BaseJavaClassVisitor {
+
+ public ScopeProcessor(AssemblyFactory factory) {
+ super(factory);
+ }
+
+ public ScopeProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public <T> void visitClass(Class<T> clazz,
+ JavaImplementation type)
+ throws IntrospectionException {
+ org.oasisopen.sca.annotation.Scope annotation = clazz.getAnnotation(org.oasisopen.sca.annotation.Scope.class);
+ if (annotation == null) {
+ type.setJavaScope(JavaScopeImpl.STATELESS);
+ return;
+ }
+
+ String name = annotation.value();
+ JavaScopeImpl scope;
+ if ("COMPOSITE".equals(name)) {
+ scope = JavaScopeImpl.COMPOSITE;
+ } else if ("STATELESS".equals(name)) {
+ scope = JavaScopeImpl.STATELESS;
+ } else {
+ scope = JavaScopeImpl.INVALID;
+ }
+ type.setJavaScope(scope);
+
+ if (type.getJavaScope().equals(JavaScopeImpl.INVALID)) {
+ throw new IntrospectionException("Invalid scope :" + name + " for " + type.getName());
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java
new file mode 100644
index 0000000000..b2aa01ab92
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java
@@ -0,0 +1,264 @@
+/*
+ * 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.JavaIntrospectionHelper.getAllInterfaces;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.jws.WebService;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+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.JavaScopeImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.oasisopen.sca.ServiceReference;
+import org.oasisopen.sca.annotation.Callback;
+import org.oasisopen.sca.annotation.Remotable;
+
+/**
+ * Processes an {@link org.oasisopen.sca.annotation.Service} annotation and updates
+ * the component type with corresponding {@link Service}s. Also processes
+ * related {@link org.oasisopen.sca.annotation.Callback} annotations.
+ *
+ * This Visitor MUST follow the ScopeProcessor in the sequence of visitors, since processing of
+ * the Callback annotations depends on knowing the Scope of the implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServiceProcessor extends BaseJavaClassVisitor {
+
+ public ServiceProcessor(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) {
+ super(assemblyFactory);
+ this.javaInterfaceFactory = javaFactory;
+ }
+
+ public ServiceProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public <T> void visitClass(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+ org.oasisopen.sca.annotation.Service annotation = clazz.getAnnotation(org.oasisopen.sca.annotation.Service.class);
+ if (annotation == null) {
+ // scan interfaces for remotable
+ Set<Class<?>> interfaces = getAllInterfaces(clazz);
+ for (Class<?> interfaze : interfaces) {
+ if (interfaze.isAnnotationPresent(Remotable.class)
+ || interfaze.isAnnotationPresent(WebService.class)
+ || interfaze.isAnnotationPresent(Callback.class)
+ ) {
+ Service service;
+ try {
+ service = createService(clazz, interfaze, null);
+ } catch (InvalidInterfaceException e) {
+ throw new IntrospectionException(e);
+ }
+ type.getServices().add(service);
+ }
+ }
+ return;
+ }
+
+ if (annotation.value().length == 0) {
+ throw new IntrospectionException("[JCA90059] The array of interfaces or classes specified by the value attribute of the @Service annotation MUST contain at least one element");
+ }
+ Class<?>[] interfaces = annotation.value();
+ if (annotation.names().length > 0) {
+ if (annotation.names().length != interfaces.length) {
+ throw new IntrospectionException("[JCA90050] The number of Strings in the names attribute array of the @Service annotation MUST match the number of elements in the value attribute array");
+ }
+ Set<String> names = new HashSet<String>();
+ names.addAll(Arrays.asList(annotation.names()));
+ if (names.size() != annotation.names().length) {
+ throw new IntrospectionException("[JCA90060] The value of each element in the @Service names array MUST be unique amongst all the other element values in the array");
+ }
+ }
+
+ //validate no scope on servce interface
+ for (Class<?> iface : interfaces) {
+ if (iface.getAnnotation(org.oasisopen.sca.annotation.Scope.class) != null) {
+ throw new IntrospectionException("[JCA90041] @Scope annotation not allowed on service interface " + iface
+ .getName());
+ }
+ }
+
+ //validate service methods implemented
+ Method[] ms = clazz.getMethods();
+ for (Class<?> iface : interfaces) {
+ for (Method m : iface.getMethods()) {
+ if (!hasMethod(m, ms)) {
+ throw new IntrospectionException("[JCA90042,JCI20002] Implementation missing service method " + m.getName() + " service interface " + iface.getName());
+ }
+ }
+ }
+
+ for (int i=0; i < interfaces.length; i++) {
+ try {
+ String name = (annotation.names().length > 0) ? annotation.names()[i] : null;
+ Service service = createService(clazz, interfaces[i], name);
+ type.getServices().add(service);
+ } catch (InvalidInterfaceException e) {
+ throw new IntrospectionException(e);
+ }
+ }
+
+ }
+
+ protected boolean hasMethod(Method m1, Method[] ms) {
+ for (Method m2 : ms) {
+ if (JavaIntrospectionHelper.exactMethodMatch(m1, m2)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException {
+
+ Callback annotation = method.getAnnotation(Callback.class);
+ if (annotation == null) {
+ return;
+ }
+ if( type.getJavaScope() == JavaScopeImpl.COMPOSITE ) {
+ throw new IllegalCallbackReferenceException("[JCA90057] @Callback on field or method cannot be used for a class with @Scope(COMPOSITE): " + type.getName() + "." + method.getName());
+ }
+
+ if (!(annotation.value() == null || annotation.value() == Void.class)) {
+ throw new IllegalCallbackReferenceException("[JCA90046] @Callback on field of method must not have any parameters: " + type.getName() + "." + method.getName());
+ }
+
+ if(Modifier.isPrivate(method.getModifiers())) {
+ throw new IllegalCallbackReferenceException("Illegal annotation @Callback found on "+method, method);
+ }
+ if (method.getParameterTypes().length != 1) {
+ throw new IllegalCallbackReferenceException("Setter must have one parameter", method);
+ }
+ JavaElementImpl element = new JavaElementImpl(method, 0);
+ createCallback(type, element);
+ }
+
+ @Override
+ public void visitField(Field field, JavaImplementation type) throws IntrospectionException {
+
+ Callback annotation = field.getAnnotation(Callback.class);
+ if (annotation == null) {
+ return;
+ }
+ if( type.getJavaScope() == JavaScopeImpl.COMPOSITE ) {
+ throw new IllegalCallbackReferenceException("[JCA90057] @Callback on field or method cannot be used for a class with @Scope(COMPOSITE): " + type.getName() + "." + field.getName());
+ }
+ if (!(annotation.value() == null || annotation.value() == Void.class)) {
+ throw new IllegalCallbackReferenceException("[JCA90046] @Callback on field of method must not have any parameters: " + type.getName() + "." + field.getName());
+ }
+ if(Modifier.isPrivate(field.getModifiers())) {
+ throw new IllegalCallbackReferenceException("Illegal annotation @Callback found on "+field, field);
+ }
+ JavaElementImpl element = new JavaElementImpl(field);
+ createCallback(type, element);
+ }
+
+ public Service createService(Class<?> clazz, Class<?> interfaze, String name) throws InvalidInterfaceException {
+ Service service = assemblyFactory.createService();
+ JavaInterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
+ service.setInterfaceContract(interfaceContract);
+
+ // The implementation class can have a Remotable annotation. This forces all service
+ // interfaces to be remotable even if the interfaces do not have a Remotable annotation.
+ boolean forceRemotable = clazz.getAnnotation(Remotable.class) != null;
+
+ JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(interfaze, forceRemotable);
+
+ if (name == null) {
+ String serviceName = interfaze.getSimpleName();
+ // If the interface has @WebService annotation then take the
+ // service name from the @name attribute if present
+ if (interfaze.isAnnotationPresent(WebService.class)){
+ if (callInterface.getQName() != null){
+ serviceName = callInterface.getQName().getLocalPart();
+ }
+ }
+
+ service.setName(serviceName);
+ } else {
+ service.setName(name);
+ }
+
+ service.getInterfaceContract().setInterface(callInterface);
+
+ if (callInterface.getCallbackClass() != null) {
+ JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(callInterface.getCallbackClass(), forceRemotable);
+ service.getInterfaceContract().setCallbackInterface(callbackInterface);
+ }
+ return service;
+ }
+
+ /**
+ * Utility methods
+ */
+
+
+ /**
+ * @param type
+ * @param element
+ * @throws IllegalCallbackReferenceException
+ */
+ private static void createCallback(JavaImplementation type, JavaElementImpl element)
+ throws IllegalCallbackReferenceException {
+ Service callbackService = null;
+ Class<?> callbackClass = element.getType();
+ Type genericType = element.getGenericType();
+ Class<?> baseType = callbackClass;
+ if(ServiceReference.class.isAssignableFrom(baseType)) {
+ // @Callback protected CallableReference<MyCallback> callback;
+ // The base type will be MyCallback
+ baseType = JavaIntrospectionHelper.getBusinessInterface(baseType, genericType);
+ }
+ for (Service service : type.getServices()) {
+ JavaInterface javaInterface = (JavaInterface)service.getInterfaceContract().getCallbackInterface();
+ if (javaInterface != null && baseType == javaInterface.getJavaClass()) {
+ callbackService = service;
+ }
+ }
+ if (callbackService == null) {
+ throw new IllegalCallbackReferenceException("Callback type does not match a service callback interface: " + type.getName() );
+ }
+ if(type.getCallbackMembers().get(baseType.getName()) == null) {
+ type.getCallbackMembers().put(baseType.getName(), new ArrayList<JavaElementImpl>());
+ }
+ type.getCallbackMembers().get(baseType.getName()).add(element);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceTypeNotFoundException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceTypeNotFoundException.java
new file mode 100644
index 0000000000..e1ca3ea565
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceTypeNotFoundException.java
@@ -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.tuscany.sca.implementation.java.introspect.impl;
+
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+
+/**
+ * Thrown when a service interface cannot be determined based on a heuristic evaluation of an implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServiceTypeNotFoundException extends IntrospectionException {
+ private static final long serialVersionUID = -5124437274726947007L;
+
+ public ServiceTypeNotFoundException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/UnknownContextTypeException.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/UnknownContextTypeException.java
new file mode 100644
index 0000000000..bfaa759cd2
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/UnknownContextTypeException.java
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+/**
+ * Thrown when a method or field marked with {@link org.oasisopen.sca.annotation.Context} takes an unknown type
+ *
+ * @version $Rev$ $Date$
+ */
+public class UnknownContextTypeException extends IllegalContextException {
+ private static final long serialVersionUID = 8125863714365422419L;
+
+ public UnknownContextTypeException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/package.html b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/package.html
new file mode 100644
index 0000000000..53614a627b
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/package.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+ * 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.
+-->
+<html>
+<head>
+</head>
+<body>
+Base Package for the implementation.java extension.
+
+Whilst this package and its subpackages are not currently deemed to represent extension developers SPI, this extension has a special relationship with implementation.spring. Implementation.spring can be viewed as an extension of implementation.java.
+
+</body>
+</html>
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationConstants.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationConstants.java
new file mode 100644
index 0000000000..c23f5e4d39
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationConstants.java
@@ -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.tuscany.sca.implementation.java.xml;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Constants for the Java Implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface JavaImplementationConstants {
+ String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912";
+ String IMPLEMENTATION_JAVA = "implementation.java";
+ QName IMPLEMENTATION_JAVA_QNAME = new QName(SCA11_NS, "implementation.java");
+ String CLASS = "class";
+ String OPERATION = "operation";
+ QName OPERATION_QNAME = new QName(SCA11_NS, OPERATION);
+}
diff --git a/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationProcessor.java b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationProcessor.java
new file mode 100644
index 0000000000..93120652ad
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationProcessor.java
@@ -0,0 +1,398 @@
+/*
+ * 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.xml;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static org.apache.tuscany.sca.implementation.java.xml.JavaImplementationConstants.CLASS;
+import static org.apache.tuscany.sca.implementation.java.xml.JavaImplementationConstants.IMPLEMENTATION_JAVA;
+import static org.apache.tuscany.sca.implementation.java.xml.JavaImplementationConstants.IMPLEMENTATION_JAVA_QNAME;
+import static org.apache.tuscany.sca.implementation.java.xml.JavaImplementationConstants.SCA11_NS;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.xml.PolicySubjectProcessor;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ClassReference;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+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.implementation.java.introspect.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.Compatibility;
+import org.apache.tuscany.sca.interfacedef.IncompatibleInterfaceContractException;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+import org.apache.tuscany.sca.policy.ExtensionType;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+
+/**
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaImplementationProcessor implements StAXArtifactProcessor<JavaImplementation> {
+
+ private JavaImplementationFactory javaFactory;
+ private AssemblyFactory assemblyFactory;
+ private PolicyFactory policyFactory;
+ private PolicySubjectProcessor policyProcessor;
+ private StAXArtifactProcessor<Object> extensionProcessor;
+ private transient InterfaceContractMapper interfaceContractMapper;
+
+ public JavaImplementationProcessor(ExtensionPointRegistry registry, StAXArtifactProcessor<?> staxProcessor) {
+ FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class);
+ this.policyFactory = modelFactories.getFactory(PolicyFactory.class);
+ this.javaFactory = modelFactories.getFactory(JavaImplementationFactory.class);
+ this.policyProcessor = new PolicySubjectProcessor(policyFactory);
+ this.extensionProcessor = (StAXArtifactProcessor<Object>)staxProcessor;
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ this.interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class);
+ }
+
+ /**
+ * Report a error.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(Monitor monitor, String message, Object model, Object... messageParameters) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "impl-javaxml-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ /**
+ * Report a exception.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(Monitor monitor, String message, Object model, Exception ex) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "impl-javaxml-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ ex);
+ monitor.problem(problem);
+ }
+ }
+
+ public JavaImplementation read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException {
+
+ // Read an <implementation.java>
+ JavaImplementation javaImplementation = javaFactory.createJavaImplementation();
+
+ ExtensionType implType = policyFactory.createImplementationType();
+ implType.setType(getArtifactType());
+ implType.setUnresolved(true);
+ javaImplementation.setExtensionType(implType);
+
+ javaImplementation.setUnresolved(true);
+ javaImplementation.setName(reader.getAttributeValue(null, CLASS));
+
+ // Read policies
+ policyProcessor.readPolicies(javaImplementation, reader);
+
+ // read operation elements if exists or skip unto end element
+ int event;
+ while (reader.hasNext()) {
+ event = reader.next();
+ if (event == END_ELEMENT && IMPLEMENTATION_JAVA_QNAME.equals(reader.getName())) {
+ break;
+ }
+ }
+ return javaImplementation;
+ }
+
+ public void write(JavaImplementation javaImplementation, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException,
+ XMLStreamException {
+
+ // Write an <implementation.java>
+ writer.writeStartElement(SCA11_NS, IMPLEMENTATION_JAVA);
+ policyProcessor.writePolicyAttributes(javaImplementation, writer);
+
+ if (javaImplementation.getName() != null) {
+ writer.writeAttribute(CLASS, javaImplementation.getName());
+ }
+
+ writer.writeEndElement();
+ }
+
+ public void resolve(JavaImplementation javaImplementation, ModelResolver resolver, ProcessorContext context)
+ throws ContributionResolveException {
+ Monitor monitor = context.getMonitor();
+ try {
+ ClassReference classReference = new ClassReference(javaImplementation.getName());
+ classReference = resolver.resolveModel(ClassReference.class, classReference, context);
+ Class<?> javaClass = classReference.getJavaClass();
+ if (javaClass == null) {
+ error(monitor, "ClassNotFoundException", resolver, javaImplementation.getName());
+ //throw new ContributionResolveException(new ClassNotFoundException(javaImplementation.getName()));
+ return;
+ }
+
+ javaImplementation.setJavaClass(javaClass);
+
+ try {
+ javaFactory.createJavaImplementation(javaImplementation, javaImplementation.getJavaClass());
+ } catch (IntrospectionException e) {
+ ContributionResolveException ce = new ContributionResolveException(e);
+ error(monitor, "ContributionResolveException", javaFactory, ce);
+ //throw ce;
+ return;
+ }
+
+ checkNoStaticAnnotations(monitor, javaImplementation);
+
+ postJAXWSProcessorResolve(resolver, javaImplementation, context);
+
+ javaImplementation.setUnresolved(false);
+
+ mergeComponentType(resolver, javaImplementation, context);
+
+ // FIXME the introspector should always create at least one service
+ if (javaImplementation.getServices().isEmpty()) {
+ javaImplementation.getServices().add(assemblyFactory.createService());
+ }
+ } catch (Throwable e) {
+
+ String message = context.getMonitor().getMessageString(JavaImplementationProcessor.class.getName(),
+ "impl-javaxml-validation-messages",
+ "ResolvingJavaImplementation");
+ message = message.replace("{0}", javaImplementation.getName());
+ message = message.replace("{1}", e.getMessage());
+
+ throw new ContributionResolveException(message, e);
+ } // end try
+ } // end method
+
+ private void checkNoStaticAnnotations(Monitor monitor, JavaImplementation javaImplementation) {
+ if (javaImplementation.getJavaClass() != null) {
+ Class<?> clazz = javaImplementation.getJavaClass();
+ for (Method m : clazz.getMethods()) {
+ if (Modifier.isStatic(m.getModifiers())) {
+ for (Annotation a : m.getAnnotations()) {
+ if (a.annotationType().getName().startsWith("org.oasisopen.sca.annotation")) {
+ error(monitor, "IllegalSCAAnnotation", javaFactory, javaImplementation.getName(), m.getName());
+ }
+ }
+ }
+ }
+ for (Field f : clazz.getFields()) {
+ if (Modifier.isStatic(f.getModifiers())) {
+ for (Annotation a : f.getAnnotations()) {
+ if (a.annotationType().getName().startsWith("org.oasisopen.sca.annotation")) {
+ error(monitor, "IllegalSCAAnnotation", javaFactory, javaImplementation.getName(), f.getName());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private JavaElementImpl getMemeber(JavaImplementation impl, String name, Class<?> type) {
+ String setter = JavaIntrospectionHelper.toSetter(name);
+ try {
+ Method method = impl.getJavaClass().getDeclaredMethod(setter, type);
+ int mod = method.getModifiers();
+ if ((Modifier.isPublic(mod) || Modifier.isProtected(mod)) && (!Modifier.isStatic(mod))) {
+ return new JavaElementImpl(method, 0);
+ }
+ } catch (NoSuchMethodException e) {
+ Field field;
+ try {
+ field = impl.getJavaClass().getDeclaredField(name);
+ int mod = field.getModifiers();
+ if ((Modifier.isPublic(mod) || Modifier.isProtected(mod)) && (!Modifier.isStatic(mod))) {
+ return new JavaElementImpl(field);
+ }
+ } catch (NoSuchFieldException e1) {
+ // Ignore
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Merge the componentType from introspection and external file
+ * @param resolver
+ * @param impl
+ */
+ private void mergeComponentType(ModelResolver resolver, JavaImplementation impl, ProcessorContext context) {
+ // FIXME: Need to clarify how to merge
+ ComponentType componentType = getComponentType(resolver, impl, context);
+ if (componentType != null && !componentType.isUnresolved()) {
+ Map<String, Reference> refMap = new HashMap<String, Reference>();
+ for (Reference ref : impl.getReferences()) {
+ refMap.put(ref.getName(), ref);
+ }
+ for (Reference reference : componentType.getReferences()) {
+ refMap.put(reference.getName(), reference);
+ }
+ impl.getReferences().clear();
+ impl.getReferences().addAll(refMap.values());
+
+ // Try to match references by type
+ Map<String, JavaElementImpl> refMembers = impl.getReferenceMembers();
+ for (Reference ref : impl.getReferences()) {
+ if (ref.getInterfaceContract() != null) {
+ Interface i = ref.getInterfaceContract().getInterface();
+ if (i instanceof JavaInterface) {
+ Class<?> type = ((JavaInterface)i).getJavaClass();
+ if (!refMembers.containsKey(ref.getName())) {
+ JavaElementImpl e = getMemeber(impl, ref.getName(), type);
+ if (e != null) {
+ refMembers.put(ref.getName(), e);
+ }
+ }
+ }
+ }
+ }
+
+ Map<String, Service> serviceMap = new HashMap<String, Service>();
+ for (Service svc : impl.getServices()) {
+ serviceMap.put(svc.getName(), svc);
+ }
+ for (Service service : componentType.getServices()) {
+ serviceMap.put(service.getName(), service);
+ }
+ impl.getServices().clear();
+ impl.getServices().addAll(serviceMap.values());
+
+ Map<String, Property> propMap = new HashMap<String, Property>();
+ for (Property prop : impl.getProperties()) {
+ propMap.put(prop.getName(), prop);
+ }
+ for (Property property : componentType.getProperties()) {
+ propMap.put(property.getName(), property);
+ }
+ impl.getProperties().clear();
+ impl.getProperties().addAll(propMap.values());
+
+ }
+ }
+
+ private void postJAXWSProcessorResolve(ModelResolver resolver, JavaImplementation impl, ProcessorContext context)
+ throws ContributionResolveException, IncompatibleInterfaceContractException {
+ for(Service service : impl.getServices()){
+ JavaInterfaceContract javaInterfaceContract = (JavaInterfaceContract)service.getInterfaceContract();
+
+ JavaInterface javaInterface = (JavaInterface)javaInterfaceContract.getInterface();
+ if (javaInterface.isUnresolved()){
+ extensionProcessor.resolve(javaInterfaceContract, resolver, context);
+ }
+
+ WSDLInterfaceContract wsdlInterfaceContract = (WSDLInterfaceContract)javaInterfaceContract.getNormalizedWSDLContract();
+ if(wsdlInterfaceContract != null){
+ // The user has explicitly associated a WSDL with the Java implementation
+ // using a @WebService(wsdlLocation="...") annotation
+ WSDLInterface wsdlInterface = (WSDLInterface)wsdlInterfaceContract.getInterface();
+ if (wsdlInterface.isUnresolved()){
+ //WSDLDefinition resolved = resolver.resolveModel(WSDLDefinition.class, wsdlInterface.getWsdlDefinition(), context);
+ extensionProcessor.resolve(wsdlInterfaceContract, resolver, context);
+
+ // check that the Java and WSDL contracts are compatible
+ interfaceContractMapper.checkCompatibility(wsdlInterfaceContract,
+ javaInterfaceContract,
+ Compatibility.SUBSET,
+ false,
+ false);
+
+ // retrieve the resolved WSDL interface
+ wsdlInterface = (WSDLInterface)wsdlInterfaceContract.getInterface();
+
+ // copy policy from the WSDL interface to the Java interface
+ javaInterface.getPolicySets().addAll(wsdlInterface.getPolicySets());
+ javaInterface.getRequiredIntents().addAll(wsdlInterface.getRequiredIntents());
+
+ // copy policy from the WSDL interface to the component type service
+ service.getPolicySets().addAll(wsdlInterface.getPolicySets());
+ service.getRequiredIntents().addAll(wsdlInterface.getRequiredIntents());
+
+ // TODO - is there anything else to be copied from the user specified WSDL?
+ }
+ }
+ }
+ }
+
+ private ComponentType getComponentType(ModelResolver resolver, JavaImplementation impl, ProcessorContext context) {
+ String className = impl.getJavaClass().getName();
+ String componentTypeURI = className.replace('.', '/') + ".componentType";
+ ComponentType componentType = assemblyFactory.createComponentType();
+ componentType.setUnresolved(true);
+ componentType.setURI(componentTypeURI);
+ componentType = resolver.resolveModel(ComponentType.class, componentType, context);
+ if (!componentType.isUnresolved()) {
+ return componentType;
+ }
+ return null;
+ }
+
+ public QName getArtifactType() {
+ return IMPLEMENTATION_JAVA_QNAME;
+ }
+
+ public Class<JavaImplementation> getModelType() {
+ return JavaImplementation.class;
+ }
+
+}