From d683dc4b30c79348b5e73f0f11b1cfd8ce4b9812 Mon Sep 17 00:00:00 2001 From: rfeng Date: Wed, 19 May 2010 00:53:52 +0000 Subject: Merge branch 'jaxrs' into trunk git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@945980 13f79535-47bb-0310-9956-ffa450edef68 --- sca-java-2.x/trunk/distribution/all/pom.xml | 2 + .../all/src/main/components/bin-samples.xml | 3 + .../distribution/all/src/main/release/bin/LICENSE | 10 +- sca-java-2.x/trunk/features/web20/pom.xml | 7 + .../src/main/resources/CallBackBasicTest.composite | 9 +- .../sca/itest/scdl/ContributionTestCase.java | 4 +- .../trunk/modules/binding-jsonrpc-runtime/pom.xml | 4 +- .../binding/jsonrpc/JSONRPCDataTypeTestCase.java | 8 +- .../binding-rest-runtime/META-INF/MANIFEST.MF | 6 + .../trunk/modules/binding-rest-runtime/pom.xml | 23 +- .../JAXRSOperationSelectorInterceptor.java | 5 + .../rest/provider/DataBindingJAXRSProvider.java | 201 +++++++++++++++++ .../rest/provider/DataBindingJAXRSReader.java | 84 +++++++ .../rest/provider/DataBindingJAXRSWriter.java | 86 ++++++++ .../binding/rest/provider/RESTBindingInvoker.java | 103 +++++++++ .../rest/provider/RESTBindingProviderFactory.java | 3 +- .../provider/RESTReferenceBindingProvider.java | 64 ++++++ .../rest/provider/RESTServiceBindingProvider.java | 242 +++++++++++++++++---- .../binding/rest/provider/TuscanyRESTServlet.java | 94 ++++++++ .../json/provider/JSONWireFormatInterceptor.java | 4 +- .../provider/JSONWireFormatServiceProvider.java | 31 ++- .../xml/provider/XMLWireFormatServiceProvider.java | 34 ++- .../sca/binding/rest/rpc/EchoServiceTestCase.java | 4 + .../wireformat/binary/BinaryServiceTestCase.java | 4 +- .../wireformat/json/CatalogServiceTestCase.java | 15 +- .../wireformat/xml/CustomerServiceTestCase.java | 11 +- .../src/test/java/services/store/Catalog.java | 2 +- .../java/services/store/FruitsCatalogImpl.java | 9 +- .../src/test/java/services/store/Items.java | 37 ++++ .../builder/impl/EndpointReferenceBuilderImpl.java | 20 +- .../tuscany/sca/databinding/json/JSONHelper.java | 14 +- .../databinding/json/jackson/InputStream2JSON.java | 49 +++++ .../sca/databinding/json/jackson/JSON2Object.java | 3 +- .../json/jackson/JSON2OutputStream.java | 65 ++++++ .../databinding/json/jackson/JacksonHelper.java | 46 ++++ ....apache.tuscany.sca.databinding.PullTransformer | 22 +- ....apache.tuscany.sca.databinding.PushTransformer | 34 +++ .../sdo/DataObject2XMLStreamReaderTestCase.java | 2 +- .../sca/databinding/DataBindingContext.java | 95 ++++++++ .../sca/databinding/xml/InputSource2Node.java | 11 +- .../sca/databinding/xml/InputStream2Node.java | 9 +- .../sca/databinding/xml/Node2OutputStream.java | 9 +- .../tuscany/sca/databinding/xml/Node2String.java | 10 +- .../tuscany/sca/databinding/xml/Node2Writer.java | 9 +- .../tuscany/sca/databinding/xml/Reader2Node.java | 10 +- .../databinding/xml/Source2ResultTransformer.java | 12 +- .../databinding/xml/Source2StringTransformer.java | 12 +- .../sca/databinding/impl/MediatorImplTestCase.java | 4 +- .../sca/databinding/xml/DataPipeTestCase.java | 6 +- .../sca/databinding/xml/Node2StringTestCase.java | 6 +- .../xml/PushTransformationTestCase.java | 2 +- .../databinding/xml/TraxTransformerTestCase.java | 13 +- .../META-INF/MANIFEST.MF | 12 +- .../modules/implementation-jaxrs-runtime/pom.xml | 14 +- .../provider/JAXRSImplementationProvider.java | 10 +- .../helloworld/jaxrs/test/HelloWorldTestCase.java | 4 +- .../implementation-jaxrs/META-INF/MANIFEST.MF | 6 +- .../trunk/modules/implementation-jaxrs/pom.xml | 14 +- .../jaxrs/impl/JAXRSImplementationImpl.java | 9 - .../jaxrs/xml/JAXRSImplementationProcessor.java | 55 +++++ .../interface-java-jaxrs/META-INF/MANIFEST.MF | 2 +- .../trunk/modules/interface-java-jaxrs/pom.xml | 2 +- .../java/jaxrs/JAXRSJavaInterfaceProcessor.java | 110 +++++----- .../java/jaxrs/RootResourceClassGenerator.java | 40 +++- .../interfacedef/java/jaxrs/ResourceWrapper.java | 4 + .../jaxrs/RootResourceClassGeneratorTestCase.java | 11 +- sca-java-2.x/trunk/modules/wink/pom.xml | 4 +- 67 files changed, 1646 insertions(+), 223 deletions(-) create mode 100644 sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSProvider.java create mode 100644 sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSReader.java create mode 100644 sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java create mode 100644 sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java create mode 100644 sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTReferenceBindingProvider.java create mode 100644 sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/TuscanyRESTServlet.java create mode 100644 sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/Items.java create mode 100644 sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/InputStream2JSON.java create mode 100644 sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2OutputStream.java create mode 100644 sca-java-2.x/trunk/modules/databinding-json/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PushTransformer create mode 100644 sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBindingContext.java (limited to 'sca-java-2.x/trunk') diff --git a/sca-java-2.x/trunk/distribution/all/pom.xml b/sca-java-2.x/trunk/distribution/all/pom.xml index cd8208ca9e..dd370b5ddd 100644 --- a/sca-java-2.x/trunk/distribution/all/pom.xml +++ b/sca-java-2.x/trunk/distribution/all/pom.xml @@ -73,6 +73,7 @@ 1.6.8 + diff --git a/sca-java-2.x/trunk/distribution/all/src/main/components/bin-samples.xml b/sca-java-2.x/trunk/distribution/all/src/main/components/bin-samples.xml index 684bf98f82..86820a0011 100644 --- a/sca-java-2.x/trunk/distribution/all/src/main/components/bin-samples.xml +++ b/sca-java-2.x/trunk/distribution/all/src/main/components/bin-samples.xml @@ -49,6 +49,9 @@ webapps/helloworld-jsp/**/* webapps/helloworld-servlet/**/* webapps/helloworld-stripes/**/* + launcher-embedded-jse/**/* + launcher-embedded-osgi/**/* + launcher-command-line//**/* diff --git a/sca-java-2.x/trunk/distribution/all/src/main/release/bin/LICENSE b/sca-java-2.x/trunk/distribution/all/src/main/release/bin/LICENSE index d5e91eb384..b2394e5918 100644 --- a/sca-java-2.x/trunk/distribution/all/src/main/release/bin/LICENSE +++ b/sca-java-2.x/trunk/distribution/all/src/main/release/bin/LICENSE @@ -317,8 +317,9 @@ The following components come under Apache Software License 2.0 stripes-1.5.2.jar tranql-connector-1.1.jar tribes-6.0.26.jar - wink-common-1.0-incubating.jar - wink-server-1.0-incubating.jar + wink-common-1.1-incubating.jar + wink-client-1.1-incubating.jar + wink-server-1.1-incubating.jar woden-api-1.0M8.jar woden-impl-dom-1.0M8.jar wss4j-1.5.4.jar @@ -700,7 +701,7 @@ jsr250-api-1.0.jar, jstl-1.1.2.jar, mail-1.4.jar, servlet-api-2.5.jar, -jsr311-api-1.0.jar +jsr311-api-1.1.jar COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 @@ -1495,8 +1496,7 @@ THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -The slf4j-api-1.5.8.jar, slf4j-jdk14-1.5.8.jar, and slf4j-simple-1.5.8.jar -are distributed under the license: +The slf4j-api-1.5.11.jar and slf4j-jdk14-1.5.11.jar are distributed under the license: Copyright (c) 2004-2008 QOS.ch All rights reserved. diff --git a/sca-java-2.x/trunk/features/web20/pom.xml b/sca-java-2.x/trunk/features/web20/pom.xml index 38ffb56011..06ddd8c3a1 100644 --- a/sca-java-2.x/trunk/features/web20/pom.xml +++ b/sca-java-2.x/trunk/features/web20/pom.xml @@ -121,6 +121,13 @@ 2.0-SNAPSHOT + + + org.apache.tuscany.sca + tuscany-implementation-widget-runtime-dojo + 2.0-SNAPSHOT + + org.apache.tuscany.sca diff --git a/sca-java-2.x/trunk/itest/callback-basic-ws/src/main/resources/CallBackBasicTest.composite b/sca-java-2.x/trunk/itest/callback-basic-ws/src/main/resources/CallBackBasicTest.composite index 42acda4714..5e77ac2b91 100644 --- a/sca-java-2.x/trunk/itest/callback-basic-ws/src/main/resources/CallBackBasicTest.composite +++ b/sca-java-2.x/trunk/itest/callback-basic-ws/src/main/resources/CallBackBasicTest.composite @@ -24,9 +24,9 @@ - - - + + + @@ -34,6 +34,9 @@ + + + diff --git a/sca-java-2.x/trunk/itest/scdl/src/test/java/org/apache/tuscany/sca/itest/scdl/ContributionTestCase.java b/sca-java-2.x/trunk/itest/scdl/src/test/java/org/apache/tuscany/sca/itest/scdl/ContributionTestCase.java index e2f28f0bb1..e70fc4086d 100644 --- a/sca-java-2.x/trunk/itest/scdl/src/test/java/org/apache/tuscany/sca/itest/scdl/ContributionTestCase.java +++ b/sca-java-2.x/trunk/itest/scdl/src/test/java/org/apache/tuscany/sca/itest/scdl/ContributionTestCase.java @@ -47,7 +47,7 @@ public class ContributionTestCase { @Test public void testRead() throws Exception { Deployer deployer = new DefaultDeployer(); - File file = new File("../../samples/calculator/target/sample-calculator.jar"); + File file = new File("../../samples/contribution-binding-sca-calculator/target/sample-contribution-binding-sca-calculator.jar"); URL url = file.toURI().toURL(); Monitor monitor = deployer.createMonitor(); Contribution contribution = deployer.loadContribution(url.toURI(), url, monitor); @@ -56,7 +56,7 @@ public class ContributionTestCase { // Ferkle around in the contribution verifying it looks as expected Assert.assertNotNull(contribution); List deployables = contribution.getDeployables(); - Assert.assertEquals(1, deployables.size()); + Assert.assertEquals(2, deployables.size()); Composite calculatorComposte = deployables.get(0); Assert.assertEquals("Calculator", calculatorComposte.getName().getLocalPart()); Assert.assertEquals(5, calculatorComposte.getComponents().size()); diff --git a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/pom.xml b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/pom.xml index 6d0cace493..c5c7e3740f 100644 --- a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/pom.xml +++ b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/pom.xml @@ -89,12 +89,12 @@ org.slf4j slf4j-api - 1.5.8 + 1.5.11 org.slf4j slf4j-jdk14 - 1.5.8 + 1.5.11 diff --git a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/test/java/org/apache/tuscany/sca/binding/jsonrpc/JSONRPCDataTypeTestCase.java b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/test/java/org/apache/tuscany/sca/binding/jsonrpc/JSONRPCDataTypeTestCase.java index b84df66f40..0fd622d29b 100644 --- a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/test/java/org/apache/tuscany/sca/binding/jsonrpc/JSONRPCDataTypeTestCase.java +++ b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/test/java/org/apache/tuscany/sca/binding/jsonrpc/JSONRPCDataTypeTestCase.java @@ -133,7 +133,7 @@ public class JSONRPCDataTypeTestCase { @Test public void testList() throws Exception { JSONObject jsonRequest = new JSONObject( - "{ \"method\": \"echoList\", \"params\": [ {\"javaClass\": \"java.util.ArrayList\", \"list\": [0,1,2,3,4]}], \"id\": 8}"); + "{ \"method\": \"echoList\", \"params\": [[0,1,2,3,4]], \"id\": 8}"); WebConversation wc = new WebConversation(); WebRequest request = new PostMethodWebRequest(SERVICE_URL, @@ -144,7 +144,7 @@ public class JSONRPCDataTypeTestCase { JSONObject jsonResp = new JSONObject(response.getText()); - Assert.assertEquals(0, jsonResp.getJSONObject("result").getJSONArray("list").get(0)); + Assert.assertEquals(0, jsonResp.getJSONArray("result").get(0)); } @Test @@ -186,7 +186,7 @@ public class JSONRPCDataTypeTestCase { @Test public void testSet() throws Exception { JSONObject jsonRequest = new JSONObject( - "{ \"method\": \"echoSet\", \"params\": [ {\"javaClass\": \"java.util.HashSet\", \"set\": {\"1\": \"red\", \"2\": \"blue\"}}],\"id\": 11}"); + "{ \"method\": \"echoSet\", \"params\": [[\"red\", \"blue\"]],\"id\": 11}"); WebConversation wc = new WebConversation(); WebRequest request = new PostMethodWebRequest(SERVICE_URL, @@ -197,6 +197,6 @@ public class JSONRPCDataTypeTestCase { JSONObject jsonResp = new JSONObject(response.getText()); - Assert.assertEquals("red", jsonResp.getJSONObject("result").getJSONObject("set").getString("red")); + Assert.assertEquals("red", jsonResp.getJSONArray("result").get(0)); } } \ No newline at end of file diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/binding-rest-runtime/META-INF/MANIFEST.MF index fb9b582d84..80758692b0 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/META-INF/MANIFEST.MF +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/META-INF/MANIFEST.MF @@ -18,11 +18,17 @@ Import-Package: javax.servlet, org.apache.tuscany.sca.binding.rest.wireformat.xml;version="2.0.0", org.apache.tuscany.sca.common.http;version="2.0.0", org.apache.tuscany.sca.core;version="2.0.0", + org.apache.tuscany.sca.databinding;version="2.0.0", + org.apache.tuscany.sca.databinding.javabeans;version="2.0.0", + org.apache.tuscany.sca.databinding.xml;version="2.0.0", org.apache.tuscany.sca.host.http;version="2.0.0", org.apache.tuscany.sca.interfacedef;version="2.0.0", + org.apache.tuscany.sca.interfacedef.impl;version="2.0.0", + org.apache.tuscany.sca.interfacedef.util;version="2.0.0", org.apache.tuscany.sca.invocation;version="2.0.0", org.apache.tuscany.sca.provider;version="2.0.0", org.apache.tuscany.sca.runtime;version="2.0.0", + org.oasisopen.sca;version="2.0.0", org.oasisopen.sca.annotation;version="2.0.0" Bundle-SymbolicName: org.apache.tuscany.sca.binding.rest.runtime Bundle-DocURL: http://www.apache.org/ diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/pom.xml b/sca-java-2.x/trunk/modules/binding-rest-runtime/pom.xml index 7dd4f380a5..fcdad0080e 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/pom.xml +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/pom.xml @@ -35,11 +35,12 @@ tuscany-binding-rest 2.0-SNAPSHOT + javax.ws.rs jsr311-api - 1.0 + 1.1 @@ -60,6 +61,12 @@ 2.0-SNAPSHOT + + org.apache.tuscany.sca + tuscany-core + 2.0-SNAPSHOT + + org.apache.tuscany.sca tuscany-databinding @@ -109,7 +116,7 @@ org.apache.tuscany.sca tuscany-interface-java-jaxrs 2.0-SNAPSHOT - test + compile @@ -119,6 +126,18 @@ test + + org.apache.wink + wink-server + 1.1-incubating + + + + org.apache.wink + wink-client + 1.1-incubating + + httpunit httpunit diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java index a79cd7dcf9..928b80a044 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java @@ -83,6 +83,11 @@ public class JAXRSOperationSelectorInterceptor implements Interceptor { public Message invoke(Message msg) { try { HTTPContext bindingContext = (HTTPContext)msg.getBindingContext(); + + // By-pass the operation selector + if (bindingContext == null) { + return getNext().invoke(msg); + } String path = URLDecoder.decode(HTTPUtil.getRequestPath(bindingContext.getHttpRequest()), "UTF-8"); diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSProvider.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSProvider.java new file mode 100644 index 0000000000..d7eeede240 --- /dev/null +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSProvider.java @@ -0,0 +1,201 @@ +/* + * 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.binding.rest.provider; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Reader; +import java.io.StringWriter; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import javax.activation.DataSource; +import javax.jws.WebParam; +import javax.jws.WebResult; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.ext.Provider; +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.databinding.Mediator; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl; +import org.apache.tuscany.sca.interfacedef.util.XMLType; + +/** + * A JAX-RS provider that leverages Tuscany's databinding framework to handle read/write + * for JAX-RS runtime + */ +@Provider +public abstract class DataBindingJAXRSProvider { + protected DataBindingExtensionPoint dataBindingExtensionPoint; + protected Mediator mediator; + + public DataBindingJAXRSProvider(ExtensionPointRegistry registry) { + this.dataBindingExtensionPoint = registry.getExtensionPoint(DataBindingExtensionPoint.class); + UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); + this.mediator = utilities.getUtility(Mediator.class); + } + + protected A getAnnotation(Annotation[] annotations, Class type) { + for (Annotation a : annotations) { + if (a.annotationType() == type) { + return type.cast(a); + } + } + return null; + } + + protected void introspectAnnotations(Annotation[] annotations, DataType targetDataType) { + WebResult result = getAnnotation(annotations, WebResult.class); + if (result != null) { + QName name = new QName(result.targetNamespace(), result.name()); + targetDataType.setLogical(new XMLType(name, null)); + } + + WebParam param = getAnnotation(annotations, WebParam.class); + if (param != null) { + QName name = new QName(param.targetNamespace(), param.name()); + targetDataType.setLogical(new XMLType(name, null)); + } + } + + protected DataType createDataType(Class type, Type genericType) { + DataType dataType = new DataTypeImpl(null, type, type, genericType); + dataBindingExtensionPoint.introspectType(dataType, null); + return dataType; + } + + protected boolean supports(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { + return MediaType.APPLICATION_JSON_TYPE.equals(mediaType) || MediaType.APPLICATION_XML_TYPE.equals(mediaType) + || MediaType.TEXT_XML_TYPE.equals(mediaType); + } + + protected Object convert(InputStream content, String contentType, Class type) throws IOException { + if (type == DataSource.class) { + return type.cast(new InputStreamDataSource(content, contentType)); + } else if (type == InputStream.class) { + return type.cast(content); + } else if (type == Reader.class) { + return type.cast(new InputStreamReader(content, "UTF-8")); + } else if (type == String.class) { + try { + StringWriter sw = new StringWriter(); + InputStreamReader reader = new InputStreamReader(content, "UTF-8"); + char[] buf = new char[8192]; + while (true) { + int size = reader.read(buf); + if (size < 0) { + break; + } + sw.write(buf, 0, size); + } + return type.cast(sw.toString()); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } else if (type == byte[].class) { + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buf = new byte[8192]; + while (true) { + int size = content.read(buf); + if (size < 0) { + break; + } + bos.write(buf, 0, size); + } + return type.cast(bos.toByteArray()); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } else { + return content; + } + } + + protected void write(OutputStream out, Object content, Class type) throws IOException { + if (content == null) { + return; + } + InputStream in = null; + if (DataSource.class.isAssignableFrom(type)) { + in = ((DataSource)content).getInputStream(); + } else if (InputStream.class.isAssignableFrom(type)) { + in = (InputStream)content; + } else if (type == String.class) { + in = new ByteArrayInputStream(((String)content).getBytes("UTF-8")); + } else if (type == byte[].class) { + in = new ByteArrayInputStream((byte[])content); + } + if (in == null) { + throw new IllegalArgumentException("Type is not supported: " + type); + } + byte[] buf = new byte[8192]; + while (true) { + int len = in.read(buf); + if (len < 0) { + in.close(); + break; + } + out.write(buf, 0, len); + } + } + + public static final class InputStreamDataSource implements DataSource { + + public static final String DEFAULT_TYPE = "application/octet-stream"; + + private final InputStream in; + private final String ctype; + + public InputStreamDataSource(InputStream in) { + this(in, null); + } + + public InputStreamDataSource(InputStream in, String ctype) { + this.in = in; + this.ctype = (ctype != null) ? ctype : DEFAULT_TYPE; + } + + public String getContentType() { + return ctype; + } + + public String getName() { + return null; + } + + public InputStream getInputStream() throws IOException { + return in; + } + + public OutputStream getOutputStream() throws IOException { + return null; + } + + } +} diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSReader.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSReader.java new file mode 100644 index 0000000000..035af0aedf --- /dev/null +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSReader.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.binding.rest.provider; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Collections; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.Provider; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl; + +/** + * The generic JAX-RS message body reader based on Tuscany's databindingframework + */ +@Provider +public class DataBindingJAXRSReader extends DataBindingJAXRSProvider implements MessageBodyReader { + + public DataBindingJAXRSReader(ExtensionPointRegistry registry) { + super(registry); + } + + public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { +// DataType dataType = createDataType(type, genericType); + return supports(type, genericType, annotations, mediaType); + } + + public T readFrom(Class type, + Type genericType, + Annotation[] annotations, + MediaType mediaType, + MultivaluedMap httpHeaders, + InputStream entityStream) throws IOException, WebApplicationException { + + Object source = entityStream; + DataType targetDataType = createDataType(type, genericType); + + String dataBinding = null; + + // FIXME: [rfeng] This is a hack to handle application/json + if (MediaType.APPLICATION_JSON_TYPE.equals(mediaType)) { + dataBinding = mediaType.toString() + "#" + InputStream.class.getName(); + } else if (MediaType.APPLICATION_XML_TYPE.equals(mediaType) || MediaType.TEXT_XML_TYPE.equals(mediaType)) { + dataBinding = InputStream.class.getName(); + } else { + dataBinding = targetDataType.getDataBinding(); + source = convert(entityStream, mediaType.toString(), type); + return (T) source; + } + DataType sourceDataType = + new DataTypeImpl(dataBinding, InputStream.class, InputStream.class, InputStream.class); + + Object result = mediator.mediate(source, sourceDataType, targetDataType, Collections.emptyMap()); + return (T)result; + } + + + +} diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java new file mode 100644 index 0000000000..8503d089eb --- /dev/null +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.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.binding.rest.provider; + +import java.io.IOException; +import java.io.OutputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Collections; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Provider; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl; + +/** + * The generic JAX-RS message body writer based on Tuscany's databindingframework + */ +@Provider +public class DataBindingJAXRSWriter extends DataBindingJAXRSProvider implements MessageBodyWriter { + + public DataBindingJAXRSWriter(ExtensionPointRegistry registry) { + super(registry); + } + + public long getSize(T t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { + return -1; + } + + public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { + // DataType dataType = createDataType(type, genericType); + return supports(type, genericType, annotations, mediaType); + } + + public void writeTo(T t, + Class type, + Type genericType, + Annotation[] annotations, + MediaType mediaType, + MultivaluedMap httpHeaders, + OutputStream entityStream) throws IOException, WebApplicationException { + DataType dataType = createDataType(type, genericType); + + String dataBinding = OutputStream.class.getName(); + // FIXME: [rfeng] This is a hack to handle application/json + if (MediaType.APPLICATION_JSON_TYPE.equals(mediaType)) { + dataBinding = mediaType.toString() + "#" + OutputStream.class.getName(); + } else if (MediaType.APPLICATION_XML_TYPE.equals(mediaType) || MediaType.TEXT_XML_TYPE.equals(mediaType)) { + dataBinding = OutputStream.class.getName(); + } else { + dataBinding = dataType.getDataBinding(); + write(entityStream, t, type); + return; + } + DataType targetDataType = + new DataTypeImpl(dataBinding, OutputStream.class, OutputStream.class, OutputStream.class); + // dataBindingExtensionPoint.introspectType(targetDataType, null); + + introspectAnnotations(annotations, targetDataType); + + mediator.mediate(t, entityStream, dataType, targetDataType, Collections. emptyMap()); + } + +} diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java new file mode 100644 index 0000000000..72a0c1a56d --- /dev/null +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java @@ -0,0 +1,103 @@ +/* + * 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.binding.rest.provider; + +import java.lang.reflect.Type; +import java.util.HashMap; +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.binding.rest.RESTBinding; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.wink.client.ClientConfig; +import org.apache.wink.client.EntityType; +import org.apache.wink.client.Resource; +import org.apache.wink.client.RestClient; + +/** + * + */ +public class RESTBindingInvoker implements Invoker { + private RESTBinding binding; + private Operation operation; + + public RESTBindingInvoker(RESTBinding binding, Operation operation) { + super(); + this.binding = binding; + this.operation = operation; + } + + private static Map, String> mapping = new HashMap, String>(); + static { + mapping.put(GET.class, HttpMethod.GET); + mapping.put(POST.class, HttpMethod.POST); + mapping.put(PUT.class, HttpMethod.PUT); + mapping.put(DELETE.class, HttpMethod.DELETE); + mapping.put(HEAD.class, HttpMethod.HEAD); + mapping.put(OPTIONS.class, HttpMethod.OPTIONS); + } + + public Message invoke(Message msg) { + ClientConfig config = new ClientConfig(); + RestClient client = new RestClient(); + Resource resource = client.resource(binding.getURI()); + String method = null; + for (Map.Entry, String> e : mapping.entrySet()) { + if (operation.getAttributes().get(e.getKey()) != null) { + method = e.getValue(); + break; + } + } + EntityType entityType = new EntityType() { + + @Override + public Class getRawClass() { + if (operation.getOutputType() != null) { + return operation.getOutputType().getPhysical(); + } else { + return null; + } + } + + @Override + public Type getType() { + if (operation.getOutputType() != null) { + return operation.getOutputType().getGenericType(); + } else { + return null; + } + } + + }; + Object result = resource.invoke(method, entityType, msg.getBody()); + msg.setBody(result); + return msg; + } + +} diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingProviderFactory.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingProviderFactory.java index 23012f4a6b..7c9ec85a9e 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingProviderFactory.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingProviderFactory.java @@ -50,8 +50,9 @@ public class RESTBindingProviderFactory implements BindingProviderFactory wireFormatToMediaTypeMapping = new HashMap(); + static { + wireFormatToMediaTypeMapping.put(JSONWireFormat.REST_WIREFORMAT_JSON_QNAME, MediaType.APPLICATION_JSON); + wireFormatToMediaTypeMapping.put(XMLWireFormat.REST_WIREFORMAT_XML_QNAME, MediaType.APPLICATION_XML); + } + + private SimpleApplication registerWithJAXRS() { + try { + SimpleApplication application = null; + + JavaInterface javaInterface = (JavaInterface)endpoint.getComponentServiceInterfaceContract().getInterface(); + Class interfaze = javaInterface.getJavaClass(); + + boolean isJAXRS = isJAXRSResource(interfaze); + if (isJAXRS) { + application = new SimpleApplication(interfaze); + + TuscanyRESTServlet restServlet = new TuscanyRESTServlet(extensionPoints); + + // Create our HTTP service listener Servlet and register it with the + // Servlet host + servletMapping = binding.getURI(); + if (!servletMapping.endsWith("/")) { + servletMapping += "/"; + } + if (!servletMapping.endsWith("*")) { + servletMapping += "*"; + } + + servletHost.addServletMapping(servletMapping, restServlet); + RegistrationUtils.registerApplication(application, restServlet.getServletContext()); + return application; + } else { + return null; + } + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + + private class SimpleApplication extends Application { + private Class resourceClass; + + public SimpleApplication(Class resourceClass) { + super(); + // boolean isJAXRS = isJAXRSResource(resourceClass); + // if (isJAXRS) { + if (resourceClass.isInterface()) { + this.resourceClass = generateResourceClass(resourceClass); + } else { + this.resourceClass = resourceClass; + } + // } else { + // throw new ServiceRuntimeException(resourceClass+" is not a JAX-RS resource class."); + // } + } + + @Override + public Set> getClasses() { + Set> classes = new HashSet>(); + classes.add(resourceClass); + return classes; + } + + private Class generateResourceClass(Class interfaze) { + try { + QName requestWireFormat = null; + if (binding.getRequestWireFormat() != null) { + requestWireFormat = binding.getRequestWireFormat().getSchemaName(); + } + QName responeWireFormat = null; + if (binding.getResponseWireFormat() != null) { + responeWireFormat = binding.getRequestWireFormat().getSchemaName(); + } + String requestMediaType = wireFormatToMediaTypeMapping.get(requestWireFormat); + String responseMediaType = wireFormatToMediaTypeMapping.get(responeWireFormat); + + String uri = endpoint.getBinding().getURI(); + String path = URI.create(uri).getPath(); + Class cls = + RootResourceClassGenerator.generateRootResourceClass(interfaze, + path, + requestMediaType, + responseMediaType); + ProxyFactory proxyFactory = ExtensibleProxyFactory.getInstance(extensionPoints); + Object proxy = proxyFactory.createProxy(interfaze, endpoint); + RootResourceClassGenerator.injectProxy(cls, proxy); + return cls; + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + + public void destroy() { + resourceClass = null; + } + } + + public static boolean isJAXRSResource(Class cls) { + for (Annotation a : cls.getAnnotations()) { + if (a.annotationType().getName().startsWith("javax.ws.rs.")) { + return true; + } + } + for (Method method : cls.getMethods()) { + for (Annotation a : method.getAnnotations()) { + if (a.annotationType().getName().startsWith("javax.ws.rs.")) { + return true; + } + } + + /* + for (Annotation[] annotations : method.getParameterAnnotations()) { + for (Annotation a : annotations) { + if (a.annotationType().getName().startsWith("javax.ws.rs.")) { + return true; + } + } + + } + */ + } + return false; + } + + public void stop() { + if (application != null) { + application.destroy(); + } // Unregister the Servlet from the Servlet host servletHost.removeServletMapping(servletMapping); } @@ -180,11 +340,11 @@ public class RESTServiceBindingProvider implements EndpointProvider { public InterfaceContract getBindingInterfaceContract() { return serviceContract; } - + public boolean supportsOneWayInvocation() { return false; } - + /** * Add specific rest interceptor to invocation chain */ @@ -193,12 +353,18 @@ public class RESTServiceBindingProvider implements EndpointProvider { InvocationChain bindingChain = endpoint.getBindingInvocationChain(); if (wfProvider != null) { - bindingChain.addInterceptor(Phase.SERVICE_BINDING_WIREFORMAT, wfProvider.createInterceptor()); + Interceptor interceptor = wfProvider.createInterceptor(); + if (interceptor != null) { + bindingChain.addInterceptor(Phase.SERVICE_BINDING_WIREFORMAT, interceptor); + } + } + + if (osProvider != null) { + Interceptor interceptor = osProvider.createInterceptor(); + if (interceptor != null) { + bindingChain.addInterceptor(Phase.SERVICE_BINDING_OPERATION_SELECTOR, interceptor); + } } - - if(osProvider != null) { - bindingChain.addInterceptor(Phase.SERVICE_BINDING_OPERATION_SELECTOR, osProvider.createInterceptor()); - } } diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/TuscanyRESTServlet.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/TuscanyRESTServlet.java new file mode 100644 index 0000000000..3d561bf21f --- /dev/null +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/TuscanyRESTServlet.java @@ -0,0 +1,94 @@ +/* + * 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.binding.rest.provider; + +import java.io.IOException; +import java.util.Enumeration; + +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.wink.common.internal.registry.ProvidersRegistry; +import org.apache.wink.server.internal.DeploymentConfiguration; +import org.apache.wink.server.internal.RequestProcessor; +import org.apache.wink.server.internal.handlers.ServerMessageContext; +import org.apache.wink.server.internal.servlet.RestServlet; + +/** + * + */ +public class TuscanyRESTServlet extends RestServlet { + private static final long serialVersionUID = 89997233133964915L; + private ExtensionPointRegistry registry; + + public TuscanyRESTServlet(ExtensionPointRegistry registry) { + super(); + this.registry = registry; + } + + @Override + public DeploymentConfiguration getDeploymentConfiguration() throws ClassNotFoundException, InstantiationException, + IllegalAccessException, IOException { + DeploymentConfiguration config = super.getDeploymentConfiguration(); + // [rfeng] FIXME: This is a hack to fool Apache wink to not remove the servlet path + config.setFilterConfig(new FilterConfig() { + + public ServletContext getServletContext() { + return getServletContext(); + } + + public Enumeration getInitParameterNames() { + return getInitParameterNames(); + } + + public String getInitParameter(String arg0) { + return getInitParameter(arg0); + } + + public String getFilterName() { + return getServletName(); + } + }); + ProvidersRegistry providers = config.getProvidersRegistry(); + providers.addProvider(new DataBindingJAXRSReader(registry), 0.001, true); + providers.addProvider(new DataBindingJAXRSWriter(registry), 0.001, true); + return config; + } + + @Override + public RequestProcessor getRequestProcessor() { + return super.getRequestProcessor(); + } + + public ServerMessageContext createMessageContext(HttpServletRequest request, HttpServletResponse response) { + ServerMessageContext messageContext; + try { + messageContext = new ServerMessageContext(request, response, getDeploymentConfiguration()); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + return messageContext; + } + + +} diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java index e73ec961b3..fdcbc92c9c 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java @@ -54,7 +54,9 @@ public class JSONWireFormatInterceptor implements Interceptor { public Message invoke(Message msg) { HTTPContext bindingContext = (HTTPContext) msg.getBindingContext(); - + if (bindingContext == null) { + return getNext().invoke(msg); + } // Decode using the charset in the request if it exists otherwise // use UTF-8 as this is what all browser implementations use. String charset = bindingContext.getHttpRequest().getCharacterEncoding(); diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatServiceProvider.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatServiceProvider.java index 90efd3390d..c90f5c331c 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatServiceProvider.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatServiceProvider.java @@ -22,6 +22,7 @@ package org.apache.tuscany.sca.binding.rest.wireformat.json.provider; import java.util.List; import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.binding.rest.provider.RESTServiceBindingProvider; import org.apache.tuscany.sca.binding.rest.wireformat.json.JSONWireFormat; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.databinding.javabeans.SimpleJavaDataBinding; @@ -30,6 +31,7 @@ import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.Interface; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; import org.apache.tuscany.sca.invocation.Interceptor; import org.apache.tuscany.sca.invocation.Phase; import org.apache.tuscany.sca.provider.WireFormatProvider; @@ -46,27 +48,44 @@ public class JSONWireFormatServiceProvider implements WireFormatProvider { private InterfaceContract serviceContract; private Binding binding; + private boolean jaxrs; public JSONWireFormatServiceProvider(ExtensionPointRegistry extensionPoints, RuntimeEndpoint endpoint) { this.extensionPoints = extensionPoints; this.endpoint = endpoint; this.binding = endpoint.getBinding(); + this.jaxrs = isJAXRSResource(); + } + + private boolean isJAXRSResource() { + Interface interfaze = endpoint.getComponentServiceInterfaceContract().getInterface(); + if (interfaze instanceof JavaInterface) { + if (RESTServiceBindingProvider.isJAXRSResource(((JavaInterface)interfaze).getJavaClass())) { + return true; + } + } + return false; } public InterfaceContract configureWireFormatInterfaceContract(InterfaceContract interfaceContract) { serviceContract = interfaceContract; - //set JSON databinding - setDataBinding(serviceContract.getInterface()); - - //make JSON databinding default - serviceContract.getInterface().resetDataBinding(JSONDataBinding.NAME); + if (!jaxrs) { + //set JSON databinding + setDataBinding(serviceContract.getInterface()); + + //make JSON databinding default + serviceContract.getInterface().resetDataBinding(JSONDataBinding.NAME); + } return serviceContract; } public Interceptor createInterceptor() { - if(binding.getRequestWireFormat() != null && binding.getRequestWireFormat() instanceof JSONWireFormat) { + if (jaxrs) { + return null; + } + if (binding.getRequestWireFormat() != null && binding.getRequestWireFormat() instanceof JSONWireFormat) { return new JSONWireFormatInterceptor(extensionPoints, endpoint); } return null; diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/provider/XMLWireFormatServiceProvider.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/provider/XMLWireFormatServiceProvider.java index 508b029b00..9e532d2df2 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/provider/XMLWireFormatServiceProvider.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/provider/XMLWireFormatServiceProvider.java @@ -24,6 +24,7 @@ import java.util.List; import javax.xml.stream.XMLStreamReader; import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.binding.rest.provider.RESTServiceBindingProvider; import org.apache.tuscany.sca.binding.rest.wireformat.xml.XMLWireFormat; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.databinding.javabeans.SimpleJavaDataBinding; @@ -32,6 +33,7 @@ import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.Interface; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; import org.apache.tuscany.sca.invocation.Interceptor; import org.apache.tuscany.sca.invocation.Phase; import org.apache.tuscany.sca.provider.WireFormatProvider; @@ -51,26 +53,44 @@ public class XMLWireFormatServiceProvider implements WireFormatProvider { private InterfaceContract serviceContract; private Binding binding; + private boolean jaxrs; + public XMLWireFormatServiceProvider(ExtensionPointRegistry extensionPoints, RuntimeEndpoint endpoint) { this.extensionPoints = extensionPoints; this.endpoint = endpoint; this.binding = endpoint.getBinding(); + this.jaxrs = isJAXRSResource(); + } + + private boolean isJAXRSResource() { + Interface interfaze = endpoint.getComponentServiceInterfaceContract().getInterface(); + if (interfaze instanceof JavaInterface) { + if (RESTServiceBindingProvider.isJAXRSResource(((JavaInterface)interfaze).getJavaClass())) { + return true; + } + } + return false; } public InterfaceContract configureWireFormatInterfaceContract(InterfaceContract interfaceContract) { serviceContract = interfaceContract; - - //make XML databinding default - serviceContract.getInterface().resetDataBinding(DATABABINDING); - - //set XML databinding - setDataBinding(serviceContract.getInterface()); + if (!jaxrs) { + + //make XML databinding default + serviceContract.getInterface().resetDataBinding(DATABABINDING); + + //set XML databinding + setDataBinding(serviceContract.getInterface()); + } return serviceContract; } public Interceptor createInterceptor() { - if(binding.getRequestWireFormat() != null && binding.getRequestWireFormat() instanceof XMLWireFormat) { + if (jaxrs) { + return null; + } + if (binding.getRequestWireFormat() != null && binding.getRequestWireFormat() instanceof XMLWireFormat) { return new XMLWireFormatInterceptor(extensionPoints, endpoint); } return null; diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/rpc/EchoServiceTestCase.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/rpc/EchoServiceTestCase.java index 4fa6fdf0a4..cb65249fe3 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/rpc/EchoServiceTestCase.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/rpc/EchoServiceTestCase.java @@ -28,6 +28,7 @@ import org.apache.tuscany.sca.node.NodeFactory; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import com.meterware.httpunit.GetMethodWebRequest; @@ -35,6 +36,7 @@ import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.WebResponse; +@Ignore public class EchoServiceTestCase { private static final String SERVICE_URL = "http://localhost:8085/EchoService"; @@ -76,6 +78,7 @@ public class EchoServiceTestCase { WebConversation wc = new WebConversation(); WebRequest request = new GetMethodWebRequest(SERVICE_URL + queryString); + request.setHeaderField("Content-Type", "application/json"); WebResponse response = wc.getResource(request); Assert.assertEquals(200, response.getResponseCode()); @@ -88,6 +91,7 @@ public class EchoServiceTestCase { WebConversation wc = new WebConversation(); WebRequest request = new GetMethodWebRequest(SERVICE_URL + queryString); + request.setHeaderField("Content-Type", "application/json"); WebResponse response = wc.getResource(request); Assert.assertEquals(200, response.getResponseCode()); diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/binary/BinaryServiceTestCase.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/binary/BinaryServiceTestCase.java index 66dc66b21a..2ca662ec4e 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/binary/BinaryServiceTestCase.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/binary/BinaryServiceTestCase.java @@ -80,7 +80,7 @@ public class BinaryServiceTestCase { "application/octet-stream"); WebResponse response = wc.getResource(request); - Assert.assertEquals(200, response.getResponseCode()); + Assert.assertEquals(204, response.getResponseCode()); // Read the content request = new GetMethodWebRequest(SERVICE_URL); @@ -94,7 +94,7 @@ public class BinaryServiceTestCase { "application/octet-stream"); response = wc.getResource(request); - Assert.assertEquals(200, response.getResponseCode()); + Assert.assertEquals(204, response.getResponseCode()); //read new results and expect to get new item back in the response request = new GetMethodWebRequest(SERVICE_URL); diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java index 694170e4f0..de5acc2fe7 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java @@ -40,11 +40,11 @@ import com.meterware.httpunit.WebResponse; public class CatalogServiceTestCase { private static final String SERVICE_URL = "http://localhost:8085/Catalog"; - private static final String GET_RESPONSE = "[{\"price\":\"$1.55\",\"name\":\"Pear\",\"javaClass\":\"services.store.Item\"},{\"price\":\"$2.99\",\"name\":\"Apple\",\"javaClass\":\"services.store.Item\"},{\"price\":\"$3.55\",\"name\":\"Orange\",\"javaClass\":\"services.store.Item\"}]"; + private static final String GET_RESPONSE = "{\"items\":[{\"price\":\"$1.55\",\"name\":\"Pear\"},{\"price\":\"$2.99\",\"name\":\"Apple\"},{\"price\":\"$3.55\",\"name\":\"Orange\"}]}"; private static final String NEW_ITEM = "{\"price\":\"$4.35\",\"name\":\"Grape\"}\""; - private static final String GET_NEW_RESPONSE = "[{\"price\":\"$1.55\",\"name\":\"Pear\",\"javaClass\":\"services.store.Item\"},{\"price\":\"$2.99\",\"name\":\"Apple\",\"javaClass\":\"services.store.Item\"},{\"price\":\"$3.55\",\"name\":\"Orange\",\"javaClass\":\"services.store.Item\"},{\"price\":\"$4.35\",\"name\":\"Grape\",\"javaClass\":\"services.store.Item\"}]"; + private static final String GET_NEW_RESPONSE = "{\"items\":[{\"price\":\"$1.55\",\"name\":\"Pear\"},{\"price\":\"$2.99\",\"name\":\"Apple\"},{\"price\":\"$3.55\",\"name\":\"Orange\"},{\"price\":\"$4.35\",\"name\":\"Grape\"}]}"; private static final String UPDATED_ITEM = "{\"price\":\"$1.35\",\"name\":\"Grape\"}\""; - private static final String GET_UPDATED_RESPONSE = "[{\"price\":\"$1.55\",\"name\":\"Pear\",\"javaClass\":\"services.store.Item\"},{\"price\":\"$2.99\",\"name\":\"Apple\",\"javaClass\":\"services.store.Item\"},{\"price\":\"$3.55\",\"name\":\"Orange\",\"javaClass\":\"services.store.Item\"},{\"price\":\"$1.35\",\"name\":\"Grape\",\"javaClass\":\"services.store.Item\"}]"; + private static final String GET_UPDATED_RESPONSE = "{\"items\":[{\"price\":\"$1.55\",\"name\":\"Pear\"},{\"price\":\"$2.99\",\"name\":\"Apple\"},{\"price\":\"$3.55\",\"name\":\"Orange\"},{\"price\":\"$1.35\",\"name\":\"Grape\"}]}"; private static Node node; @@ -76,6 +76,7 @@ public class CatalogServiceTestCase { public void testGetInvocation() throws Exception { WebConversation wc = new WebConversation(); WebRequest request = new GetMethodWebRequest(SERVICE_URL); + request.setHeaderField("Content-Type", "application/json"); WebResponse response = wc.getResource(request); Assert.assertEquals(200, response.getResponseCode()); @@ -88,12 +89,14 @@ public class CatalogServiceTestCase { //Add new item to catalog WebConversation wc = new WebConversation(); WebRequest request = new PostMethodWebRequest(SERVICE_URL, new ByteArrayInputStream(NEW_ITEM.getBytes("UTF-8")),"application/json"); + request.setHeaderField("Content-Type", "application/json"); WebResponse response = wc.getResource(request); - Assert.assertEquals(200, response.getResponseCode()); + Assert.assertEquals(204, response.getResponseCode()); //read new results and expect to get new item back in the response request = new GetMethodWebRequest(SERVICE_URL); + request.setHeaderField("Content-Type", "application/json"); response = wc.getResource(request); //for debug purposes @@ -109,12 +112,14 @@ public class CatalogServiceTestCase { //Add new item to catalog WebConversation wc = new WebConversation(); WebRequest request = new PostMethodWebRequest(SERVICE_URL, new ByteArrayInputStream(UPDATED_ITEM.getBytes("UTF-8")),"application/json"); + request.setHeaderField("Content-Type", "application/json"); WebResponse response = wc.getResource(request); - Assert.assertEquals(200, response.getResponseCode()); + Assert.assertEquals(204, response.getResponseCode()); //read new results and expect to get new item back in the response request = new GetMethodWebRequest(SERVICE_URL); + request.setHeaderField("Content-Type", "application/json"); response = wc.getResource(request); //for debug purposes diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/CustomerServiceTestCase.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/CustomerServiceTestCase.java index 000f66c7b3..a5f99d9737 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/CustomerServiceTestCase.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/CustomerServiceTestCase.java @@ -29,6 +29,7 @@ import org.apache.tuscany.sca.node.NodeFactory; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import com.meterware.httpunit.GetMethodWebRequest; @@ -40,9 +41,9 @@ import com.meterware.httpunit.WebResponse; public class CustomerServiceTestCase { private static final String SERVICE_URL = "http://localhost:8085/Customer"; - private static final String GET_RESPONSE = "john@domain.comJohnJohn"; + private static final String GET_RESPONSE = "john@domain.comJohnJohn"; private static final String UPDATED_ITEM = "john@updated-domain.comJohnJohn"; - private static final String GET_UPDATED_RESPONSE = "john@updated-domain.comJohnJohn"; + private static final String GET_UPDATED_RESPONSE = "john@updated-domain.comJohnJohn"; private static Node node; @@ -71,9 +72,11 @@ public class CustomerServiceTestCase { } @Test + @Ignore public void testGetInvocation() throws Exception { WebConversation wc = new WebConversation(); WebRequest request = new GetMethodWebRequest(SERVICE_URL); + request.setHeaderField("Content-Type", "application/xml"); WebResponse response = wc.getResource(request); //for debug purposes @@ -99,12 +102,14 @@ public class CustomerServiceTestCase { //Add new item to catalog WebConversation wc = new WebConversation(); WebRequest request = new PostMethodWebRequest(SERVICE_URL, new ByteArrayInputStream(UPDATED_ITEM.getBytes("UTF-8")),"application/json"); + request.setHeaderField("Content-Type", "application/xml"); WebResponse response = wc.getResource(request); - Assert.assertEquals(200, response.getResponseCode()); + Assert.assertEquals(204, response.getResponseCode()); //read new results and expect to get new item back in the response request = new GetMethodWebRequest(SERVICE_URL); + request.setHeaderField("Content-Type", "application/xml"); response = wc.getResource(request); //for debug purposes diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/Catalog.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/Catalog.java index 9ffe8fe931..7e579c6aba 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/Catalog.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/Catalog.java @@ -33,7 +33,7 @@ import org.oasisopen.sca.annotation.Remotable; public interface Catalog { @GET - Item[] getItem(); + Items getItem(); @GET @Path("{id}") diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/FruitsCatalogImpl.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/FruitsCatalogImpl.java index c7a9807878..126b8e7d7a 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/FruitsCatalogImpl.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/FruitsCatalogImpl.java @@ -19,6 +19,7 @@ package services.store; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -46,10 +47,10 @@ public class FruitsCatalogImpl implements Catalog { catalog.put("Pear", new Item("Pear", currencySymbol + currencyConverter.getConversion("USD", currencyCode, 1.55))); } - public Item[] getItem() { - Item[] catalogArray = new Item[catalog.size()]; - catalog.values().toArray(catalogArray); - return catalogArray; + public Items getItem() { + Items items = new Items(); + items.setItems(new ArrayList(catalog.values())); + return items; } public Item getItemById(String itemId) { diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/Items.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/Items.java new file mode 100644 index 0000000000..82a995943d --- /dev/null +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/services/store/Items.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 services.store; + +import java.util.List; + +/** + * + */ +public class Items { + private List items; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java b/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java index d7c345b9f1..261909c52e 100644 --- a/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java +++ b/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java @@ -315,11 +315,11 @@ public class EndpointReferenceBuilderImpl { endpointRef.setStatus(EndpointReference.Status.RESOLVED_BINDING); } - if (reference.getCallbackService() != null) { - Endpoint callbackEndpoint = - createEndpoint(component, reference.getCallbackService(), false); - endpointRef.setCallbackEndpoint(callbackEndpoint); - } +// if (reference.getCallbackService() != null) { +// Endpoint callbackEndpoint = +// createEndpoint(component, reference.getCallbackService(), false); +// endpointRef.setCallbackEndpoint(callbackEndpoint); +// } reference.getEndpointReferences().add(endpointRef); continue; @@ -352,11 +352,11 @@ public class EndpointReferenceBuilderImpl { } endpointRef.setTargetEndpoint(endpoint); - if (reference.getCallbackService() != null) { - Endpoint callbackEndpoint = - createEndpoint(component, reference.getCallbackService(), false); - endpointRef.setCallbackEndpoint(callbackEndpoint); - } +// if (reference.getCallbackService() != null) { +// Endpoint callbackEndpoint = +// createEndpoint(component, reference.getCallbackService(), false); +// endpointRef.setCallbackEndpoint(callbackEndpoint); +// } reference.getEndpointReferences().add(endpointRef); } } diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/JSONHelper.java b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/JSONHelper.java index cdcad3a472..028690a789 100644 --- a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/JSONHelper.java +++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/JSONHelper.java @@ -19,11 +19,14 @@ package org.apache.tuscany.sca.databinding.json; +import java.util.Collection; + import org.apache.tuscany.sca.databinding.json.jackson.JacksonHelper; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParser; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; +import org.json.JSONArray; /** * @version $Rev$ $Date$ @@ -79,19 +82,22 @@ public class JSONHelper { return json; } - public static T toJSON(String json, Class type) { + public static Object toJSON(String json, Class type) { if (type == JSONObject.class) { try { - return type.cast(new JSONObject(json)); + return new JSONObject(json); } catch (JSONException e) { throw new IllegalArgumentException(e); } } else { if (type == null) { - type = (Class)org.json.JSONObject.class; + type = org.json.JSONObject.class; } try { - return type.cast(new org.json.JSONObject(json)); + if (type == JSONArray.class || type.isArray() || Collection.class.isAssignableFrom(type)) { + return new JSONArray(json); + } + return new org.json.JSONObject(json); } catch (org.json.JSONException e) { throw new IllegalArgumentException(e); } diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/InputStream2JSON.java b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/InputStream2JSON.java new file mode 100644 index 0000000000..57b9d55b44 --- /dev/null +++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/InputStream2JSON.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.databinding.json.jackson; + +import java.io.InputStream; + +import org.apache.tuscany.sca.databinding.PullTransformer; +import org.apache.tuscany.sca.databinding.TransformationContext; +import org.apache.tuscany.sca.databinding.json.JSONDataBinding; + +/** + * + */ +public class InputStream2JSON implements PullTransformer { + + public String getSourceDataBinding() { + return "application/json" + "#" + InputStream.class.getName(); + } + + public String getTargetDataBinding() { + return JSONDataBinding.NAME; + } + + public int getWeight() { + return 10; + } + + public Object transform(InputStream source, TransformationContext context) { + return JacksonHelper.createJsonParser(source); + } + +} diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2Object.java b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2Object.java index 5edcc6701e..3620fc117f 100644 --- a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2Object.java +++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2Object.java @@ -54,8 +54,9 @@ public class JSON2Object implements PullTransformer { return mapper.treeToValue((JsonNode)source, context.getTargetDataType().getPhysical()); } else if (source instanceof JsonParser) { return mapper.readValue((JsonParser)source, javaType); + } else { + return mapper.readValue(source.toString(), javaType); } - return null; } catch (Exception e) { throw new TransformationException(e); } diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2OutputStream.java b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2OutputStream.java new file mode 100644 index 0000000000..920485a540 --- /dev/null +++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2OutputStream.java @@ -0,0 +1,65 @@ +/* + * 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.databinding.json.jackson; + +import java.io.OutputStream; + +import org.apache.tuscany.sca.databinding.PushTransformer; +import org.apache.tuscany.sca.databinding.TransformationContext; +import org.apache.tuscany.sca.databinding.TransformationException; +import org.apache.tuscany.sca.databinding.json.JSONDataBinding; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; + +/** + * + */ +public class JSON2OutputStream implements PushTransformer { + + public String getSourceDataBinding() { + return JSONDataBinding.NAME; + } + + public String getTargetDataBinding() { + return "application/json" + "#" + OutputStream.class.getName(); + } + + public void transform(Object source, OutputStream sink, TransformationContext context) { + if (source == null) { + return; + } + if (source instanceof JsonNode) { + JacksonHelper.write((JsonNode)source, sink); + } else if (source instanceof JsonParser) { + JacksonHelper.write((JsonParser)source, sink); + } else { + try { + sink.write(source.toString().getBytes("UTF-8")); + } catch (Exception e) { + throw new TransformationException(e); + } + } + } + + public int getWeight() { + return 50; + } + +} diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java index 1e3399017c..ae3bb8fd48 100644 --- a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java +++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java @@ -20,13 +20,18 @@ package org.apache.tuscany.sca.databinding.json.jackson; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; import java.io.StringWriter; +import org.codehaus.jackson.JsonEncoding; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.map.AnnotationIntrospector; +import org.codehaus.jackson.map.DeserializationConfig; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector; import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; @@ -41,6 +46,8 @@ public class JacksonHelper { AnnotationIntrospector secondary = new JacksonAnnotationIntrospector(); AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary, secondary); mapper.getDeserializationConfig().setAnnotationIntrospector(pair); + // [rfeng] To avoid complaints about javaClass + mapper.getDeserializationConfig().set(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, Boolean.FALSE); mapper.getSerializationConfig().setAnnotationIntrospector(pair); return mapper; } @@ -79,4 +86,43 @@ public class JacksonHelper { } } + public static JsonParser createJsonParser(InputStream content) { + JsonFactory jsonFactory = new JsonFactory(); + try { + return jsonFactory.createJsonParser(content); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + public static JsonParser createJsonParser(Reader content) { + JsonFactory jsonFactory = new JsonFactory(); + try { + return jsonFactory.createJsonParser(content); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + public static void write(JsonNode node, OutputStream out) { + try { + JsonFactory jsonFactory = new JsonFactory(); + JsonGenerator generator = jsonFactory.createJsonGenerator(out, JsonEncoding.UTF8); + generator.writeTree(node); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + public static void write(JsonParser parser, OutputStream out) { + try { + JsonFactory jsonFactory = new JsonFactory(); + JsonGenerator generator = jsonFactory.createJsonGenerator(out, JsonEncoding.UTF8); + JsonNode node = parser.readValueAs(JsonNode.class); + generator.writeTree(node); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + } diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer b/sca-java-2.x/trunk/modules/databinding-json/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer index 800e4a43fb..3590a46c47 100644 --- a/sca-java-2.x/trunk/modules/databinding-json/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer +++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer @@ -18,15 +18,17 @@ # Implementation classes for the transformers org.apache.tuscany.sca.databinding.json.JSON2XMLStreamReader;source=JSON,target=javax.xml.stream.XMLStreamReader,weight=5000 org.apache.tuscany.sca.databinding.json.XMLStreamReader2JSON;source=javax.xml.stream.XMLStreamReader,target=JSON,weight=5000,public=false -org.apache.tuscany.sca.databinding.json.JavaBean2JSON;source=java:complexType,target=JSON,weight=80000,public=false -org.apache.tuscany.sca.databinding.json.JavaBean2JSON;source=java:simpleType,target=JSON,weight=80000,public=false +org.apache.tuscany.sca.databinding.json.jackson.Object2JSON;source=java:complexType,target=JSON,weight=90000,public=true +org.apache.tuscany.sca.databinding.json.jackson.Object2JSON;source=java:simpleType,target=JSON,weight=90000,public=false org.apache.tuscany.sca.databinding.json.axiom.JSON2OMElement;source=JSON,target=org.apache.axiom.om.OMElement,weight=500 -org.apache.tuscany.sca.databinding.json.JavaBean2JSON;source=java:array,target=JSON,weight=80000,public=false -org.apache.tuscany.sca.databinding.json.JavaBean2JSON;source=commonj.sdo.DataObject,target=JSON,weight=80000,public=false -org.apache.tuscany.sca.databinding.json.JavaBean2JSON;source=javax.xml.bind.JAXBElement,target=JSON,weight=80000,public=false -org.apache.tuscany.sca.databinding.json.JSON2JavaBean;source=JSON,target=java:complexType,weight=80000,public=false -org.apache.tuscany.sca.databinding.json.JSON2JavaBean;source=JSON,target=java:simpleType,weight=80000,public=false -org.apache.tuscany.sca.databinding.json.JSON2JavaBean;source=JSON,target=commonj.sdo.DataObject,weight=80000,public=false -org.apache.tuscany.sca.databinding.json.JSON2JavaBean;source=JSON,target=javax.xml.bind.JAXBElement,weight=80000,public=false -org.apache.tuscany.sca.databinding.json.JSON2JavaBean;source=JSON,target=java:array,weight=80000,public=false +org.apache.tuscany.sca.databinding.json.jackson.Object2JSON;source=java:array,target=JSON,weight=90000,public=false +org.apache.tuscany.sca.databinding.json.jackson.Object2JSON;source=commonj.sdo.DataObject,target=JSON,weight=90000,public=false +org.apache.tuscany.sca.databinding.json.jackson.Object2JSON;source=javax.xml.bind.JAXBElement,target=JSON,weight=90000,public=false +org.apache.tuscany.sca.databinding.json.jackson.JSON2Object;source=JSON,target=java:complexType,weight=90000,public=false +org.apache.tuscany.sca.databinding.json.jackson.JSON2Object;source=JSON,target=java:simpleType,weight=90000,public=false +org.apache.tuscany.sca.databinding.json.jackson.JSON2Object;source=JSON,target=commonj.sdo.DataObject,weight=90000,public=false +org.apache.tuscany.sca.databinding.json.jackson.JSON2Object;source=JSON,target=javax.xml.bind.JAXBElement,weight=90000,public=false +org.apache.tuscany.sca.databinding.json.jackson.JSON2Object;source=JSON,target=java:array,weight=90000,public=false + +org.apache.tuscany.sca.databinding.json.jackson.InputStream2JSON;source=application/json#java.io.InputStream;target=JSON,weight=50,public=true diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PushTransformer b/sca-java-2.x/trunk/modules/databinding-json/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PushTransformer new file mode 100644 index 0000000000..6fb438eec7 --- /dev/null +++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PushTransformer @@ -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. +org.apache.tuscany.sca.databinding.json.jackson.JSON2OutputStream;source=JSON;target=application/json#java.io.OutputStream,weight=50,public=true +# 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.databinding.json.jackson.JSON2OutputStream;source=JSON;target=application/json#java.io.OutputStream,weight=50,public=true \ No newline at end of file diff --git a/sca-java-2.x/trunk/modules/databinding-sdo/src/test/java/org/apache/tuscany/sca/databinding/sdo/DataObject2XMLStreamReaderTestCase.java b/sca-java-2.x/trunk/modules/databinding-sdo/src/test/java/org/apache/tuscany/sca/databinding/sdo/DataObject2XMLStreamReaderTestCase.java index d1b272b1b3..c2a9f46059 100644 --- a/sca-java-2.x/trunk/modules/databinding-sdo/src/test/java/org/apache/tuscany/sca/databinding/sdo/DataObject2XMLStreamReaderTestCase.java +++ b/sca-java-2.x/trunk/modules/databinding-sdo/src/test/java/org/apache/tuscany/sca/databinding/sdo/DataObject2XMLStreamReaderTestCase.java @@ -68,7 +68,7 @@ public class DataObject2XMLStreamReaderTestCase extends SDOTransformerTestCaseBa XMLStreamReader2Node t2 = new XMLStreamReader2Node(new DefaultExtensionPointRegistry()); org.w3c.dom.Node node = t2.transform(reader, context); assertNotNull(node); - Node2String t3 = new Node2String(); + Node2String t3 = new Node2String(new DefaultExtensionPointRegistry()); String xml = t3.transform(node, context); assertTrue(xml.contains("xmlns:xsi")); } diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBindingContext.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBindingContext.java new file mode 100644 index 0000000000..c77d0ad0f6 --- /dev/null +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBindingContext.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.databinding; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import org.apache.tuscany.sca.interfacedef.Operation; + +/** + * The context for databinding processing + */ +public class DataBindingContext { + + private String contentType; + private Class type; + private Type genericType; + private Annotation[] annotations; + private Operation operation; + + public DataBindingContext(Class type, + Type genericType, + Annotation[] annotations, + Operation operation, + String contentType) { + super(); + this.type = type; + this.genericType = genericType; + this.annotations = annotations; + this.operation = operation; + this.contentType = contentType; + } + + public DataBindingContext(Class type, Type genericType, Annotation[] annotations) { + super(); + this.type = type; + this.genericType = genericType; + this.annotations = annotations; + } + + public DataBindingContext(Class type) { + super(); + this.type = type; + this.genericType = type; + } + + public Class getType() { + return type; + } + + public Type getGenericType() { + return genericType; + } + + public Annotation[] getAnnotations() { + return annotations; + } + + public Operation getOperation() { + return operation; + } + + public A getAnnotation(Class type) { + if (annotations == null) { + return null; + } + for (Annotation a : annotations) { + if (a.annotationType() == type) { + return type.cast(a); + } + } + return null; + } + + public String getContentType() { + return contentType; + } +} diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/InputSource2Node.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/InputSource2Node.java index 5333d8047a..0bb0513011 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/InputSource2Node.java +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/InputSource2Node.java @@ -22,6 +22,7 @@ import javax.xml.transform.Source; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.stream.StreamSource; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.databinding.BaseTransformer; import org.apache.tuscany.sca.databinding.PullTransformer; import org.apache.tuscany.sca.databinding.TransformationContext; @@ -36,8 +37,14 @@ import org.xml.sax.InputSource; */ public class InputSource2Node extends BaseTransformer implements PullTransformer { - private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer(); - + + private final Source2ResultTransformer TRANSFORMER; + + public InputSource2Node(ExtensionPointRegistry registry) { + super(); + this.TRANSFORMER = new Source2ResultTransformer(registry); + } + public Node transform(InputSource source, TransformationContext context) { try { Source streamSource = new StreamSource(source.getCharacterStream()); diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/InputStream2Node.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/InputStream2Node.java index 31254ff2c6..c9183c4cbf 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/InputStream2Node.java +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/InputStream2Node.java @@ -24,6 +24,7 @@ import javax.xml.transform.Source; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.sax.SAXSource; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.databinding.BaseTransformer; import org.apache.tuscany.sca.databinding.PullTransformer; import org.apache.tuscany.sca.databinding.TransformationContext; @@ -38,8 +39,14 @@ import org.xml.sax.InputSource; */ public class InputStream2Node extends BaseTransformer implements PullTransformer { - private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer(); + private final Source2ResultTransformer TRANSFORMER; + + public InputStream2Node(ExtensionPointRegistry registry) { + super(); + this.TRANSFORMER = new Source2ResultTransformer(registry); + } + public Node transform(InputStream source, TransformationContext context) { try { Source streamSource = new SAXSource(new InputSource(source)); diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2OutputStream.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2OutputStream.java index bf39509e35..25ed70dda5 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2OutputStream.java +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2OutputStream.java @@ -25,6 +25,7 @@ import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.databinding.BaseTransformer; import org.apache.tuscany.sca.databinding.PushTransformer; import org.apache.tuscany.sca.databinding.TransformationContext; @@ -38,8 +39,14 @@ import org.w3c.dom.Node; */ public class Node2OutputStream extends BaseTransformer implements PushTransformer { - private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer(); + private final Source2ResultTransformer TRANSFORMER; + + public Node2OutputStream(ExtensionPointRegistry registry) { + super(); + this.TRANSFORMER = new Source2ResultTransformer(registry); + } + public void transform(Node source, OutputStream writer, TransformationContext context) { try { Source domSource = new DOMSource(source); diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2String.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2String.java index a43354e99c..fb3023345c 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2String.java +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2String.java @@ -20,6 +20,7 @@ package org.apache.tuscany.sca.databinding.xml; import java.io.StringWriter; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.databinding.BaseTransformer; import org.apache.tuscany.sca.databinding.PullTransformer; import org.apache.tuscany.sca.databinding.TransformationContext; @@ -32,8 +33,13 @@ import org.w3c.dom.Node; * @version $Rev$ $Date$ */ public class Node2String extends BaseTransformer implements PullTransformer { - private static final Node2Writer TRANSFORMER = new Node2Writer(); - + private final Node2Writer TRANSFORMER; + + public Node2String(ExtensionPointRegistry registry) { + super(); + this.TRANSFORMER = new Node2Writer(registry); + } + public String transform(Node source, TransformationContext context) { try { StringWriter writer = new StringWriter(); diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2Writer.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2Writer.java index 18561d0eeb..6c1d241ce9 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2Writer.java +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Node2Writer.java @@ -25,6 +25,7 @@ import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.databinding.BaseTransformer; import org.apache.tuscany.sca.databinding.PushTransformer; import org.apache.tuscany.sca.databinding.TransformationContext; @@ -37,8 +38,14 @@ import org.w3c.dom.Node; * @version $Rev$ $Date$ */ public class Node2Writer extends BaseTransformer implements PushTransformer { - private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer(); + private final Source2ResultTransformer TRANSFORMER; + + public Node2Writer(ExtensionPointRegistry registry) { + super(); + this.TRANSFORMER = new Source2ResultTransformer(registry); + } + public void transform(Node source, Writer writer, TransformationContext context) { try { Source domSource = new DOMSource(source); diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Reader2Node.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Reader2Node.java index 31adea234d..1866f3864a 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Reader2Node.java +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Reader2Node.java @@ -24,6 +24,7 @@ import javax.xml.transform.Source; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.stream.StreamSource; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.databinding.BaseTransformer; import org.apache.tuscany.sca.databinding.PullTransformer; import org.apache.tuscany.sca.databinding.TransformationContext; @@ -36,8 +37,13 @@ import org.w3c.dom.Node; * @version $Rev$ $Date$ */ public class Reader2Node extends BaseTransformer implements PullTransformer { - private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer(); - + private final Source2ResultTransformer TRANSFORMER; + + public Reader2Node(ExtensionPointRegistry registry) { + super(); + this.TRANSFORMER = new Source2ResultTransformer(registry); + } + public Node transform(Reader source, TransformationContext context) { try { Source streamSource = new StreamSource(source); diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Source2ResultTransformer.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Source2ResultTransformer.java index da78e6f9a6..dd69e3ea66 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Source2ResultTransformer.java +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Source2ResultTransformer.java @@ -22,6 +22,8 @@ import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.TransformerFactory; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.databinding.BaseTransformer; import org.apache.tuscany.sca.databinding.PushTransformer; import org.apache.tuscany.sca.databinding.TransformationContext; @@ -34,11 +36,17 @@ import org.apache.tuscany.sca.databinding.TransformationException; */ public class Source2ResultTransformer extends BaseTransformer implements PushTransformer { - private static final TransformerFactory FACTORY = TransformerFactory.newInstance(); + private final TransformerFactory factory; + public Source2ResultTransformer(ExtensionPointRegistry registry) { + super(); + FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class); + factory = factories.getFactory(TransformerFactory.class); + } + public void transform(Source source, Result result, TransformationContext context) { try { - javax.xml.transform.Transformer transformer = FACTORY.newTransformer(); + javax.xml.transform.Transformer transformer = factory.newTransformer(); transformer.transform(source, result); } catch (Exception e) { throw new TransformationException(e); diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Source2StringTransformer.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Source2StringTransformer.java index 5cf1867b96..0c3db2a477 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Source2StringTransformer.java +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/Source2StringTransformer.java @@ -24,6 +24,8 @@ import javax.xml.transform.Source; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.databinding.BaseTransformer; import org.apache.tuscany.sca.databinding.PullTransformer; import org.apache.tuscany.sca.databinding.TransformationContext; @@ -36,11 +38,17 @@ import org.apache.tuscany.sca.databinding.TransformationException; */ public class Source2StringTransformer extends BaseTransformer implements PullTransformer { - private static final TransformerFactory FACTORY = TransformerFactory.newInstance(); + private final TransformerFactory factory; + public Source2StringTransformer(ExtensionPointRegistry registry) { + super(); + FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class); + factory = factories.getFactory(TransformerFactory.class); + } + public String transform(Source source, TransformationContext context) { try { - javax.xml.transform.Transformer transformer = FACTORY.newTransformer(); + javax.xml.transform.Transformer transformer = factory.newTransformer(); StringWriter sw = new StringWriter(); StreamResult result = new StreamResult(sw); transformer.transform(source, result); diff --git a/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/impl/MediatorImplTestCase.java b/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/impl/MediatorImplTestCase.java index a74a8e5550..953e539dd1 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/impl/MediatorImplTestCase.java +++ b/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/impl/MediatorImplTestCase.java @@ -87,8 +87,8 @@ public class MediatorImplTestCase { registry.addTransformer(new String2SAX(), true); registry.addTransformer(new SAX2DOMPipe(extensionPointRegistry), true); - registry.addTransformer(new Node2String(), true); - registry.addTransformer(new Node2Writer(), true); + registry.addTransformer(new Node2String(extensionPointRegistry), true); + registry.addTransformer(new Node2Writer(extensionPointRegistry), true); mediator = new MediatorImpl(dataBindingRegistry, registry); } diff --git a/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/DataPipeTestCase.java b/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/DataPipeTestCase.java index 682fbd4243..da18a4f89c 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/DataPipeTestCase.java +++ b/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/DataPipeTestCase.java @@ -27,6 +27,7 @@ import java.io.Writer; import org.apache.tuscany.sca.common.xml.dom.DOMHelper; import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.databinding.DataPipe; import org.apache.tuscany.sca.databinding.DataPipeTransformer; import org.apache.tuscany.sca.databinding.impl.PipedTransformer; @@ -76,11 +77,12 @@ public class DataPipeTestCase { @Test public final void testPiped() throws Exception { - Node2Writer node2Writer = new Node2Writer(); + ExtensionPointRegistry registry = new DefaultExtensionPointRegistry(); + Node2Writer node2Writer = new Node2Writer(registry); Writer2ReaderDataPipe pipe = new Writer2ReaderDataPipe(); PipedTransformer transformer = new PipedTransformer(node2Writer, pipe); - Document document = DOMHelper.getInstance(new DefaultExtensionPointRegistry()).newDocument(); + Document document = DOMHelper.getInstance(registry).newDocument(); Element element = document.createElementNS("http://ns1", "root"); document.appendChild(element); Reader reader = transformer.transform(document, null); diff --git a/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/Node2StringTestCase.java b/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/Node2StringTestCase.java index 516b57c851..75c43dbf79 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/Node2StringTestCase.java +++ b/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/Node2StringTestCase.java @@ -20,6 +20,7 @@ package org.apache.tuscany.sca.databinding.xml; import org.apache.tuscany.sca.common.xml.dom.DOMHelper; import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -32,10 +33,11 @@ public class Node2StringTestCase { @Test public void testTransformation() throws Exception { - Document document = DOMHelper.getInstance(new DefaultExtensionPointRegistry()).newDocument(); + ExtensionPointRegistry registry = new DefaultExtensionPointRegistry(); + Document document = DOMHelper.getInstance(registry).newDocument(); Element element = document.createElementNS("http://ns1", "test"); document.appendChild(element); - new Node2String().transform(document, null); + new Node2String(registry).transform(document, null); } } diff --git a/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/PushTransformationTestCase.java b/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/PushTransformationTestCase.java index a8657a5be8..5027f64f01 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/PushTransformationTestCase.java +++ b/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/PushTransformationTestCase.java @@ -73,7 +73,7 @@ public class PushTransformationTestCase { new PipedTransformer(t2, new SAX2DOMPipe(registry)); Node node = t3.transform(reader, null); Assert.assertNotNull(node); - Node2String t4 = new Node2String(); + Node2String t4 = new Node2String(registry); String xml = t4.transform(node, null); Assert.assertTrue(xml != null && xml.indexOf("1999-12-05") != -1); } diff --git a/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/TraxTransformerTestCase.java b/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/TraxTransformerTestCase.java index fb9895f120..6fd8ce2e8b 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/TraxTransformerTestCase.java +++ b/sca-java-2.x/trunk/modules/databinding/src/test/java/org/apache/tuscany/sca/databinding/xml/TraxTransformerTestCase.java @@ -28,6 +28,8 @@ import java.io.StringWriter; import java.io.Writer; import java.net.URL; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.junit.Before; import org.junit.Test; import org.w3c.dom.Node; @@ -50,22 +52,23 @@ public class TraxTransformerTestCase { @Test public void testTransformDOM() throws IOException { + ExtensionPointRegistry registry = new DefaultExtensionPointRegistry(); InputStream is = url.openStream(); - InputStream2Node t1 = new InputStream2Node(); + InputStream2Node t1 = new InputStream2Node(registry); Node node = t1.transform(is, null); is.close(); Writer writer = new StringWriter(); - Node2Writer t2 = new Node2Writer(); + Node2Writer t2 = new Node2Writer(registry); t2.transform(node, writer, null); String str = writer.toString(); StringReader reader = new StringReader(str); - Reader2Node t3 = new Reader2Node(); + Reader2Node t3 = new Reader2Node(registry); node = t3.transform(reader, null); ByteArrayOutputStream os = new ByteArrayOutputStream(); - Node2OutputStream t4 = new Node2OutputStream(); + Node2OutputStream t4 = new Node2OutputStream(registry); t4.transform(node, os, null); InputSource inputSource = new InputSource(new ByteArrayInputStream(os.toByteArray())); - InputSource2Node t5 = new InputSource2Node(); + InputSource2Node t5 = new InputSource2Node(registry); node = t5.transform(inputSource, null); } diff --git a/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/META-INF/MANIFEST.MF index 783e874e36..d914db4ea2 100644 --- a/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/META-INF/MANIFEST.MF +++ b/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/META-INF/MANIFEST.MF @@ -9,12 +9,12 @@ Bundle-Description: Apache Tuscany SCA Implementation JAXRS Runtime Bundle-SymbolicName: org.apache.tuscany.sca.implementation.jaxrs.provider Bundle-DocURL: http://www.apache.org/ Import-Package: javax.servlet, + javax.servlet.http, javax.ws.rs, javax.ws.rs.core, - org.apache.wink.server.internal.servlet, - org.apache.wink.server.utils, org.apache.tuscany.sca.assembly;version="2.0.0", org.apache.tuscany.sca.core;version="2.0.0", + org.apache.tuscany.sca.core.invocation;version="2.0.0", org.apache.tuscany.sca.host.http;version="2.0.0", org.apache.tuscany.sca.implementation.jaxrs;version="2.0.0", org.apache.tuscany.sca.interfacedef;version="2.0.0", @@ -22,6 +22,10 @@ Import-Package: javax.servlet, org.apache.tuscany.sca.policy;version="2.0.0", org.apache.tuscany.sca.provider;version="2.0.0", org.apache.tuscany.sca.runtime;version="2.0.0", - org.oasisopen.sca.annotation;version="2.0.0", - org.oasisopen.sca;version="2.0.0" + org.apache.wink.server.internal, + org.apache.wink.server.internal.handlers, + org.apache.wink.server.internal.servlet, + org.apache.wink.server.utils, + org.oasisopen.sca;version="2.0.0", + org.oasisopen.sca.annotation;version="2.0.0" Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6 diff --git a/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/pom.xml b/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/pom.xml index 3d18f1983b..c9448116af 100644 --- a/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/pom.xml +++ b/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/pom.xml @@ -41,8 +41,16 @@ org.apache.tuscany.sca tuscany-implementation-java-runtime 2.0-SNAPSHOT + test + + org.apache.tuscany.sca + tuscany-binding-rest-runtime + 2.0-SNAPSHOT + runtime + + org.apache.tuscany.sca tuscany-host-http @@ -79,18 +87,18 @@ org.apache.wink wink-server - 1.0-incubating + 1.1-incubating javax.ws.rs jsr311-api - 1.0 + 1.1 org.apache.wink wink-client - 1.0-incubating + 1.1-incubating test diff --git a/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/provider/JAXRSImplementationProvider.java b/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/provider/JAXRSImplementationProvider.java index e2397b3bcc..91d4607831 100644 --- a/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/provider/JAXRSImplementationProvider.java +++ b/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/provider/JAXRSImplementationProvider.java @@ -19,18 +19,12 @@ package org.apache.tuscany.sca.implementation.jaxrs.provider; -import javax.servlet.Servlet; -import javax.ws.rs.core.Application; - import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.implementation.jaxrs.JAXRSImplementation; import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.provider.ImplementationProvider; import org.apache.tuscany.sca.runtime.RuntimeComponentService; -import org.apache.wink.server.internal.servlet.RestServlet; -import org.apache.wink.server.utils.RegistrationUtils; -import org.oasisopen.sca.ServiceRuntimeException; /** * @@ -57,6 +51,7 @@ public class JAXRSImplementationProvider implements ImplementationProvider { } public void start() { + /* RestServlet restServlet = new RestServlet(); host.addServletMapping("/*", restServlet); Application application; @@ -66,13 +61,16 @@ public class JAXRSImplementationProvider implements ImplementationProvider { throw new ServiceRuntimeException(e); } RegistrationUtils.registerApplication(application, restServlet.getServletContext()); + */ } public void stop() { + /* Servlet servlet = host.removeServletMapping("/*"); if (servlet != null) { servlet.destroy(); } + */ } } diff --git a/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/src/test/java/helloworld/jaxrs/test/HelloWorldTestCase.java b/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/src/test/java/helloworld/jaxrs/test/HelloWorldTestCase.java index 20ddf88505..34edff56ca 100644 --- a/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/src/test/java/helloworld/jaxrs/test/HelloWorldTestCase.java +++ b/sca-java-2.x/trunk/modules/implementation-jaxrs-runtime/src/test/java/helloworld/jaxrs/test/HelloWorldTestCase.java @@ -30,13 +30,11 @@ import org.apache.wink.client.ClientResponse; import org.apache.wink.client.RestClient; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; /** * */ -@Ignore public class HelloWorldTestCase { private static Node node; @@ -55,6 +53,8 @@ public class HelloWorldTestCase { public void testDummy() { RestClient client = new RestClient(); ClientResponse response = client.resource("http://localhost:8080/world").get(); + String out = response.getEntity(String.class); + System.out.println(out); Assert.assertEquals(200, response.getStatusCode()); } diff --git a/sca-java-2.x/trunk/modules/implementation-jaxrs/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/implementation-jaxrs/META-INF/MANIFEST.MF index f768396eb2..b2920bf5a6 100644 --- a/sca-java-2.x/trunk/modules/implementation-jaxrs/META-INF/MANIFEST.MF +++ b/sca-java-2.x/trunk/modules/implementation-jaxrs/META-INF/MANIFEST.MF @@ -8,7 +8,9 @@ Bundle-Version: 2.0.0 Bundle-ManifestVersion: 2 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-Description: Apache Tuscany SCA Implementation JAXRS Model -Import-Package: javax.xml.stream;resolution:=optional, +Import-Package: javax.ws.rs;version="1.0.0", + javax.ws.rs.core;version="1.0.0", + javax.xml.stream;resolution:=optional, org.apache.tuscany.sca.assembly;version="2.0.0", org.apache.tuscany.sca.assembly.builder;version="2.0.0", org.apache.tuscany.sca.assembly.impl;version="2.0.0", @@ -18,6 +20,8 @@ Import-Package: javax.xml.stream;resolution:=optional, org.apache.tuscany.sca.contribution.resolver;version="2.0.0", org.apache.tuscany.sca.core;version="2.0.0", org.apache.tuscany.sca.implementation.jaxrs;version="2.0.0", + org.apache.tuscany.sca.interfacedef;version="2.0.0", + org.apache.tuscany.sca.interfacedef.java;version="2.0.0", org.apache.tuscany.sca.monitor;version="2.0.0", org.apache.tuscany.sca.policy;version="2.0.0", org.apache.tuscany.sca.runtime;version="2.0.0", diff --git a/sca-java-2.x/trunk/modules/implementation-jaxrs/pom.xml b/sca-java-2.x/trunk/modules/implementation-jaxrs/pom.xml index 7f5f47f8da..23dce9ab5c 100644 --- a/sca-java-2.x/trunk/modules/implementation-jaxrs/pom.xml +++ b/sca-java-2.x/trunk/modules/implementation-jaxrs/pom.xml @@ -55,16 +55,28 @@ 2.0-SNAPSHOT + + org.apache.tuscany.sca + tuscany-interface-java + 2.0-SNAPSHOT + + org.apache.tuscany.sca tuscany-monitor 2.0-SNAPSHOT + + org.apache.tuscany.sca + tuscany-binding-rest + 2.0-SNAPSHOT + + javax.ws.rs jsr311-api - 1.0 + 1.1 diff --git a/sca-java-2.x/trunk/modules/implementation-jaxrs/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/impl/JAXRSImplementationImpl.java b/sca-java-2.x/trunk/modules/implementation-jaxrs/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/impl/JAXRSImplementationImpl.java index 99f6f8df59..4c19f1b52e 100644 --- a/sca-java-2.x/trunk/modules/implementation-jaxrs/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/impl/JAXRSImplementationImpl.java +++ b/sca-java-2.x/trunk/modules/implementation-jaxrs/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/impl/JAXRSImplementationImpl.java @@ -18,10 +18,6 @@ */ package org.apache.tuscany.sca.implementation.jaxrs.impl; -import java.util.Collections; -import java.util.List; - -import org.apache.tuscany.sca.assembly.Service; import org.apache.tuscany.sca.assembly.impl.ImplementationImpl; import org.apache.tuscany.sca.implementation.jaxrs.JAXRSImplementation; @@ -40,11 +36,6 @@ public class JAXRSImplementationImpl extends ImplementationImpl implements JAXRS super(TYPE); } - public List getServices() { - // The Web implementation does not offer services - return Collections.emptyList(); - } - public String getApplication() { return application; } diff --git a/sca-java-2.x/trunk/modules/implementation-jaxrs/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/xml/JAXRSImplementationProcessor.java b/sca-java-2.x/trunk/modules/implementation-jaxrs/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/xml/JAXRSImplementationProcessor.java index 037d8f385a..da25b6edd5 100644 --- a/sca-java-2.x/trunk/modules/implementation-jaxrs/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/xml/JAXRSImplementationProcessor.java +++ b/sca-java-2.x/trunk/modules/implementation-jaxrs/src/main/java/org/apache/tuscany/sca/implementation/jaxrs/xml/JAXRSImplementationProcessor.java @@ -20,11 +20,17 @@ package org.apache.tuscany.sca.implementation.jaxrs.xml; import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import javax.ws.rs.Path; +import javax.ws.rs.core.Application; 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.Service; +import org.apache.tuscany.sca.binding.rest.RESTBinding; +import org.apache.tuscany.sca.binding.rest.RESTBindingFactory; import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor; import org.apache.tuscany.sca.contribution.processor.ContributionReadException; import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; @@ -37,6 +43,11 @@ import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.implementation.jaxrs.JAXRSImplementation; import org.apache.tuscany.sca.implementation.jaxrs.JAXRSImplementationFactory; +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.ServiceRuntimeException; /** * Implements a StAX artifact processor for Web implementations. @@ -45,11 +56,17 @@ public class JAXRSImplementationProcessor extends BaseStAXArtifactProcessor impl StAXArtifactProcessor { private static final QName IMPLEMENTATION_JAXRS = JAXRSImplementation.TYPE; + private AssemblyFactory assemblyFactory; private JAXRSImplementationFactory implementationFactory; + private RESTBindingFactory restBindingFactory; + private JavaInterfaceFactory javaInterfaceFactory; public JAXRSImplementationProcessor(ExtensionPointRegistry extensionPoints) { FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); this.implementationFactory = modelFactories.getFactory(JAXRSImplementationFactory.class); + this.restBindingFactory = modelFactories.getFactory(RESTBindingFactory.class); + this.javaInterfaceFactory = modelFactories.getFactory(JavaInterfaceFactory.class); } public QName getArtifactType() { @@ -91,6 +108,44 @@ public class JAXRSImplementationProcessor extends BaseStAXArtifactProcessor impl classReference = resolver.resolveModel(ClassReference.class, classReference, context); implementation.setApplicationClass(classReference.getJavaClass()); implementation.setUnresolved(false); + + Application application; + try { + application = (Application) implementation.getApplicationClass().newInstance(); + } catch (Exception e) { + throw new ContributionResolveException(e); + } + + for(Class rootResourceClass: application.getClasses()) { + addService(implementation, rootResourceClass); + } + for(Object rootResource: application.getSingletons()) { + addService(implementation, rootResource.getClass()); + } + + } + + private void addService(JAXRSImplementation implementation, Class rootResourceClass) { + Service service = assemblyFactory.createService(); + JavaInterfaceContract contract = javaInterfaceFactory.createJavaInterfaceContract(); + JavaInterface javaInterface; + try { + javaInterface = javaInterfaceFactory.createJavaInterface(rootResourceClass); + } catch (InvalidInterfaceException e) { + throw new ServiceRuntimeException(e); + } + contract.setInterface(javaInterface); + service.setInterfaceContract(contract); + RESTBinding binding = restBindingFactory.createRESTBinding(); + // FIXME: The @ApplicationPath is available for JAX-RS 1.1 + // binding.setURI("/"); + Path path = rootResourceClass.getAnnotation(Path.class); + if (path != null) { + binding.setURI(path.value()); + } + service.getBindings().add(binding); + service.setName(rootResourceClass.getSimpleName()); + implementation.getServices().add(service); } public void write(JAXRSImplementation implementation, XMLStreamWriter writer, ProcessorContext context) diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxrs/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/interface-java-jaxrs/META-INF/MANIFEST.MF index 355879ca0e..f45e70ad23 100644 --- a/sca-java-2.x/trunk/modules/interface-java-jaxrs/META-INF/MANIFEST.MF +++ b/sca-java-2.x/trunk/modules/interface-java-jaxrs/META-INF/MANIFEST.MF @@ -10,7 +10,7 @@ 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;version="1.0.0", +Import-Package: javax.ws.rs, org.apache.tuscany.sca.interfacedef, org.apache.tuscany.sca.interfacedef.java, org.apache.tuscany.sca.interfacedef.java.impl, diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxrs/pom.xml b/sca-java-2.x/trunk/modules/interface-java-jaxrs/pom.xml index 991f778b48..c6410c1c83 100644 --- a/sca-java-2.x/trunk/modules/interface-java-jaxrs/pom.xml +++ b/sca-java-2.x/trunk/modules/interface-java-jaxrs/pom.xml @@ -32,7 +32,7 @@ javax.ws.rs jsr311-api - 1.0 + 1.1 diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSJavaInterfaceProcessor.java b/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSJavaInterfaceProcessor.java index 49fbb31a30..71683ba2c4 100644 --- a/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSJavaInterfaceProcessor.java +++ b/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/JAXRSJavaInterfaceProcessor.java @@ -21,10 +21,15 @@ package org.apache.tuscany.sca.interfacedef.java.jaxrs; 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; @@ -35,68 +40,69 @@ 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> mapping = new HashMap>(); + 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; + HttpMethod httpMethod = method.getAnnotation(HttpMethod.class); + if (httpMethod != null) { + methodName = httpMethod.value(); + } + if (method.isAnnotationPresent(GET.class)) { + methodName = HttpMethod.GET; + } else if (method.isAnnotationPresent(POST.class)) { + methodName = HttpMethod.POST; + } else if (method.isAnnotationPresent(PUT.class)) { + methodName = HttpMethod.PUT; + } else if (method.isAnnotationPresent(DELETE.class)) { + methodName = HttpMethod.DELETE; + } else if (method.isAnnotationPresent(HEAD.class)) { + methodName = HttpMethod.HEAD; + } else if (method.isAnnotationPresent(OPTIONS.class)) { + methodName = HttpMethod.OPTIONS; + } + + boolean jaxrs = false; + Class type = mapping.get(methodName); + if (type != null) { + jaxrs = true; + operation.getAttributes().put(type, Boolean.TRUE); + Map attrs = operation.getInterface().getAttributes(); + List operations = (List)attrs.get(type); + if (operations == null) { + operations = new ArrayList(); + attrs.put(type, operations); + operations.add(operation); + } else { + operations.add(operation); + } + } + + return jaxrs; + + } public void visitInterface(JavaInterface contract) throws InvalidInterfaceException { - - final Class clazz = contract.getJavaClass(); - List getOperations = new ArrayList(); - List putOperations = new ArrayList(); - List postOperations = new ArrayList(); - List deleteOperations = new ArrayList(); - boolean hasJAXRSAnnotarions = false; - + for (Operation op : contract.getOperations()) { final JavaOperation operation = (JavaOperation)op; - final Method method = operation.getJavaMethod(); - - GET get = method.getAnnotation(GET.class); - if(get != null) { - hasJAXRSAnnotarions = true; - operation.getAttributes().put(GET.class, true); - getOperations.add(operation); - } - - PUT put = method.getAnnotation(PUT.class); - if(put != null) { - hasJAXRSAnnotarions = true; - operation.getAttributes().put(PUT.class, true); - putOperations.add(operation); - } - - POST post = method.getAnnotation(POST.class); - if(post != null) { - hasJAXRSAnnotarions = true; - operation.getAttributes().put(POST.class, true); - postOperations.add(operation); - } - - DELETE delete = method.getAnnotation(DELETE.class); - if(delete != null) { + if (introspectHTTPMethod(operation)) { hasJAXRSAnnotarions = true; - operation.getAttributes().put(DELETE.class, true); - deleteOperations.add(operation); } } - - if(! getOperations.isEmpty()) { - contract.getAttributes().put(GET.class, getOperations); - } - - if(! putOperations.isEmpty()) { - contract.getAttributes().put(PUT.class, putOperations); - } - if(! postOperations.isEmpty()) { - contract.getAttributes().put(POST.class, postOperations); - } - - if(! deleteOperations.isEmpty()) { - contract.getAttributes().put(DELETE.class, deleteOperations); - } - - // Always set JAX-RS annotated interfaces as remotables if (hasJAXRSAnnotarions) { contract.setRemotable(true); diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGenerator.java b/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGenerator.java index ebe4bb4e17..0d23295986 100644 --- a/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGenerator.java +++ b/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGenerator.java @@ -19,6 +19,7 @@ package org.apache.tuscany.sca.interfacedef.java.jaxrs; +import java.lang.reflect.Field; import java.lang.reflect.Method; import org.objectweb.asm.AnnotationVisitor; @@ -33,19 +34,27 @@ public class RootResourceClassGenerator implements Opcodes { private static final String DELEGATE_FIELD = "delegate"; - public static Class generateRootResourceClass(Class interfaze, String path) throws Exception { + 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"; - byte[] content = generate(interfaze, path); + 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) throws Exception { + 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 = @@ -56,6 +65,7 @@ public class RootResourceClassGenerator implements Opcodes { declareClass(cw, interfaceName, className); annotatePath(cw, path); + annotateContentTypes(cw, consumes, produces); declareField(cw, interfaceName); declareConstructor(cw, className); @@ -142,4 +152,28 @@ public class RootResourceClassGenerator implements Opcodes { av.visit("value", path); av.visitEnd(); } + + // @Consumes() + // @Provides() + 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(); + } + } } diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/ResourceWrapper.java b/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/ResourceWrapper.java index 625a91c45a..23b674778e 100644 --- a/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/ResourceWrapper.java +++ b/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/ResourceWrapper.java @@ -19,10 +19,14 @@ package org.apache.tuscany.sca.interfacedef.java.jaxrs; +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; diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGeneratorTestCase.java b/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGeneratorTestCase.java index cef9fcf90e..aa6abcd5f6 100644 --- a/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGeneratorTestCase.java +++ b/sca-java-2.x/trunk/modules/interface-java-jaxrs/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxrs/RootResourceClassGeneratorTestCase.java @@ -22,7 +22,9 @@ package org.apache.tuscany.sca.interfacedef.java.jaxrs; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import javax.ws.rs.Consumes; import javax.ws.rs.Path; +import javax.ws.rs.Produces; import org.junit.Assert; import org.junit.Test; @@ -33,10 +35,17 @@ import org.junit.Test; public class RootResourceClassGeneratorTestCase { @Test public void testGenerator() throws Exception { - Class cls = RootResourceClassGenerator.generateRootResourceClass(Resource.class, "myURI"); + 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()); diff --git a/sca-java-2.x/trunk/modules/wink/pom.xml b/sca-java-2.x/trunk/modules/wink/pom.xml index 2b1d14e5a5..5444bdb8b5 100644 --- a/sca-java-2.x/trunk/modules/wink/pom.xml +++ b/sca-java-2.x/trunk/modules/wink/pom.xml @@ -47,13 +47,13 @@ org.apache.wink wink-server - 1.1-incubating-SNAPSHOT + 1.1-incubating provided org.apache.wink wink-common - 1.1-incubating-SNAPSHOT + 1.1-incubating provided -- cgit v1.2.3