blob: 1e487abf511db8992ffbb515cdb3bc21bf2db113 [file] [log] [blame]
/**
* 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.cxf.jaxrs.client;
import java.lang.reflect.InvocationHandler;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.ws.rs.core.MultivaluedMap;
import org.apache.cxf.common.util.ProxyHelper;
import org.apache.cxf.feature.Feature;
import org.apache.cxf.jaxrs.model.UserResource;
/**
* Factory for creating proxy clients.
*
*/
public final class JAXRSClientFactory {
private JAXRSClientFactory() {
}
/**
* Creates a proxy
* @param baseAddress baseAddress
* @param cls resource class, if not interface then a CGLIB proxy will be created
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls) {
return create(URI.create(baseAddress), cls);
}
/**
* Creates a proxy using a custom class loader
* @param baseAddress baseAddress
* @param loader class loader
* @param cls resource class, if not interface then a CGLIB proxy will be created
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, ClassLoader loader) {
JAXRSClientFactoryBean bean = getBean(baseAddress, cls, null);
bean.setClassLoader(loader);
return bean.create(cls);
}
/**
* Creates a proxy
* @param baseURI baseURI
* @param cls resource class, if not interface then a CGLIB proxy will be created
* @return typed proxy
*/
public static <T> T create(URI baseURI, Class<T> cls) {
return create(baseURI, cls, false);
}
/**
* Creates a proxy
* @param baseURI baseURI
* @param cls resource class, if not interface then a CGLIB proxy will be created
* @param inheritHeaders if true then existing proxy headers will be inherited by
* subresource proxies if any
* @return typed proxy
*/
public static <T> T create(URI baseURI, Class<T> cls, boolean inheritHeaders) {
JAXRSClientFactoryBean bean = getBean(baseURI.toString(), cls, null);
bean.setInheritHeaders(inheritHeaders);
return bean.create(cls);
}
/**
* Creates a proxy
* @param baseAddress baseAddres
* @param cls resource class, if not interface then a CGLIB proxy will be created
* @param properties additional properties
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, Map<String, Object> properties) {
JAXRSClientFactoryBean bean = getBean(baseAddress, cls, null);
bean.setProperties(properties);
return bean.create(cls);
}
/**
* Creates a proxy
* @param baseAddress baseAddress
* @param cls resource class, if not interface then a CGLIB proxy will be created
* @param configLocation classpath location of the configuration resource
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, String configLocation) {
JAXRSClientFactoryBean bean = getBean(baseAddress, cls, configLocation);
return bean.create(cls);
}
/**
* Creates a proxy
* @param baseAddress baseAddress
* @param cls resource class, if not interface then a CGLIB proxy will be created
* This class is expected to have a root JAXRS Path annotation containing
* template variables, for ex, "/path/{id1}/{id2}"
* @param configLocation classpath location of the configuration resource
* @param varValues values to replace root Path template variables
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, String configLocation,
Object... varValues) {
JAXRSClientFactoryBean bean = getBean(baseAddress, cls, configLocation);
return bean.create(cls, varValues);
}
/**
* Creates a proxy
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param providers list of providers
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, List<?> providers) {
return create(baseAddress, cls, providers, null);
}
/**
* Creates a thread safe proxy
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param providers list of providers
* @param threadSafe if true then a thread-safe proxy will be created
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, List<?> providers, boolean threadSafe) {
return create(baseAddress, cls, providers, Collections.emptyMap(), threadSafe);
}
/**
* Creates a thread safe proxy
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param providers list of providers
* @param threadSafe if true then a thread-safe proxy will be created
* @param properties additional properties
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, List<?> providers,
Map<String, Object> properties, boolean threadSafe) {
JAXRSClientFactoryBean bean = getBean(baseAddress, cls, null);
bean.setProviders(providers);
bean.setProperties(properties);
if (threadSafe) {
bean.setInitialState(new ThreadLocalClientState(baseAddress, properties));
}
return bean.create(cls);
}
/**
* Creates a thread safe proxy and allows to specify time to keep state.
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param providers list of providers
* @param timeToKeepState how long to keep this state
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, List<?> providers, long timeToKeepState) {
JAXRSClientFactoryBean bean = getBean(baseAddress, cls, null);
bean.setProviders(providers);
bean.setInitialState(new ThreadLocalClientState(baseAddress, timeToKeepState));
return bean.create(cls);
}
/**
* Creates a proxy
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param providers list of providers
* @param configLocation classpath location of the configuration resource
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, List<?> providers, String configLocation) {
JAXRSClientFactoryBean bean = getBean(baseAddress, cls, configLocation);
bean.setProviders(providers);
return bean.create(cls);
}
/**
* Creates a proxy
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param providers list of providers
* @param features the features which will be applied to the client
* @param configLocation classpath location of the configuration resource
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, List<?> providers,
List<Feature> features,
String configLocation) {
JAXRSClientFactoryBean bean = getBean(baseAddress, cls, configLocation);
bean.setProviders(providers);
bean.setFeatures(features);
return bean.create(cls);
}
/**
* Creates a proxy which will do basic authentication
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param username username
* @param password password
* @param configLocation classpath location of the configuration resource
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, String username,
String password, String configLocation) {
JAXRSClientFactoryBean bean = getBean(baseAddress, cls, configLocation);
bean.setUsername(username);
bean.setPassword(password);
return bean.create(cls);
}
/**
* Creates a proxy which will do basic authentication
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param providers list of providers
* @param username username
* @param password password
* @param configLocation classpath location of the configuration resource
* @return typed proxy
*/
public static <T> T create(String baseAddress, Class<T> cls, List<?> providers,
String username, String password, String configLocation) {
JAXRSClientFactoryBean bean = getBean(baseAddress, cls, configLocation);
bean.setUsername(username);
bean.setPassword(password);
bean.setProviders(providers);
return bean.create(cls);
}
/**
* Creates a proxy using user resource model
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param modelRef model location
* @return typed proxy
*/
public static <T> T createFromModel(String baseAddress, Class<T> cls, String modelRef,
String configLocation) {
return createFromModel(baseAddress, cls, modelRef, Collections.emptyList(), configLocation);
}
/**
* Creates a proxy using user resource model
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param modelRef model location
* @param providers list of providers
* @param configLocation classpath location of the configuration resource
* @return typed proxy
*/
public static <T> T createFromModel(String baseAddress, Class<T> cls, String modelRef,
List<?> providers, String configLocation) {
JAXRSClientFactoryBean bean = WebClient.getBean(baseAddress, configLocation);
bean.setProviders(providers);
bean.setModelRef(modelRef);
bean.setServiceClass(cls);
return bean.create(cls);
}
/**
* Creates a thread safe proxy using user resource model
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param modelRef model location
* @param providers list of providers
* @param threadSafe if true then thread-safe proxy will be created
* @return typed proxy
*/
public static <T> T createFromModel(String baseAddress, Class<T> cls, String modelRef,
List<?> providers, boolean threadSafe) {
JAXRSClientFactoryBean bean = WebClient.getBean(baseAddress, null);
bean.setProviders(providers);
bean.setModelRef(modelRef);
bean.setServiceClass(cls);
if (threadSafe) {
bean.setInitialState(new ThreadLocalClientState(baseAddress));
}
return bean.create(cls);
}
/**
* Creates a thread safe proxy using user resource model and allows to
* specify time to keep state.
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param modelRef model location
* @param providers list of providers
* @param timeToKeepState how long to keep this state
* @return typed proxy
*/
public static <T> T createFromModel(String baseAddress, Class<T> cls, String modelRef,
List<?> providers, long timeToKeepState) {
JAXRSClientFactoryBean bean = WebClient.getBean(baseAddress, null);
bean.setProviders(providers);
bean.setModelRef(modelRef);
bean.setServiceClass(cls);
bean.setInitialState(new ThreadLocalClientState(baseAddress, timeToKeepState));
return bean.create(cls);
}
/**
* Creates a proxy using user resource model
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param modelBeans model beans
* @param configLocation classpath location of the configuration resource
* @return typed proxy
*/
public static <T> T createFromModel(String baseAddress, Class<T> cls, List<UserResource> modelBeans,
String configLocation) {
return createFromModel(baseAddress, cls, modelBeans, Collections.emptyList(), configLocation);
}
/**
* Creates a proxy using user resource model
* @param baseAddress baseAddress
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param modelBeans model beans
* @param providers list of providers
* @param configLocation classpath location of the configuration resource
* @return typed proxy
*/
public static <T> T createFromModel(String baseAddress, Class<T> cls, List<UserResource> modelBeans,
List<?> providers, String configLocation) {
JAXRSClientFactoryBean bean = WebClient.getBean(baseAddress, configLocation);
bean.setProviders(providers);
bean.setModelBeans(modelBeans);
bean.setServiceClass(cls);
return bean.create(cls);
}
/**
* Creates a proxy, baseURI will be set to Client currentURI
*
* @param client Client instance
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @return typed proxy
*/
public static <T> T fromClient(Client client, Class<T> cls) {
return fromClient(client, cls, false);
}
/**
* Creates a proxy, baseURI will be set to Client currentURI
* @param client Client instance
* @param cls proxy class, if not interface then a CGLIB proxy will be created
* @param inheritHeaders if true then existing Client headers will be inherited by new proxy
* and subresource proxies if any
* @return typed proxy
*/
public static <T> T fromClient(Client client, Class<T> cls, boolean inheritHeaders) {
JAXRSClientFactoryBean bean = getBean(client.getCurrentURI().toString(), cls, null);
bean.setInheritHeaders(inheritHeaders);
ClientState clientState = WebClient.getClientState(client);
final T proxy;
if (clientState == null) {
proxy = bean.create(cls);
if (inheritHeaders) {
WebClient.client(proxy).headers(client.getHeaders());
}
} else {
MultivaluedMap<String, String> headers = inheritHeaders ? client.getHeaders() : null;
bean.setInitialState(clientState.newState(client.getCurrentURI(), headers, null, bean.getProperties()));
proxy = bean.create(cls);
}
WebClient.copyProperties(WebClient.client(proxy), client);
return proxy;
}
static <T> T createProxy(Class<T> cls, ClassLoader loader, InvocationHandler handler) {
return cls.cast(ProxyHelper.getProxy(loader == null ? cls.getClassLoader() : loader,
new Class[]{Client.class, InvocationHandlerAware.class, cls},
handler));
}
private static JAXRSClientFactoryBean getBean(String baseAddress, Class<?> cls, String configLocation) {
JAXRSClientFactoryBean bean = WebClient.getBean(baseAddress, configLocation);
bean.setServiceClass(cls);
return bean;
}
}