Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.wink.client.ClientConfig Maven / Gradle / Ivy
/*******************************************************************************
* 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.wink.client;
import java.io.FileNotFoundException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import javax.ws.rs.core.Application;
import org.apache.wink.client.handlers.ClientHandler;
import org.apache.wink.client.handlers.ConnectionHandler;
import org.apache.wink.client.internal.handlers.AcceptHeaderHandler;
import org.apache.wink.client.internal.handlers.HttpURLConnectionHandler;
import org.apache.wink.common.WinkApplication;
import org.apache.wink.common.internal.WinkConfiguration;
import org.apache.wink.common.internal.application.ApplicationFileLoader;
import org.apache.wink.common.internal.i18n.Messages;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Provides client configuration. The ClientConfig is implemented using the
* builder pattern so method calls can be easily aggregated. Custom Providers
* are defined by calling the {@link #applications(Application...)} method.
* Custom client handlers are defined by calling the
* {@link #handlers(ClientHandler...)} method.
*/
public class ClientConfig implements Cloneable, WinkConfiguration {
private static final Logger logger =
LoggerFactory
.getLogger(ClientConfig.class);
private String proxyHost;
private int proxyPort;
private boolean followRedirects;
private LinkedList handlers;
private LinkedList applications;
private boolean modifiable;
private boolean isAcceptHeaderAutoSet;
private boolean loadWinkApplications = true;
private boolean bypassHostnameVerification = false;
private static final String WINK_CLIENT_CONNECTTIMEOUT =
"wink.client.connectTimeout"; //$NON-NLS-1$
private static final String WINK_CLIENT_READTIMEOUT =
"wink.client.readTimeout"; //$NON-NLS-1$
private static final String WINK_SUPPORT_DTD_EXPANSION =
"wink.supportDTDEntityExpansion"; //$NON-NLS-1$
private static int WINK_CLIENT_CONNECTTIMEOUT_DEFAULT = 60000;
private static int WINK_CLIENT_READTIMEOUT_DEFAULT = 60000;
private static boolean WINK_CLIENT_SUPPORT_DTD_EXPANSION_DEFAULT = false;
private Properties properties = null;
/**
* Construct a new ClientConfig with the following default settings:
*
* proxy: none
* connect timeout: 60 seconds
* read timeout: 60 seconds
* follow redirects: true
*
*/
public ClientConfig() {
modifiable = true;
proxyHost = null;
proxyPort = 80;
followRedirects = true;
isAcceptHeaderAutoSet = true;
handlers = new LinkedList();
}
private void initDefaultApplication() {
if (applications != null) {
return;
} else {
applications = new LinkedList();
}
try {
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws FileNotFoundException{
final Set> classes =
new ApplicationFileLoader(loadWinkApplications).getClasses();
applications(new WinkApplication() {
@Override
public Set> getClasses() {
return classes;
}
@Override
public double getPriority() {
return WinkApplication.SYSTEM_PRIORITY;
}
});
return null;
}
});
} catch(PrivilegedActionException e) {
throw new ClientConfigException(e.getException());
}
}
/**
* Get the proxy host
*
* @return the proxy host
*/
public final String getProxyHost() {
return proxyHost;
}
/**
* Set the proxy host
*
* @param proxyHost proxy host
* @return this client configuration
* @throws ClientConfigException
*/
public final ClientConfig proxyHost(String proxyHost) {
if (!modifiable) {
throw new ClientConfigException(Messages.getMessage("clientConfigurationUnmodifiable")); //$NON-NLS-1$
}
this.proxyHost = proxyHost;
return this;
}
/**
* Get the proxy port
*
* @return the proxy port
*/
public final int getProxyPort() {
return proxyPort;
}
/**
* Set the proxy port
*
* @param proxyPort proxy port
* @return this client configuration
* @throws ClientConfigException
*/
public final ClientConfig proxyPort(int proxyPort) {
if (!modifiable) {
throw new ClientConfigException(Messages.getMessage("clientConfigurationUnmodifiable")); //$NON-NLS-1$
}
if (proxyPort <= 0) {
proxyPort = 80;
}
this.proxyPort = proxyPort;
return this;
}
/**
* Convenience method to get the int value of the wink.client.connectTimeout property
*
* @return the connect timeout in milliseconds
*/
public final int getConnectTimeout() {
try {
return Integer.valueOf(getProperties().getProperty(WINK_CLIENT_CONNECTTIMEOUT)).intValue();
} catch (NumberFormatException e) {
logger.trace("Value in properties for key {} is invalid. Reverting to default: {}", WINK_CLIENT_CONNECTTIMEOUT, WINK_CLIENT_CONNECTTIMEOUT_DEFAULT); //$NON-NLS-1$
getProperties().setProperty(WINK_CLIENT_CONNECTTIMEOUT, String.valueOf(WINK_CLIENT_CONNECTTIMEOUT_DEFAULT));
return getReadTimeout(); // this is safe, because it's unit tested. :)
}
}
/**
* Convenience method to set the wink.client.connectTimeout property
*
* @param connectTimeout the connect timeout in milliseconds
* @return this client configuration
* @throws ClientConfigException
*/
public final ClientConfig connectTimeout(int connectTimeout) {
if (!modifiable) {
throw new ClientConfigException(Messages.getMessage("clientConfigurationUnmodifiable")); //$NON-NLS-1$
}
getProperties().setProperty(WINK_CLIENT_CONNECTTIMEOUT, String.valueOf(connectTimeout));
return this;
}
/**
* Convenience method to get the int value of the wink.client.readTimeout property
*
* @return the read timeout in milliseconds
*/
public final int getReadTimeout() {
try {
return Integer.valueOf(getProperties().getProperty(WINK_CLIENT_READTIMEOUT)).intValue();
} catch (NumberFormatException e) {
logger.trace("Value in properties for key {} is invalid. Reverting to default: {}", WINK_CLIENT_READTIMEOUT, WINK_CLIENT_READTIMEOUT_DEFAULT); //$NON-NLS-1$
getProperties().setProperty(WINK_CLIENT_READTIMEOUT, String.valueOf(WINK_CLIENT_READTIMEOUT_DEFAULT));
return getReadTimeout(); // this is safe, because it's unit tested. :)
}
}
/**
* Convenience method to set the wink.client.readTimeout property
*
* @param readTimeout the read timeout in milliseconds
* @return this client configuration
* @throws ClientConfigException
*/
public final ClientConfig readTimeout(int readTimeout) {
if (!modifiable) {
throw new ClientConfigException(Messages.getMessage("clientConfigurationUnmodifiable")); //$NON-NLS-1$
}
getProperties().setProperty(WINK_CLIENT_READTIMEOUT, String.valueOf(readTimeout));
return this;
}
/**
* Convenience method to get the boolean value of the wink.supportDTDExpansion property
*
* @return boolean
*/
public final boolean isSupportDTDExpansion() {
// this is safe. See valueOf javadoc
return Boolean.valueOf(getProperties().getProperty(WINK_SUPPORT_DTD_EXPANSION)).booleanValue();
}
/**
* Convenience method to set the wink.supportDTDExpansion property
*
* @param supportDTDExpansion boolean
* @return this client configuration
* @throws ClientConfigException
*/
public final ClientConfig supportDTDExpansion(boolean supportDTDExpansion) {
if (!modifiable) {
throw new ClientConfigException(Messages.getMessage("clientConfigurationUnmodifiable")); //$NON-NLS-1$
}
getProperties().setProperty(WINK_SUPPORT_DTD_EXPANSION, String.valueOf(supportDTDExpansion));
return this;
}
/**
* Returns whether to client will automatically follow redirects
*
* @return true if client will automatically follow redirects; false
* otherwise
*/
public final boolean isFollowRedirects() {
return followRedirects;
}
/**
* Set whether to client will automatically follow redirects
*
* @param followRedirects whether to client will automatically follow
* redirects
* @return this client configuration
* @throws ClientConfigException
*/
public final ClientConfig followRedirects(boolean followRedirects) {
if (!modifiable) {
throw new ClientConfigException(Messages.getMessage("clientConfigurationUnmodifiable")); //$NON-NLS-1$
}
this.followRedirects = followRedirects;
return this;
}
/**
* Returns whether client will automatically set an appropriate Accept
* header
*
* @return true if client will automatically set an appropriate Accept
* header; false otherwise
*/
public final boolean isAcceptHeaderAutoSet() {
return isAcceptHeaderAutoSet;
}
/**
* Set whether client will automatically set an appropriate Accept header
*
* @param isAcceptHeaderAutoSet whether client will automatically set an
* appropriate Accept header
* @return this client configuration
* @throws ClientConfigException
*/
public final ClientConfig acceptHeaderAutoSet(boolean isAcceptHeaderAutoSet) {
if (!modifiable) {
throw new ClientConfigException(Messages.getMessage("clientConfigurationUnmodifiable")); //$NON-NLS-1$
}
this.isAcceptHeaderAutoSet = isAcceptHeaderAutoSet;
return this;
}
/**
* Get an unmodifiable list of the client handlers
*
* @return an unmodifiable list of the client handlers
*/
public final List getHandlers() {
return Collections.unmodifiableList(handlers);
}
/**
* Add client handlers
*
* @param handlers the handlers to add
* @return this client configuration
* @throws ClientConfigException
*/
public final ClientConfig handlers(ClientHandler... handlers) {
if (!modifiable) {
throw new ClientConfigException(Messages.getMessage("clientConfigurationUnmodifiable")); //$NON-NLS-1$
}
for (ClientHandler handler : handlers) {
this.handlers.add(handler);
}
return this;
}
/* package */ClientConfig build() {
if (isAcceptHeaderAutoSet) {
handlers.add(new AcceptHeaderHandler());
}
handlers.add(getConnectionHandler());
modifiable = false;
return this;
}
/**
* Returns the client handler that acts as the connection handler. This
* handler is always the last handler on the chain and is automatically
* added to the end of the defined list of handlers.
*
* This method should be overridden in order to provide an alternate
* connection handler.
*
* @return the connection handler
*/
protected ConnectionHandler getConnectionHandler() {
return new HttpURLConnectionHandler();
}
/**
* Get an unmodifiable list of the applications
*
* @return
*/
public final List getApplications() {
if (applications == null) {
initDefaultApplication();
}
return Collections.unmodifiableList(applications);
}
/**
* Add applications
*
* @param applications the applications to add
* @return this client configuration
* @throws ClientConfigException
*/
public final ClientConfig applications(Application... applications) {
if (!modifiable) {
throw new ClientConfigException(Messages.getMessage("clientConfigurationUnmodifiable")); //$NON-NLS-1$
}
if (this.applications == null) {
initDefaultApplication();
}
for (Application application : applications) {
this.applications.add(application);
}
return this;
}
@Override
protected ClientConfig clone() {
if (applications == null) {
initDefaultApplication();
}
try {
ClientConfig clone = (ClientConfig)super.clone();
clone.handlers = new LinkedList(handlers);
clone.applications = new LinkedList(applications);
// need to deep copy the properties:
// TODO: thread safe? Remember there's an Iterator at work under the putAll
Properties props = new Properties();
props.putAll(getProperties());
clone.setProperties(props);
return clone;
} catch (CloneNotSupportedException e) {
// can't happen
throw new RuntimeException(e);
}
}
public void setLoadWinkApplications(boolean loadWinkApplications) {
this.loadWinkApplications = loadWinkApplications;
}
public boolean isLoadWinkApplications() {
return loadWinkApplications;
}
/**
* Convenience method for getting all properties registered on this instance. System properties may be changed between creation of
* new instances.
*
* The following properties are meaningful to a ClientConfig instance:
* wink.client.connectTimeout - value is in milliseconds, default is 60000
* wink.client.readTimeout - value is in milliseconds, default is 60000
* wink.supportDTDExpansion - value is "true" or "false" to allow DOCTYPE entity expansion when built-in providers parse XML, default is "false"
*
* @return properties on this ClientConfig instance
*/
public Properties getProperties() {
if (properties == null) {
properties = new Properties();
try {
String connectTimeoutString = System.getProperty(WINK_CLIENT_CONNECTTIMEOUT, String.valueOf(WINK_CLIENT_CONNECTTIMEOUT_DEFAULT));
int toSet = Integer.parseInt(connectTimeoutString);
properties.put(WINK_CLIENT_CONNECTTIMEOUT, String.valueOf(toSet));
logger.trace("Wink client connectTimeout default value is {}.", toSet); //$NON-NLS-1$
} catch (Exception e) {
logger.trace("Error processing {} system property: {}", WINK_CLIENT_CONNECTTIMEOUT, e); //$NON-NLS-1$
}
try {
String readTimeoutString = System.getProperty(WINK_CLIENT_READTIMEOUT, String.valueOf(WINK_CLIENT_READTIMEOUT_DEFAULT));
int toSet = Integer.parseInt(readTimeoutString);
properties.put(WINK_CLIENT_READTIMEOUT, String.valueOf(toSet));
logger.trace("Wink client readTimeout default value is {}.", toSet); //$NON-NLS-1$
} catch (Exception e) {
logger.trace("Error processing {} system property: {}", WINK_CLIENT_READTIMEOUT, e); //$NON-NLS-1$
}
try {
String supportDTD = System.getProperty(WINK_SUPPORT_DTD_EXPANSION, String.valueOf(WINK_CLIENT_SUPPORT_DTD_EXPANSION_DEFAULT));
boolean toSet = Boolean.valueOf(supportDTD); // require "true" or "false", not "yes" or "no" or other variants (see parseBoolean vs. valueOf javadoc)
properties.put(WINK_SUPPORT_DTD_EXPANSION, String.valueOf(toSet));
if(logger.isTraceEnabled()) {
logger.trace("Wink client readTimeout default value is {}.", String.valueOf(toSet)); //$NON-NLS-1$
}
} catch (Exception e) {
logger.trace("Error processing {} system property: {}", WINK_SUPPORT_DTD_EXPANSION, e); //$NON-NLS-1$
}
}
return properties;
}
/**
* Convenience method to set the client configuration properties.
*
* The following properties are meaningful to a ClientConfig instance:
* wink.client.connectTimeout - value is in milliseconds, default is 60000
* wink.client.readTimeout - value is in milliseconds, default is 60000
* wink.supportDTDExpansion - value is "true" or "false" to allow DOCTYPE entity expansion when built-in providers parse XML, default is "false"
*
* @param properties the properties object to use. If properties parameter is null, the properties on this ClientConfig will be cleared with Properties.clear()
*/
public void setProperties(Properties properties) {
if (!modifiable) {
throw new ClientConfigException(Messages.getMessage("clientConfigurationUnmodifiable")); //$NON-NLS-1$
}
if (properties == null) {
this.properties.clear();
return;
}
this.properties = properties;
}
/**
* Get whether or not hostname verification will be bypassed for SSL
* certificates.
*
* @return Whether or not hostname verification will be bypassed for SSL
* certificates
*/
public boolean getBypassHostnameVerification() {
return bypassHostnameVerification;
}
/**
* Set whether or not hostname verification to bypass hostname verification
* for SSL certificates. Default value is false.
*
* @param bypassHostnameVerification true to bypass hostname verification
*/
public void setBypassHostnameVerification(boolean bypassHostnameVerification) {
this.bypassHostnameVerification = bypassHostnameVerification;
}
}