summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x
diff options
context:
space:
mode:
authorrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2010-11-13 17:42:16 +0000
committerrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2010-11-13 17:42:16 +0000
commitefccdd821b68280ee3b73c8ef5cda121bc27f620 (patch)
treec43374b274b5bc3e943826af279ff23a526174b9 /sca-java-2.x
parentd2413f4a139158cc70a996c92b0730e64a239c87 (diff)
Improve jaxb/json databindings and jsonrpc binding to better handle interfaces
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1034820 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x')
-rw-r--r--sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/META-INF/MANIFEST.MF1
-rw-r--r--sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCBindingInvoker.java48
-rw-r--r--sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCClient.java293
-rw-r--r--sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCClientInvoker.java13
-rw-r--r--sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCReferenceBindingProvider.java19
-rw-r--r--sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java30
-rw-r--r--sca-java-2.x/trunk/modules/databinding-json/META-INF/MANIFEST.MF2
-rw-r--r--sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2Object.java3
-rw-r--r--sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java83
-rw-r--r--sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSON.java9
10 files changed, 444 insertions, 57 deletions
diff --git a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/META-INF/MANIFEST.MF
index 7c7b8e14a5..0ca3d9ef25 100644
--- a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/META-INF/MANIFEST.MF
+++ b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/META-INF/MANIFEST.MF
@@ -35,6 +35,7 @@ Import-Package: javax.security.auth.login,
org.apache.tuscany.sca.runtime;version="2.0.0",
org.jabsorb,
org.jabsorb.client,
+ org.jabsorb.serializer,
org.json,
org.oasisopen.sca;version="2.0.0",
org.oasisopen.sca.annotation;version="2.0.0"
diff --git a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCBindingInvoker.java b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCBindingInvoker.java
index ecca09dc92..3de6e57dda 100644
--- a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCBindingInvoker.java
+++ b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCBindingInvoker.java
@@ -26,9 +26,9 @@ import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.apache.tuscany.sca.assembly.EndpointReference;
-import org.apache.tuscany.sca.binding.jsonrpc.JSONRPCBinding;
import org.apache.tuscany.sca.databinding.json.JSONDataBinding;
import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Message;
import org.json.JSONArray;
@@ -39,18 +39,18 @@ import org.json.JSONObject;
*
* @version $Rev$ $Date$
*/
-public class JSONRPCBindingInvoker implements Invoker {
+public class JSONRPCBindingInvoker implements Invoker, DataExchangeSemantics {
private EndpointReference endpointReference;
private Operation operation;
private String uri;
-
+
private HttpClient httpClient;
public JSONRPCBindingInvoker(EndpointReference endpointReference, Operation operation, HttpClient httpClient) {
this.endpointReference = endpointReference;
this.operation = operation;
- this.uri = ((JSONRPCBinding) endpointReference.getBinding()).getURI();
-
+ this.uri = endpointReference.getBinding().getURI();
+
this.httpClient = httpClient;
}
@@ -64,9 +64,9 @@ public class JSONRPCBindingInvoker implements Invoker {
final String db = msg.getOperation().getWrapper().getDataBinding();
String req;
if (!db.equals(JSONDataBinding.NAME)) {
-
- JSONObject jsonRequest = null;;
+ JSONObject jsonRequest = null;
+ ;
Object[] args = null;
try {
// Extract the method
@@ -87,7 +87,7 @@ public class JSONRPCBindingInvoker implements Invoker {
}
req = jsonRequest.toString();
} else {
- req = (String)((Object[])msg.getBody())[0];
+ req = (String)((Object[])msg.getBody())[0];
}
StringEntity entity = new StringEntity(req, "UTF-8");
post.setEntity(entity);
@@ -97,20 +97,20 @@ public class JSONRPCBindingInvoker implements Invoker {
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//success
try {
- String entityResponse = EntityUtils.toString(response.getEntity());
+ String entityResponse = EntityUtils.toString(response.getEntity());
if (!db.equals(JSONDataBinding.NAME)) {
JSONObject jsonResponse = new JSONObject(entityResponse);
- //check requestId
- if (! jsonResponse.getString("id").equalsIgnoreCase(requestId)) {
- throw new RuntimeException("Invalid response id:" + requestId );
- }
+ //check requestId
+ if (!jsonResponse.getString("id").equalsIgnoreCase(requestId)) {
+ throw new RuntimeException("Invalid response id:" + requestId);
+ }
- msg.setBody(jsonResponse.get("result"));
+ msg.setBody(jsonResponse.get("result"));
} else {
- msg.setBody(entityResponse);
+ msg.setBody(entityResponse);
}
-
+
} catch (Exception e) {
//FIXME Exceptions are not handled correctly here
// They should be reported to the client JavaScript as proper
@@ -125,17 +125,18 @@ public class JSONRPCBindingInvoker implements Invoker {
return msg;
}
-
+
private static JSONObject getJSONRequest(Message msg) {
-
- JSONObject jsonRequest = null;;
+
+ JSONObject jsonRequest = null;
+ ;
Object[] args = null;
Object id = null;
try {
// Extract the method
jsonRequest = new JSONObject();
jsonRequest.putOpt("method", "Service" + "." + msg.getOperation().getName());
-
+
// Extract the arguments
args = msg.getBody();
JSONArray array = new JSONArray();
@@ -151,5 +152,10 @@ public class JSONRPCBindingInvoker implements Invoker {
return jsonRequest;
}
-
+
+ @Override
+ public boolean allowsPassByReference() {
+ return true;
+ }
+
}
diff --git a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCClient.java b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCClient.java
new file mode 100644
index 0000000000..f427233e52
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCClient.java
@@ -0,0 +1,293 @@
+/*
+ * 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.jsonrpc.provider;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
+
+import org.codehaus.jackson.JsonFactory;
+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.deser.CustomDeserializerFactory;
+import org.codehaus.jackson.map.deser.StdDeserializerProvider;
+import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector;
+import org.codehaus.jackson.map.ser.CustomSerializerFactory;
+import org.codehaus.jackson.map.type.TypeFactory;
+import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;
+import org.codehaus.jackson.xc.XmlAdapterJsonDeserializer;
+import org.codehaus.jackson.xc.XmlAdapterJsonSerializer;
+import org.jabsorb.JSONRPCBridge;
+import org.jabsorb.JSONRPCResult;
+import org.jabsorb.JSONSerializer;
+import org.jabsorb.client.ClientError;
+import org.jabsorb.client.ErrorResponse;
+import org.jabsorb.client.Session;
+import org.jabsorb.serializer.FixUp;
+import org.jabsorb.serializer.SerializerState;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class JSONRPCClient implements InvocationHandler {
+ // private static Logger log = LoggerFactory.getLogger(JsonrpcClient.class);
+
+ private Session session;
+ private JSONSerializer serializer;
+
+ /**
+ * Maintain a unique id for each message
+ */
+ private int id = 0;
+
+ /**
+ * Allow access to the serializer
+ *
+ * @return The serializer for this class
+ */
+ public JSONSerializer getSerializer() {
+ return serializer;
+ }
+
+ /**
+ * Create a client given a session
+ *
+ * @param session --
+ * transport session to use for this connection
+ */
+ public JSONRPCClient(Session session) {
+ try {
+ this.session = session;
+ serializer = new JSONSerializer();
+ serializer.registerDefaultSerializers();
+ serializer.setMarshallClassHints(false);
+ serializer.setMarshallNullAttributes(false);
+ } catch (Exception e) {
+ throw new ClientError(e);
+ }
+ }
+
+ private synchronized int getId() {
+ return id++;
+ }
+
+ /** Manual instantiation of HashMap<String, Object> */
+ private static class ProxyMap extends HashMap<Object, Object> {
+ public String getString(Object key) {
+ return (String)super.get(key);
+ }
+
+ public Object putString(String key, Object value) {
+ return super.put(key, value);
+ }
+ }
+
+ private ProxyMap proxyMap = new ProxyMap();
+
+ /**
+ * Create a proxy for communicating with the remote service.
+ *
+ * @param key
+ * the remote object key
+ * @param klass
+ * the class of the interface the remote object should adhere to
+ * @return created proxy
+ */
+ public Object openProxy(String key, Class klass) {
+ Object result = java.lang.reflect.Proxy.newProxyInstance(klass.getClassLoader(), new Class[] {klass}, this);
+ proxyMap.put(result, key);
+ return result;
+ }
+
+ /**
+ * Dispose of the proxy that is no longer needed
+ *
+ * @param proxy
+ */
+ public void closeProxy(Object proxy) {
+ proxyMap.remove(proxy);
+ }
+
+ /**
+ * This method is public because of the inheritance from the
+ * InvokationHandler -- should never be called directly.
+ */
+ public Object invoke(Object proxyObj, Method method, Object[] args) throws Exception {
+ String methodName = method.getName();
+ if (methodName.equals("hashCode")) {
+ return new Integer(System.identityHashCode(proxyObj));
+ } else if (methodName.equals("equals")) {
+ return (proxyObj == args[0] ? Boolean.TRUE : Boolean.FALSE);
+ } else if (methodName.equals("toString")) {
+ return proxyObj.getClass().getName() + '@' + Integer.toHexString(proxyObj.hashCode());
+ }
+ return invoke(proxyMap.getString(proxyObj),
+ method.getName(),
+ args,
+ method.getReturnType(),
+ method.getGenericReturnType());
+ }
+
+ private Object invoke(String objectTag, String methodName, Object[] args, Class returnType, Type genericReturnType)
+ throws Exception {
+ final int id = getId();
+ JSONObject message = new JSONObject();
+ String methodTag = objectTag == null ? "" : objectTag + ".";
+ methodTag += methodName;
+ message.put("method", methodTag);
+
+ {
+ SerializerState state = new SerializerState();
+
+ if (args != null) {
+
+ JSONArray params = marshal(args); // (JSONArray)serializer.marshall(state, /* parent */ null, args, "params");
+
+ if ((state.getFixUps() != null) && (state.getFixUps().size() > 0)) {
+ JSONArray fixups = new JSONArray();
+ for (Iterator i = state.getFixUps().iterator(); i.hasNext();) {
+ FixUp fixup = (FixUp)i.next();
+ fixups.put(fixup.toJSONArray());
+ }
+ message.put("fixups", fixups);
+ }
+ message.put("params", params);
+ } else {
+ message.put("params", new JSONArray());
+ }
+ }
+ message.put("id", id);
+
+ JSONObject responseMessage = session.sendAndReceive(message);
+
+ if (!responseMessage.has("result")) {
+ processException(responseMessage);
+ }
+ Object rawResult = responseMessage.get("result");
+ if (rawResult == null) {
+ processException(responseMessage);
+ }
+ if (returnType.equals(Void.TYPE)) {
+ return null;
+ }
+
+ {
+ JSONArray fixups = responseMessage.optJSONArray("fixups");
+
+ if (fixups != null) {
+ for (int i = 0; i < fixups.length(); i++) {
+ JSONArray assignment = fixups.getJSONArray(i);
+ JSONArray fixup = assignment.getJSONArray(0);
+ JSONArray original = assignment.getJSONArray(1);
+ JSONRPCBridge.applyFixup(rawResult, fixup, original);
+ }
+ }
+ }
+ if (returnType.isInterface()) {
+ ObjectMapper mapper = createObjectMapper(returnType);
+ return mapper.readValue(rawResult.toString(), TypeFactory.type(genericReturnType));
+ }
+ return serializer.unmarshall(new SerializerState(), returnType, rawResult);
+ }
+
+ private JSONArray marshal(Object[] args) throws Exception {
+ if(args==null) {
+ return new JSONArray();
+ }
+ ObjectMapper mapper = createObjectMapper(null);
+ String json = mapper.writeValueAsString(args);
+ return new JSONArray(json);
+ }
+
+ public static JsonParser createJsonParser(String content) {
+ JsonFactory jsonFactory = new JsonFactory();
+ try {
+ return jsonFactory.createJsonParser(content);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public static ObjectMapper createObjectMapper(Class<?> cls) {
+ ObjectMapper mapper = new ObjectMapper();
+ if (cls != null) {
+ // Workaround for http://jira.codehaus.org/browse/JACKSON-413
+ Package pkg = cls.getPackage();
+ if (pkg != null) {
+ XmlJavaTypeAdapters adapters = pkg.getAnnotation(XmlJavaTypeAdapters.class);
+ if (adapters != null) {
+ CustomSerializerFactory serializerFactory = new CustomSerializerFactory();
+ CustomDeserializerFactory deserializerFactory = new CustomDeserializerFactory();
+ for (XmlJavaTypeAdapter a : adapters.value()) {
+ XmlAdapter xmlAdapter = null;
+ try {
+ xmlAdapter = a.value().newInstance();
+ } catch (Throwable e) {
+ // Ignore
+ }
+ if (xmlAdapter != null) {
+ XmlAdapterJsonDeserializer deserializer = new XmlAdapterJsonDeserializer(xmlAdapter);
+ XmlAdapterJsonSerializer serializer = new XmlAdapterJsonSerializer(xmlAdapter);
+ deserializerFactory.addSpecificMapping(a.type(), deserializer);
+ serializerFactory.addGenericMapping(a.type(), serializer);
+ StdDeserializerProvider deserializerProvider =
+ new StdDeserializerProvider(deserializerFactory);
+ mapper.setSerializerFactory(serializerFactory);
+ mapper.setDeserializerProvider(deserializerProvider);
+ }
+ }
+ }
+ }
+ }
+ AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
+ 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;
+ }
+
+ /**
+ * Generate and throw exception based on the data in the 'responseMessage'
+ */
+ protected void processException(JSONObject responseMessage) throws JSONException {
+ JSONObject error = (JSONObject)responseMessage.get("error");
+ if (error != null) {
+ Integer code = new Integer(error.has("code") ? error.getInt("code") : 0);
+ String trace = error.has("trace") ? error.getString("trace") : null;
+ String msg = error.has("msg") ? error.getString("msg") : null;
+ throw new ErrorResponse(code, msg, trace);
+ } else
+ throw new ErrorResponse(new Integer(JSONRPCResult.CODE_ERR_PARSE),
+ "Unknown response:" + responseMessage.toString(2), null);
+ }
+
+}
diff --git a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCClientInvoker.java b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCClientInvoker.java
index 2b0859c416..3b2d2b707d 100644
--- a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCClientInvoker.java
+++ b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCClientInvoker.java
@@ -26,9 +26,9 @@ import org.apache.tuscany.sca.assembly.EndpointReference;
import org.apache.tuscany.sca.binding.jsonrpc.JSONRPCBinding;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Message;
-import org.jabsorb.client.Client;
import org.jabsorb.client.Session;
import org.jabsorb.client.TransportRegistry;
@@ -37,7 +37,7 @@ import org.jabsorb.client.TransportRegistry;
*
* @version $Rev$ $Date$
*/
-public class JSONRPCClientInvoker implements Invoker {
+public class JSONRPCClientInvoker implements Invoker, DataExchangeSemantics {
private EndpointReference endpointReference;
private Operation operation;
private Method method;
@@ -52,7 +52,7 @@ public class JSONRPCClientInvoker implements Invoker {
public Message invoke(Message msg) {
Session session = TransportRegistry.i().createSession(uri);
- Client client = new Client(session);
+ JSONRPCClient client = new JSONRPCClient(session);
Object proxy = client.openProxy("", method.getDeclaringClass());
try {
@@ -66,5 +66,10 @@ public class JSONRPCClientInvoker implements Invoker {
}
return msg;
}
-
+
+ @Override
+ public boolean allowsPassByReference() {
+ return true;
+ }
+
}
diff --git a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCReferenceBindingProvider.java b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCReferenceBindingProvider.java
index adc19202b3..3eaf6ceb7a 100644
--- a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCReferenceBindingProvider.java
+++ b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCReferenceBindingProvider.java
@@ -56,7 +56,7 @@ public class JSONRPCReferenceBindingProvider implements ReferenceBindingProvider
public JSONRPCReferenceBindingProvider(EndpointReference endpointReference) {
this.endpointReference = endpointReference;
- this.reference = (RuntimeComponentReference) endpointReference.getReference();
+ this.reference = (RuntimeComponentReference)endpointReference.getReference();
//clone the service contract to avoid databinding issues
/*
@@ -70,6 +70,10 @@ public class JSONRPCReferenceBindingProvider implements ReferenceBindingProvider
*/
// Create an HTTP client
+ httpClient = createHttpClient();
+ }
+
+ public HttpClient createHttpClient() {
HttpParams defaultParameters = new BasicHttpParams();
//defaultParameters.setIntParameter(HttpConnectionManagerParams.MAX_TOTAL_CONNECTIONS, 10);
HttpProtocolParams.setContentCharset(defaultParameters, HTTP.UTF_8);
@@ -79,9 +83,10 @@ public class JSONRPCReferenceBindingProvider implements ReferenceBindingProvider
SchemeRegistry supportedSchemes = new SchemeRegistry();
supportedSchemes.register(new Scheme(HttpHost.DEFAULT_SCHEME_NAME, PlainSocketFactory.getSocketFactory(), 80));
- ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(defaultParameters, supportedSchemes);
+ ClientConnectionManager connectionManager =
+ new ThreadSafeClientConnManager(defaultParameters, supportedSchemes);
- httpClient = new DefaultHttpClient(connectionManager, defaultParameters);
+ return new DefaultHttpClient(connectionManager, defaultParameters);
}
public InterfaceContract getBindingInterfaceContract() {
@@ -90,10 +95,10 @@ public class JSONRPCReferenceBindingProvider implements ReferenceBindingProvider
}
public Invoker createInvoker(Operation operation) {
- final Interface intf = reference.getInterfaceContract().getInterface();
- if (intf.isDynamic()) {
- return new JSONRPCBindingInvoker(endpointReference, operation, httpClient);
- }
+ final Interface intf = reference.getInterfaceContract().getInterface();
+ if (intf.isDynamic()) {
+ return new JSONRPCBindingInvoker(endpointReference, operation, httpClient);
+ }
return new JSONRPCClientInvoker(endpointReference, operation, httpClient);
}
diff --git a/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java b/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java
index 13eceb0d9a..9fa9038006 100644
--- a/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java
+++ b/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java
@@ -18,6 +18,7 @@
*/
package org.apache.tuscany.sca.databinding.jaxb;
+import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -363,6 +364,31 @@ public final class JAXBContextHelper {
return cls;
}
}
+
+ private static Class<?> erase(Type type) {
+ if (type instanceof Class) {
+ return (Class<?>)type;
+ }
+ if (type instanceof ParameterizedType) {
+ ParameterizedType pt = (ParameterizedType)type;
+ return (Class<?>)pt.getRawType();
+ }
+ if (type instanceof TypeVariable) {
+ TypeVariable tv = (TypeVariable)type;
+ Type[] bounds = tv.getBounds();
+ return (0 < bounds.length) ? erase(bounds[0]) : Object.class;
+ }
+ if (type instanceof WildcardType) {
+ WildcardType wt = (WildcardType)type;
+ Type[] bounds = wt.getUpperBounds();
+ return (0 < bounds.length) ? erase(bounds[0]) : Object.class;
+ }
+ if (type instanceof GenericArrayType) {
+ GenericArrayType gat = (GenericArrayType)type;
+ return Array.newInstance(erase(gat.getGenericComponentType()), 0).getClass();
+ }
+ throw new IllegalArgumentException("Unknown Type kind: " + type.getClass());
+ }
public static Class<?> getValueType(XmlJavaTypeAdapter adapter) {
if (adapter != null) {
@@ -371,9 +397,9 @@ public final class JAXBContextHelper {
Type superClass = adapterClass.getGenericSuperclass();
while (superClass instanceof ParameterizedType && XmlAdapter.class != ((ParameterizedType)superClass)
.getRawType()) {
- superClass = ((Class<?>)((ParameterizedType)superClass).getRawType()).getGenericSuperclass();
+ superClass = erase(superClass).getGenericSuperclass();
}
- return (Class<?>)((ParameterizedType)superClass).getActualTypeArguments()[0];
+ return erase(((ParameterizedType)superClass).getActualTypeArguments()[0]);
}
}
return null;
diff --git a/sca-java-2.x/trunk/modules/databinding-json/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/databinding-json/META-INF/MANIFEST.MF
index 42674a55f8..2882a31966 100644
--- a/sca-java-2.x/trunk/modules/databinding-json/META-INF/MANIFEST.MF
+++ b/sca-java-2.x/trunk/modules/databinding-json/META-INF/MANIFEST.MF
@@ -21,7 +21,9 @@ Import-Package: javax.xml.namespace,
org.apache.tuscany.sca.interfacedef.util;version="2.0.0",
org.codehaus.jackson,
org.codehaus.jackson.map,
+ org.codehaus.jackson.map.deser,
org.codehaus.jackson.map.introspect,
+ org.codehaus.jackson.map.ser,
org.codehaus.jackson.map.type,
org.codehaus.jackson.type,
org.codehaus.jackson.xc;resolution:=optional,
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 ca28ec5833..c7ae9d636d 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
@@ -38,7 +38,6 @@ public class JSON2Object implements PullTransformer<Object, Object> {
public JSON2Object() {
super();
- mapper = JacksonHelper.createObjectMapper();
}
public Object transform(Object source, TransformationContext context) {
@@ -47,6 +46,8 @@ public class JSON2Object implements PullTransformer<Object, Object> {
}
try {
+ Class<?> cls = context.getTargetDataType().getPhysical();
+ ObjectMapper mapper = JacksonHelper.createObjectMapper(cls);
JavaType javaType = TypeFactory.type(context.getTargetDataType().getGenericType());
if (source instanceof String) {
String sourceString = (String) source;
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 ae3bb8fd48..00ddc2601d 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
@@ -25,6 +25,10 @@ import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
+
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;
@@ -32,16 +36,63 @@ 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.MappingJsonFactory;
import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.deser.CustomDeserializerFactory;
+import org.codehaus.jackson.map.deser.StdDeserializerProvider;
import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector;
+import org.codehaus.jackson.map.ser.CustomSerializerFactory;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;
+import org.codehaus.jackson.xc.XmlAdapterJsonDeserializer;
+import org.codehaus.jackson.xc.XmlAdapterJsonSerializer;
/**
*
*/
public class JacksonHelper {
- public static ObjectMapper createObjectMapper() {
- ObjectMapper mapper = new ObjectMapper();
+ private final static ObjectMapper MAPPER = createMapper();
+ private final static JsonFactory FACTORY = new MappingJsonFactory(createMapper());
+
+ public static ObjectMapper createMapper() {
+ return createObjectMapper(null);
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public static ObjectMapper createObjectMapper(Class<?> cls) {
+ ObjectMapper mapper = null;
+ if (cls != null) {
+ // Workaround for http://jira.codehaus.org/browse/JACKSON-413
+ Package pkg = cls.getPackage();
+ if (pkg != null) {
+ XmlJavaTypeAdapters adapters = pkg.getAnnotation(XmlJavaTypeAdapters.class);
+ if (adapters != null) {
+ CustomSerializerFactory serializerFactory = new CustomSerializerFactory();
+ CustomDeserializerFactory deserializerFactory = new CustomDeserializerFactory();
+ for (XmlJavaTypeAdapter a : adapters.value()) {
+ XmlAdapter xmlAdapter = null;
+ try {
+ xmlAdapter = a.value().newInstance();
+ } catch (Throwable e) {
+ // Ignore
+ }
+ if (xmlAdapter != null) {
+ XmlAdapterJsonDeserializer deserializer = new XmlAdapterJsonDeserializer(xmlAdapter);
+ XmlAdapterJsonSerializer serializer = new XmlAdapterJsonSerializer(xmlAdapter);
+ deserializerFactory.addSpecificMapping(a.type(), deserializer);
+ serializerFactory.addGenericMapping(a.type(), serializer);
+ StdDeserializerProvider deserializerProvider =
+ new StdDeserializerProvider(deserializerFactory);
+ mapper = new ObjectMapper();
+ mapper.setSerializerFactory(serializerFactory);
+ mapper.setDeserializerProvider(deserializerProvider);
+ }
+ }
+ }
+ }
+ }
+ if (mapper == null) {
+ mapper = new ObjectMapper();
+ }
AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary, secondary);
@@ -52,13 +103,13 @@ public class JacksonHelper {
return mapper;
}
+ public static JsonFactory getJsonFactory() {
+ return FACTORY;
+ }
+
public static String toString(JsonNode node) {
try {
- JsonFactory jsonFactory = new JsonFactory();
- StringWriter sw = new StringWriter();
- JsonGenerator generator = jsonFactory.createJsonGenerator(sw);
- generator.writeTree(node);
- return sw.toString();
+ return MAPPER.writeValueAsString(node);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
@@ -66,7 +117,7 @@ public class JacksonHelper {
public static String toString(JsonParser parser) {
try {
- JsonFactory jsonFactory = new JsonFactory();
+ JsonFactory jsonFactory = getJsonFactory();
StringWriter sw = new StringWriter();
JsonGenerator generator = jsonFactory.createJsonGenerator(sw);
JsonNode node = parser.readValueAs(JsonNode.class);
@@ -78,7 +129,7 @@ public class JacksonHelper {
}
public static JsonParser createJsonParser(String content) {
- JsonFactory jsonFactory = new JsonFactory();
+ JsonFactory jsonFactory = getJsonFactory();
try {
return jsonFactory.createJsonParser(content);
} catch (IOException e) {
@@ -87,26 +138,26 @@ public class JacksonHelper {
}
public static JsonParser createJsonParser(InputStream content) {
- JsonFactory jsonFactory = new JsonFactory();
+ JsonFactory jsonFactory = getJsonFactory();
try {
return jsonFactory.createJsonParser(content);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
-
+
public static JsonParser createJsonParser(Reader content) {
- JsonFactory jsonFactory = new JsonFactory();
+ JsonFactory jsonFactory = getJsonFactory();
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();
+ JsonFactory jsonFactory = getJsonFactory();
JsonGenerator generator = jsonFactory.createJsonGenerator(out, JsonEncoding.UTF8);
generator.writeTree(node);
} catch (IOException e) {
@@ -116,7 +167,7 @@ public class JacksonHelper {
public static void write(JsonParser parser, OutputStream out) {
try {
- JsonFactory jsonFactory = new JsonFactory();
+ JsonFactory jsonFactory = getJsonFactory();
JsonGenerator generator = jsonFactory.createJsonGenerator(out, JsonEncoding.UTF8);
JsonNode node = parser.readValueAs(JsonNode.class);
generator.writeTree(node);
@@ -124,5 +175,5 @@ public class JacksonHelper {
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/Object2JSON.java b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSON.java
index d543d0554a..38b826b202 100644
--- a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSON.java
+++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSON.java
@@ -35,11 +35,9 @@ import org.codehaus.jackson.map.ObjectMapper;
* @version $Rev$ $Date$
*/
public class Object2JSON implements PullTransformer<Object, Object> {
- private ObjectMapper mapper;
public Object2JSON() {
super();
- mapper = JacksonHelper.createObjectMapper();
}
public Object transform(Object source, TransformationContext context) {
@@ -58,12 +56,11 @@ public class Object2JSON implements PullTransformer<Object, Object> {
if (targetType != null && targetType.isPrimitive()) {
return source;
}
+ ObjectMapper mapper = JacksonHelper.createObjectMapper(targetType);
String value = mapper.writeValueAsString(source);
- if (targetType == String.class ||
- targetType == Object.class ||
- targetType.isPrimitive()) {
+ if (targetType == String.class || targetType == Object.class || targetType.isPrimitive()) {
return value;
- } else if (targetType == BigDecimal.class){
+ } else if (targetType == BigDecimal.class) {
return value.toString();
} else if (JsonNode.class.isAssignableFrom(targetType)) {
return JacksonHelper.createJsonParser(value).readValueAsTree();