package com.googlecode.jsonrpc4j.spring.rest; import com.fasterxml.jackson.databind.ObjectMapper; import com.googlecode.jsonrpc4j.JsonRpcClient; import com.googlecode.jsonrpc4j.JsonRpcClient.RequestListener; import com.googlecode.jsonrpc4j.ReflectionUtil; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.remoting.support.UrlBasedRemoteAccessor; import org.springframework.web.client.RestTemplate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Map; /** * @param <T> the bean type * @author toha */ @SuppressWarnings("unused") class JsonRestProxyFactoryBean<T> extends UrlBasedRemoteAccessor implements MethodInterceptor, InitializingBean, FactoryBean<T>, ApplicationContextAware { private T proxyObject = null; private RequestListener requestListener = null; private ObjectMapper objectMapper = null; private RestTemplate restTemplate = null; private JsonRpcRestClient jsonRpcRestClient = null; private Map<String, String> extraHttpHeaders = new HashMap<>(); private SSLContext sslContext = null; private HostnameVerifier hostNameVerifier = null; private ApplicationContext applicationContext; /** * {@inheritDoc} */ @Override public void afterPropertiesSet() { super.afterPropertiesSet(); proxyObject = ProxyFactory.getProxy(getObjectType(), this); if (objectMapper == null && applicationContext != null && applicationContext.containsBean("objectMapper")) { objectMapper = (ObjectMapper) applicationContext.getBean("objectMapper"); } if (objectMapper == null && applicationContext != null) { try { objectMapper = BeanFactoryUtils.beanOfTypeIncludingAncestors(applicationContext, ObjectMapper.class); } catch (Exception e) { logger.debug(e); } } if (objectMapper == null) { objectMapper = new ObjectMapper(); } try { jsonRpcRestClient = new JsonRpcRestClient(new URL(getServiceUrl()), objectMapper, restTemplate, new HashMap<String, String>()); jsonRpcRestClient.setRequestListener(requestListener); jsonRpcRestClient.setSslContext(sslContext); jsonRpcRestClient.setHostNameVerifier(hostNameVerifier); } catch (MalformedURLException mue) { throw new RuntimeException(mue); } } /** * {@inheritDoc} */ @Override public Object invoke(MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); if (method.getDeclaringClass() == Object.class && method.getName().equals("toString")) { return proxyObject.getClass().getName() + "@" + System.identityHashCode(proxyObject); } Type retType = (invocation.getMethod().getGenericReturnType() != null) ? invocation.getMethod().getGenericReturnType() : invocation.getMethod().getReturnType(); Object arguments = ReflectionUtil.parseArguments(invocation.getMethod(), invocation.getArguments()); return jsonRpcRestClient.invoke(invocation.getMethod().getName(), arguments, retType, extraHttpHeaders); } /** * {@inheritDoc} */ @Override public T getObject() { return proxyObject; } /** * {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public Class<T> getObjectType() { return (Class<T>) getServiceInterface(); } /** * {@inheritDoc} */ @Override public boolean isSingleton() { return true; } /** * {@inheritDoc} */ @Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } /** * @param objectMapper the objectMapper to set */ public void setObjectMapper(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } /** * @param extraHttpHeaders the extraHttpHeaders to set */ public void setExtraHttpHeaders(Map<String, String> extraHttpHeaders) { this.extraHttpHeaders = extraHttpHeaders; } /** * @param requestListener the requestListener to set */ public void setRequestListener(JsonRpcClient.RequestListener requestListener) { this.requestListener = requestListener; } /** * @param sslContext SSL contest for JsonRpcClient */ public void setSslContext(SSLContext sslContext) { this.sslContext = sslContext; } /** * @param hostNameVerifier the hostNameVerifier to pass to JsonRpcClient */ public void setHostNameVerifier(HostnameVerifier hostNameVerifier) { this.hostNameVerifier = hostNameVerifier; } /** * @param restTemplate external RestTemplate */ public void setRestTemplate(RestTemplate restTemplate) { this.restTemplate = restTemplate; } }