summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/LICENSE205
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/META-INF/MANIFEST.MF18
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/NOTICE6
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/pom.xml60
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/CodeGenerationHelper.java280
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/GeneratedClassLoader.java86
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSJavaInterfaceProcessor.java116
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGenerator.java231
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/resources/META-INF/services/org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor17
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/Bean.java31
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSInterfaceProcessorTestCase.java66
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/MockedResource.java51
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/Resource.java50
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/ResourceWrapper.java59
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGeneratorTestCase.java84
15 files changed, 1360 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/LICENSE b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/LICENSE
@@ -0,0 +1,205 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
+
+
+
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/META-INF/MANIFEST.MF b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..f45e70ad23
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Export-Package: org.apache.tuscany.sca.interfacedef.java.jaxrs;version="2.0.0"
+SCA-Version: 1.1
+Bundle-Name: Apache Tuscany Java Interface for JAX-RS
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany Java Interface for JAXWS
+Bundle-SymbolicName: org.apache.tuscany.sca.interface.java.jaxrs
+Bundle-DocURL: http://www.apache.org/
+Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
+Import-Package: javax.ws.rs,
+ org.apache.tuscany.sca.interfacedef,
+ org.apache.tuscany.sca.interfacedef.java,
+ org.apache.tuscany.sca.interfacedef.java.impl,
+ org.apache.tuscany.sca.interfacedef.java.introspect,
+ org.objectweb.asm;version="3.1.0"
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/NOTICE b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/NOTICE
new file mode 100644
index 0000000000..d69e595698
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2011 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/pom.xml b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/pom.xml
new file mode 100644
index 0000000000..7970cb3dcc
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>2.0-Beta3-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-interface-java-jaxrs</artifactId>
+ <name>Apache Tuscany SCA Interface Java For JAX_RS</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-core-runtime-pom</artifactId>
+ <type>pom</type>
+ <scope>provided</scope>
+ <version>2.0-Beta3-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm</artifactId>
+ <version>3.1</version>
+ <type>jar</type>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/CodeGenerationHelper.java b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/CodeGenerationHelper.java
new file mode 100644
index 0000000000..e1891e6c0b
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/CodeGenerationHelper.java
@@ -0,0 +1,280 @@
+/*
+ * 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.interfacedef.java.jaxrs;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.objectweb.asm.Opcodes;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CodeGenerationHelper {
+ /**
+ * @param type
+ * @return
+ */
+ public static Class<?> getErasure(Type type) {
+ if (type instanceof Class) {
+ return (Class<?>)type;
+ } else if (type instanceof GenericArrayType) {
+ GenericArrayType arrayType = (GenericArrayType)type;
+ Class<?> componentType = getErasure(arrayType.getGenericComponentType());
+ return Array.newInstance(componentType, 0).getClass();
+ } 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();
+ if (types.length == 0) {
+ return Object.class;
+ }
+ return getErasure(types[0]);
+ } else if (type instanceof TypeVariable) {
+ TypeVariable<?> var = (TypeVariable<?>)type;
+ Type[] types = var.getBounds();
+ if (types.length == 0) {
+ return Object.class;
+ }
+ return getErasure(types[0]);
+ }
+ return null;
+ }
+
+ /**
+ * @param type
+ * @return
+ */
+ public static String getJAXWSSignature(Type type) {
+ Class<?> cls = getErasure(type);
+ if (Collection.class.isAssignableFrom(cls) && (type instanceof ParameterizedType)) {
+ ParameterizedType pType = (ParameterizedType)type;
+ Type p = pType.getActualTypeArguments()[0];
+ StringBuffer sb = new StringBuffer();
+ sb.append(getSignature(cls));
+ sb.deleteCharAt(sb.length() - 1); // Remove ;
+ sb.append('<').append(getSignature(getErasure(p))).append(">;");
+ return sb.toString();
+ } else if (Map.class.isAssignableFrom(cls) && (type instanceof ParameterizedType)) {
+ ParameterizedType pType = (ParameterizedType)type;
+ Type key = pType.getActualTypeArguments()[0];
+ Type value = pType.getActualTypeArguments()[1];
+ StringBuffer sb = new StringBuffer();
+ sb.append(getSignature(cls));
+ sb.deleteCharAt(sb.length() - 1); // Remove ;
+ sb.append('<').append(getSignature(getErasure(key))).append(getSignature(getErasure(value))).append(">;");
+ return sb.toString();
+ } else {
+ return getSignature(cls);
+ }
+ }
+
+ /**
+ * @param type
+ * @return
+ */
+ public static String getSignature(Type type) {
+ if (!(type instanceof Class)) {
+ if (type instanceof ParameterizedType) {
+ ParameterizedType pType = (ParameterizedType)type;
+ StringBuffer sb = new StringBuffer();
+ String rawType = getSignature(pType.getRawType());
+ sb.append(rawType.substring(0, rawType.length() - 1));
+ sb.append('<');
+ for (Type t : pType.getActualTypeArguments()) {
+ String argType = getSignature(t);
+ sb.append(argType);
+ }
+ sb.append('>');
+ sb.append(rawType.substring(rawType.length() - 1));
+ return sb.toString();
+ }
+ if (type instanceof TypeVariable) {
+ return "T" + ((TypeVariable<?>)type).getName() + ";";
+ }
+ if (type instanceof GenericArrayType) {
+ GenericArrayType arrayType = (GenericArrayType)type;
+ return "[" + getSignature(arrayType.getGenericComponentType());
+ }
+ if (type instanceof WildcardType) {
+ WildcardType wType = (WildcardType)type;
+ Type[] types = wType.getUpperBounds();
+ StringBuffer sb = new StringBuffer();
+ if (types.length == 0 || !(types.length == 1 && types[0] == Object.class)) {
+ sb.append('+');
+ for (Type t : types) {
+ sb.append(getSignature(t));
+ }
+ }
+ types = wType.getLowerBounds();
+ if (types.length != 0) {
+ sb.append('-');
+ for (Type t : wType.getLowerBounds()) {
+ sb.append(getSignature(t));
+ }
+ }
+ if (sb.length() == 0) {
+ return "*";
+ }
+ return sb.toString();
+ }
+ }
+ Class<?> cls = (Class<?>)type;
+ return org.objectweb.asm.Type.getDescriptor(cls);
+ }
+
+ /**
+ * Get the actual type arguments a child class has used to extend a generic base class.
+ *
+ * @param baseClass the base class
+ * @param childClass the child class
+ * @return a list of the raw classes for the actual type arguments.
+ */
+ public static <T> List<Class<?>> resovleTypeArguments(Class<T> baseClass, Class<? extends T> childClass) {
+ Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
+ Type type = childClass;
+ // start walking up the inheritance hierarchy until we hit baseClass
+ while (!getErasure(type).equals(baseClass)) {
+ if (type instanceof Class) {
+ // there is no useful information for us in raw types, so just keep going.
+ type = ((Class<?>)type).getGenericSuperclass();
+ } else {
+ ParameterizedType parameterizedType = (ParameterizedType)type;
+ Class<?> rawType = getErasure(parameterizedType.getRawType());
+
+ Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+ TypeVariable<?>[] typeParameters = rawType.getTypeParameters();
+ for (int i = 0; i < actualTypeArguments.length; i++) {
+ resolvedTypes.put(typeParameters[i], actualTypeArguments[i]);
+ }
+
+ if (!rawType.equals(baseClass)) {
+ type = rawType.getGenericSuperclass();
+ }
+ }
+ }
+
+ // finally, for each actual type argument provided to baseClass, determine (if possible)
+ // the raw class for that type argument.
+ Type[] actualTypeArguments;
+ if (type instanceof Class) {
+ actualTypeArguments = ((Class<?>)type).getTypeParameters();
+ } else {
+ actualTypeArguments = ((ParameterizedType)type).getActualTypeArguments();
+ }
+ List<Class<?>> typeArgumentsAsClasses = new ArrayList<Class<?>>();
+ // resolve types by chasing down type variables.
+ for (Type baseType : actualTypeArguments) {
+ while (resolvedTypes.containsKey(baseType)) {
+ baseType = resolvedTypes.get(baseType);
+ }
+ typeArgumentsAsClasses.add(getErasure(baseType));
+ }
+ return typeArgumentsAsClasses;
+ }
+
+ /*
+ 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 int getLoadOPCode(String signature) {
+ if ("Z".equals(signature) || "B".equals(signature)
+ || "C".equals(signature)
+ || "S".equals(signature)
+ || "I".equals(signature)) {
+ return Opcodes.ILOAD;
+ }
+
+ if ("J".equals(signature)) {
+ return Opcodes.LLOAD;
+ }
+
+ if ("F".equals(signature)) {
+ return Opcodes.FLOAD;
+ }
+
+ if ("D".equals(signature)) {
+ return Opcodes.DLOAD;
+ }
+
+ return Opcodes.ALOAD;
+
+ }
+
+ public static int getReturnOPCode(String signature) {
+ if ("Z".equals(signature) || "B".equals(signature)
+ || "C".equals(signature)
+ || "S".equals(signature)
+ || "I".equals(signature)) {
+ return Opcodes.IRETURN;
+ }
+
+ if ("J".equals(signature)) {
+ return Opcodes.LRETURN;
+ }
+
+ if ("F".equals(signature)) {
+ return Opcodes.FRETURN;
+ }
+
+ if ("D".equals(signature)) {
+ return Opcodes.DRETURN;
+ }
+ if ("V".equals(signature)) {
+ return Opcodes.RETURN;
+ }
+
+ return Opcodes.ARETURN;
+
+ }
+
+ /**
+ * Get the package prefix for generated JAXWS artifacts
+ * @param cls
+ * @return
+ */
+ public static String getPackagePrefix(Class<?> cls) {
+ String name = cls.getName();
+ int index = name.lastIndexOf('.');
+ if (index == -1) {
+ return "jaxws.";
+ } else {
+ return name.substring(0, index) + ".jaxws.";
+ }
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/GeneratedClassLoader.java b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/GeneratedClassLoader.java
new file mode 100644
index 0000000000..5d296dfe12
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/GeneratedClassLoader.java
@@ -0,0 +1,86 @@
+/*
+ * 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.interfacedef.java.jaxrs;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashMap;
+import java.util.Map;
+
+public class GeneratedClassLoader extends URLClassLoader {
+ private class GeneratedClass {
+ private String className;
+ private byte[] byteCode;
+ private Class<?> cls;
+
+ public GeneratedClass(String className, byte[] byteCode) {
+ super();
+ this.className = className;
+ this.byteCode = byteCode;
+ }
+
+ public synchronized Class<?> getGeneratedClass() {
+ if (cls == null) {
+ cls = defineClass(className, byteCode, 0, byteCode.length);
+ }
+ return cls;
+ }
+ }
+
+ private Map<String, GeneratedClass> generatedClasses = new HashMap<String, GeneratedClass>();
+
+ public GeneratedClassLoader(ClassLoader parentLoader) {
+ super(new URL[0], parentLoader);
+ }
+
+ @Override
+ protected Class<?> findClass(String className) throws ClassNotFoundException {
+ GeneratedClass cls = generatedClasses.get(className);
+ if (cls != null) {
+ return cls.getGeneratedClass();
+ }
+ return super.findClass(className);
+ }
+
+ public synchronized Class<?> getGeneratedClass(String className, byte[] byteCode) {
+ GeneratedClass cls = generatedClasses.get(className);
+ if (cls == null) {
+ cls = new GeneratedClass(className, byteCode);
+ generatedClasses.put(className, cls);
+ }
+ return cls.getGeneratedClass();
+ }
+
+ @Override
+ public String toString() {
+ if( getParent() != null ) {
+ return "java.net.URLClassLoader:\n"
+ + "hashcode: " + hashCode() + "\n"
+ + "URLs: " + java.util.Arrays.asList(
+ getURLs() ) + "\n"
+ + "parent { " + getParent() + " }\n";
+ } else {
+ return "java.net.URLClassLoader:\n"
+ + "hashcode: " + hashCode() + "\n"
+ + "URLs: " + java.util.Arrays.asList(
+ getURLs() ) + "\n";
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSJavaInterfaceProcessor.java b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSJavaInterfaceProcessor.java
new file mode 100644
index 0000000000..83f88c98cb
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSJavaInterfaceProcessor.java
@@ -0,0 +1,116 @@
+/*
+ * 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.interfacedef.java.jaxrs;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.OPTIONS;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor;
+
+public class JAXRSJavaInterfaceProcessor implements JavaInterfaceVisitor {
+ private static Map<String, Class<?>> mapping = new HashMap<String, Class<?>>();
+ static {
+ mapping.put(HttpMethod.GET, GET.class);
+ mapping.put(HttpMethod.POST, POST.class);
+ mapping.put(HttpMethod.PUT, PUT.class);
+ mapping.put(HttpMethod.DELETE, DELETE.class);
+ mapping.put(HttpMethod.HEAD, HEAD.class);
+ mapping.put(HttpMethod.OPTIONS, OPTIONS.class);
+ }
+
+ private boolean introspectHTTPMethod(JavaOperation operation) {
+ Method method = operation.getJavaMethod();
+
+ String methodName = null;
+
+ /**
+ * A request method designator is a runtime annotation that is annotated with the @HttpMethod annotation.
+ * JAX-RS defines a set of request method designators for the common HTTP methods: @GET, @POST, @PUT,
+ * @DELETE, @HEAD. Users may define their own custom request method designators including alternate
+ * designators for the common HTTP methods.
+ */
+ for (Annotation a : method.getAnnotations()) {
+ Class<?> annotationType = a.annotationType();
+ if (annotationType == HttpMethod.class) {
+ methodName = ((HttpMethod)a).value();
+ break;
+ }
+ // Http method related annotations such as @GET, @POST will have itself annotated with
+ // @HttpMethod
+ HttpMethod m = a.annotationType().getAnnotation(HttpMethod.class);
+ if (m != null) {
+ methodName = m.value();
+ break;
+ }
+ }
+
+ boolean jaxrs = false;
+ Class<?> type = mapping.get(methodName);
+ if (type != null) {
+ jaxrs = true;
+ operation.getAttributes().put(type, Boolean.TRUE);
+ Map<Object, Object> attrs = operation.getInterface().getAttributes();
+ List<Operation> operations = (List<Operation>)attrs.get(type);
+ if (operations == null) {
+ operations = new ArrayList<Operation>();
+ attrs.put(type, operations);
+ operations.add(operation);
+ } else {
+ operations.add(operation);
+ }
+ }
+
+ return jaxrs;
+
+ }
+
+ public void visitInterface(JavaInterface contract) throws InvalidInterfaceException {
+
+ boolean hasJAXRSAnnotarions = false;
+
+ for (Operation op : contract.getOperations()) {
+ final JavaOperation operation = (JavaOperation)op;
+ if (introspectHTTPMethod(operation)) {
+ hasJAXRSAnnotarions = true;
+ }
+ }
+
+ // Always set JAX-RS annotated interfaces as remotables
+ if (hasJAXRSAnnotarions) {
+ contract.setRemotable(true);
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGenerator.java b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGenerator.java
new file mode 100644
index 0000000000..c9fc8aafe3
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGenerator.java
@@ -0,0 +1,231 @@
+/*
+ * 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.interfacedef.java.jaxrs;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+public class RootResourceClassGenerator implements Opcodes {
+
+ private static final String DELEGATE_FIELD = "delegate";
+
+ public static Class<?> generateRootResourceClass(Class<?> interfaze, String path, String consumes, String produces)
+ throws Exception {
+ if (!interfaze.isInterface()) {
+ throw new IllegalArgumentException(interfaze + " is not an interface.");
+ }
+ GeneratedClassLoader classLoader = new GeneratedClassLoader(interfaze.getClassLoader());
+ String interfaceName = interfaze.getName();
+ int index = interfaze.getName().lastIndexOf('.');
+ String className =
+ interfaceName.substring(0, index) + ".Generated" + interfaceName.substring(index + 1) + "Impl";
+
+ final byte[] content = generate(interfaze, path, consumes, produces);
+ Class<?> cls = classLoader.getGeneratedClass(className, content);
+ return cls;
+ }
+
+ public static void injectProxy(Class<?> generatedResourceClass, Object proxy) throws Exception {
+ Field field = generatedResourceClass.getField("delegate");
+ field.set(null, proxy);
+ }
+
+ public static byte[] generate(Class<?> interfaze, String path, String consumes, String produces) throws Exception {
+ String interfaceName = Type.getInternalName(interfaze);
+ int index = interfaceName.lastIndexOf('/');
+ String className =
+ interfaceName.substring(0, index) + "/Generated" + interfaceName.substring(index + 1) + "Impl";
+
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+
+ declareClass(cw, interfaceName, className);
+
+ annotatePath(cw, path);
+ annotateContentTypes(cw, consumes, produces);
+ declareField(cw, interfaceName);
+ declareConstructor(cw, className);
+
+ for (Method method : interfaze.getMethods()) {
+ if (!(method.getDeclaringClass() == Object.class)) {
+ generateMethod(cw, interfaceName, className, method, consumes, produces);
+ }
+ }
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+
+ // public <ReturnType> method(<Type0> arg0, ..., <TypeN> argN) throws <ExpectionType0>, ..., <ExceptionTypeK>
+ private static void generateMethod(ClassWriter cw,
+ String interfaceName,
+ String className,
+ Method method,
+ String consumes,
+ String produces) {
+ String methodDescriptor = Type.getMethodDescriptor(method);
+
+ String signatureString = getSignature(method);
+
+ MethodVisitor mv =
+ cw.visitMethod(ACC_PUBLIC,
+ method.getName(),
+ methodDescriptor,
+ signatureString,
+ getExceptionInternalNames(method));
+
+ mv.visitCode();
+ mv.visitFieldInsn(GETSTATIC, className, DELEGATE_FIELD, getSignature(interfaceName));
+ Class<?>[] paramTypes = method.getParameterTypes();
+ for (int i = 0; i < paramTypes.length; i++) {
+ String signature = Type.getDescriptor(paramTypes[i]);
+ mv.visitVarInsn(CodeGenerationHelper.getLoadOPCode(signature), i + 1);
+ }
+ mv.visitMethodInsn(INVOKEINTERFACE, interfaceName, method.getName(), methodDescriptor);
+
+ Class<?> returnType = method.getReturnType();
+ mv.visitInsn(CodeGenerationHelper.getReturnOPCode(Type.getDescriptor(returnType)));
+ int size = paramTypes.length + 1;
+ mv.visitMaxs(size, size);
+ mv.visitEnd();
+ }
+
+ /**
+ * [rfeng] A hack to get the generic method signature
+ * @param method
+ * @return
+ */
+ private static String getSignature(Method method) {
+ try {
+ Field field = method.getClass().getDeclaredField("signature");
+ field.setAccessible(true);
+ return (String)field.get(method);
+ } catch (Throwable e) {
+ return null;
+ }
+ }
+
+ private static String[] getExceptionInternalNames(Method method) {
+ Class<?>[] types = method.getExceptionTypes();
+ if (types.length == 0) {
+ return null;
+ }
+ String[] names = new String[types.length];
+ for (int i = 0; i < types.length; i++) {
+ names[i] = Type.getInternalName(types[i]);
+ }
+ return names;
+ }
+
+ private static String getSignature(String interfaceName) {
+ return "L" + interfaceName + ";";
+ }
+
+ private static void declareConstructor(ClassWriter cw, String className) {
+ MethodVisitor mv;
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ Label l0 = new Label();
+ mv.visitLabel(l0);
+ // mv.visitLineNumber(37, l0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+ mv.visitInsn(RETURN);
+ Label l1 = new Label();
+ mv.visitLabel(l1);
+ mv.visitLocalVariable("this", getSignature(className), null, l0, l1, 0);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+
+ // public static <Interface> delegate;
+ private static void declareField(ClassWriter cw, String interfaceName) {
+ FieldVisitor fv =
+ cw.visitField(ACC_PUBLIC + ACC_STATIC, DELEGATE_FIELD, getSignature(interfaceName), null, null);
+ fv.visitEnd();
+ }
+
+ // public class _<Interface>Impl implements <Interface>
+ private static void declareClass(ClassWriter cw, String interfaceName, String className) {
+ cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, null, "java/lang/Object", new String[] {interfaceName});
+ }
+
+ // @Path(<path>)
+ private static void annotatePath(ClassWriter cw, String path) {
+ AnnotationVisitor av = cw.visitAnnotation("Ljavax/ws/rs/Path;", true);
+ av.visit("value", path);
+ av.visitEnd();
+ }
+
+ // @Consumes(<contentTypes>)
+ // @Provides(<contentTypes>)
+ private static void annotateContentTypes(ClassWriter cw, String consumes, String produces) {
+ AnnotationVisitor av = null;
+ if (consumes != null) {
+ av = cw.visitAnnotation("Ljavax/ws/rs/Consumes;", true);
+ AnnotationVisitor av1 = av.visitArray("value");
+ for (String s : consumes.split("(,| )")) {
+ av1.visit(null, s.trim());
+ }
+ av1.visitEnd();
+ av.visitEnd();
+ }
+ if (produces != null) {
+ av = cw.visitAnnotation("Ljavax/ws/rs/Produces;", true);
+ AnnotationVisitor av1 = av.visitArray("value");
+ for (String s : produces.split("(,| )")) {
+ av1.visit(null, s.trim());
+ }
+ av1.visitEnd();
+ av.visitEnd();
+ }
+ }
+
+ // @Consumes(<contentTypes>)
+ // @Provides(<contentTypes>)
+ private static void annotateContentTypes(MethodVisitor mv, String consumes, String produces) {
+ AnnotationVisitor av = null;
+ if (consumes != null) {
+ av = mv.visitAnnotation("Ljavax/ws/rs/Consumes;", true);
+ AnnotationVisitor av1 = av.visitArray("value");
+ for (String s : consumes.split("(,| )")) {
+ av1.visit(null, s.trim());
+ }
+ av1.visitEnd();
+ av.visitEnd();
+ }
+ if (produces != null) {
+ av = mv.visitAnnotation("Ljavax/ws/rs/Produces;", true);
+ AnnotationVisitor av1 = av.visitArray("value");
+ for (String s : produces.split("(,| )")) {
+ av1.visit(null, s.trim());
+ }
+ av1.visitEnd();
+ av.visitEnd();
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/resources/META-INF/services/org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/resources/META-INF/services/org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor
new file mode 100644
index 0000000000..9101d744b3
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/main/resources/META-INF/services/org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor
@@ -0,0 +1,17 @@
+# 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.
+org.apache.tuscany.sca.interfacedef.java.jaxrs.JAXRSJavaInterfaceProcessor;ranking=100
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/Bean.java b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/Bean.java
new file mode 100644
index 0000000000..20a4276b8b
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/Bean.java
@@ -0,0 +1,31 @@
+/*
+ * 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.interfacedef.java.jaxrs;
+
+import javax.ws.rs.GET;
+
+import org.oasisopen.sca.annotation.Remotable;
+
+@Remotable
+public interface Bean {
+
+ @GET
+ String[] get();
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSInterfaceProcessorTestCase.java b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSInterfaceProcessorTestCase.java
new file mode 100644
index 0000000000..b680eaa491
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSInterfaceProcessorTestCase.java
@@ -0,0 +1,66 @@
+package org.apache.tuscany.sca.interfacedef.java.jaxrs;
+/*
+ * 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.
+ */
+
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import javax.ws.rs.GET;
+
+import junit.framework.Assert;
+
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.DefaultJavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class JAXRSInterfaceProcessorTestCase {
+ private ExtensionPointRegistry registry;
+
+ @Before
+ public void setUp() throws Exception {
+ registry = new DefaultExtensionPointRegistry();
+ }
+
+ @Test
+ public final void testProcessor() throws Exception {
+ DefaultJavaInterfaceFactory iFactory = new DefaultJavaInterfaceFactory(registry);
+ JavaInterface contract = iFactory.createJavaInterface(Bean.class);
+
+ assertTrue(contract.isRemotable());
+
+ Assert.assertEquals(1,contract.getOperations().size());
+
+ List<Operation> getOperations = (List<Operation>) contract.getAttributes().get(GET.class);
+ Assert.assertEquals(1,getOperations.size());
+
+ //list operation
+ System.out.println(">>> JAX-RS Operations");
+ for(Operation o : contract.getOperations()) {
+ System.out.println(">>>>>>" + o);
+ }
+
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/MockedResource.java b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/MockedResource.java
new file mode 100644
index 0000000000..7940a9e145
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/MockedResource.java
@@ -0,0 +1,51 @@
+/*
+ * 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.interfacedef.java.jaxrs;
+
+import java.util.List;
+
+public class MockedResource implements Resource {
+ private String value;
+
+ public MockedResource() {
+ super();
+ }
+
+ public String get() {
+ return value;
+ }
+
+ public void create(String value) {
+ this.value = value;
+ }
+
+ public void delete() {
+ value = null;
+ }
+
+ public void update(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String getList(List<String> names) {
+ return value;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/Resource.java b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/Resource.java
new file mode 100644
index 0000000000..00d0fe9264
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/Resource.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.interfacedef.java.jaxrs;
+
+import java.util.List;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.QueryParam;
+
+import org.oasisopen.sca.annotation.Remotable;
+
+@Remotable
+public interface Resource {
+
+ @GET
+ String get();
+
+ @GET
+ String getList(@QueryParam("list") List<String> names);
+
+ @PUT
+ void update(String value);
+
+ @POST
+ void create(String value);
+
+ @DELETE
+ void delete();
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/ResourceWrapper.java b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/ResourceWrapper.java
new file mode 100644
index 0000000000..40e0bf7d2a
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/ResourceWrapper.java
@@ -0,0 +1,59 @@
+/*
+ * 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.interfacedef.java.jaxrs;
+
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+@Path("myURI")
+@Produces({"application/xml", "application/json"})
+@Consumes({"application/xml", "application/json"})
+public class ResourceWrapper implements Resource {
+ public static Resource delegate;
+
+ public ResourceWrapper() {
+ super();
+ }
+
+ public String get() {
+ return delegate.get();
+ }
+
+ public void create(String value) {
+ delegate.create(value);
+ }
+
+ public void delete() {
+ delegate.delete();
+ }
+
+ public void update(String value) {
+ delegate.update(value);
+ }
+
+ @Override
+ public String getList(List<String> names) {
+ return delegate.getList(names);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGeneratorTestCase.java b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGeneratorTestCase.java
new file mode 100644
index 0000000000..0a761df6b8
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGeneratorTestCase.java
@@ -0,0 +1,84 @@
+/*
+ * 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.interfacedef.java.jaxrs;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class RootResourceClassGeneratorTestCase {
+ @Test
+ public void testGenerator() throws Exception {
+ Class<?> cls =
+ RootResourceClassGenerator.generateRootResourceClass(Resource.class,
+ "myURI",
+ "application/xml,application/json",
+ "application/xml,application/json");
+ Assert.assertTrue(cls.isAnnotationPresent(Path.class));
+ Path path = cls.getAnnotation(Path.class);
+ Assert.assertEquals("myURI", path.value());
+
+ Produces produces = cls.getAnnotation(Produces.class);
+ Assert.assertEquals("application/xml", produces.value()[0]);
+
+ Consumes consumes = cls.getAnnotation(Consumes.class);
+ Assert.assertEquals("application/json", consumes.value()[1]);
+
+ Field field = cls.getField("delegate");
+ Assert.assertSame(Resource.class, field.getType());
+
+ Assert.assertTrue(Modifier.isPublic(field.getModifiers()));
+ Assert.assertTrue(Modifier.isStatic(field.getModifiers()));
+
+ Assert.assertTrue(Resource.class.isAssignableFrom(cls));
+
+ Method m = cls.getMethod("getList", List.class);
+ System.out.println(m.toGenericString());
+ Type type = m.getGenericParameterTypes()[0];
+ Assert.assertTrue(type instanceof ParameterizedType);
+ ParameterizedType pType = (ParameterizedType)type;
+ Assert.assertEquals(String.class, pType.getActualTypeArguments()[0]);
+
+ Resource resource = new MockedResource();
+ field.set(null, resource);
+
+ Resource resourceProxy = (Resource)cls.newInstance();
+ Assert.assertNull(resourceProxy.get());
+ resourceProxy.create("123");
+ Assert.assertEquals("123", resourceProxy.get());
+ resourceProxy.update("ABC");
+ Assert.assertEquals("ABC", resourceProxy.get());
+ resourceProxy.delete();
+ Assert.assertNull(resourceProxy.get());
+ }
+}