diff options
Diffstat (limited to 'sandbox/sebastien/java/shell/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl')
4 files changed, 501 insertions, 0 deletions
diff --git a/sandbox/sebastien/java/shell/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/BaseJavaImplementationImpl.java b/sandbox/sebastien/java/shell/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/BaseJavaImplementationImpl.java new file mode 100644 index 0000000000..7cbb4d7a0c --- /dev/null +++ b/sandbox/sebastien/java/shell/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/BaseJavaImplementationImpl.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.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() + ")"; + } + + @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/sandbox/sebastien/java/shell/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaClassIntrospectorImpl.java b/sandbox/sebastien/java/shell/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/sandbox/sebastien/java/shell/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/sandbox/sebastien/java/shell/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationFactoryImpl.java b/sandbox/sebastien/java/shell/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/sandbox/sebastien/java/shell/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/sandbox/sebastien/java/shell/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationImpl.java b/sandbox/sebastien/java/shell/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/sandbox/sebastien/java/shell/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; + } + +} |