HTTPCLIENT-1238: Contribute Bundle Activator And Central Proxy Configuration
Contributed by Simone Tripodi <simonetripodi at apache.org> git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1469247 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
68243b227f
commit
edeee62f8d
|
@ -1,6 +1,9 @@
|
||||||
Changes since release 4.3 BETA1
|
Changes since release 4.3 BETA1
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
* [HTTPCLIENT-1238] Contribute Bundle Activator And Central Proxy Configuration.
|
||||||
|
Contributed by Simone Tripodi <simonetripodi at apache.org>
|
||||||
|
|
||||||
* [HTTPCLIENT-1341] DeflateDecompressingEntity does not call Inflater#end.
|
* [HTTPCLIENT-1341] DeflateDecompressingEntity does not call Inflater#end.
|
||||||
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,11 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpcore</artifactId>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-codec</groupId>
|
<groupId>commons-codec</groupId>
|
||||||
<artifactId>commons-codec</artifactId>
|
<artifactId>commons-codec</artifactId>
|
||||||
|
@ -72,16 +77,30 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.osgi</groupId>
|
||||||
|
<artifactId>org.osgi.core</artifactId>
|
||||||
|
<version>4.2.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.osgi</groupId>
|
||||||
|
<artifactId>org.osgi.compendium</artifactId>
|
||||||
|
<version>4.2.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- test dependencies, mainly OSGi runtime environment -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>src/main/resources</directory>
|
<directory>src/main/resources</directory>
|
||||||
<filtering>true</filtering>
|
|
||||||
<includes>
|
|
||||||
<include>**/*.properties</include>
|
|
||||||
</includes>
|
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@ -103,6 +122,7 @@
|
||||||
org.apache.http.impl.cookie.*;version=${project.version},
|
org.apache.http.impl.cookie.*;version=${project.version},
|
||||||
org.apache.http.impl.conn.*;version=${project.version},
|
org.apache.http.impl.conn.*;version=${project.version},
|
||||||
org.apache.http.impl.client.*;version=${project.version}
|
org.apache.http.impl.client.*;version=${project.version}
|
||||||
|
org.apache.http.osgi.services;version=${project.version}
|
||||||
</_exportcontents>
|
</_exportcontents>
|
||||||
<Embed-Dependency>*;scope=compile|runtime;inline=true</Embed-Dependency>
|
<Embed-Dependency>*;scope=compile|runtime;inline=true</Embed-Dependency>
|
||||||
<Import-Package>
|
<Import-Package>
|
||||||
|
@ -111,10 +131,11 @@
|
||||||
javax.net,
|
javax.net,
|
||||||
javax.net.ssl,
|
javax.net.ssl,
|
||||||
javax.security.auth.x500,
|
javax.security.auth.x500,
|
||||||
org.ietf.jgss,
|
org.ietf.jgss,,
|
||||||
|
org.osgi.framework,
|
||||||
|
org.osgi.service.cm,
|
||||||
org.apache.commons.logging;version=${commons-logging.version},
|
org.apache.commons.logging;version=${commons-logging.version},
|
||||||
org.apache.http;version=${httpcore.version},
|
org.apache.http;version=${httpcore.version},
|
||||||
org.apache.http.config.*;version=${httpcore.version},
|
|
||||||
org.apache.http.concurrent;version=${httpcore.version},
|
org.apache.http.concurrent;version=${httpcore.version},
|
||||||
org.apache.http.entity;version=${httpcore.version},
|
org.apache.http.entity;version=${httpcore.version},
|
||||||
org.apache.http.io;version=${httpcore.version},
|
org.apache.http.io;version=${httpcore.version},
|
||||||
|
@ -130,6 +151,7 @@
|
||||||
net.sf.ehcache.*;resolution:=optional,
|
net.sf.ehcache.*;resolution:=optional,
|
||||||
net.spy.memcached.*;resolution:=optional
|
net.spy.memcached.*;resolution:=optional
|
||||||
</Import-Package>
|
</Import-Package>
|
||||||
|
<Bundle-Activator>org.apache.http.osgi.impl.HttpProxyConfigurationActivator</Bundle-Activator>
|
||||||
<!-- Stop the JAVA_1_n_HOME variables from being treated as headers by Bnd -->
|
<!-- Stop the JAVA_1_n_HOME variables from being treated as headers by Bnd -->
|
||||||
<_removeheaders>JAVA_1_3_HOME,JAVA_1_4_HOME</_removeheaders>
|
<_removeheaders>JAVA_1_3_HOME,JAVA_1_4_HOME</_removeheaders>
|
||||||
</instructions>
|
</instructions>
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.impl;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Dictionary;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.osgi.services.HttpClientBuilderFactory;
|
||||||
|
import org.apache.http.osgi.services.ProxyConfiguration;
|
||||||
|
import org.osgi.framework.BundleActivator;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.Constants;
|
||||||
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
import org.osgi.service.cm.ConfigurationException;
|
||||||
|
import org.osgi.service.cm.ManagedServiceFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
public final class HttpProxyConfigurationActivator implements BundleActivator, ManagedServiceFactory {
|
||||||
|
|
||||||
|
private static final String SERVICE_FACTORY_NAME = "Apache HTTP Client Proxy Configuration Factory";
|
||||||
|
|
||||||
|
private static final String SERVICE_PID = "org.apache.http.proxyconfigurator";
|
||||||
|
|
||||||
|
private ServiceRegistration configurator;
|
||||||
|
|
||||||
|
private ServiceRegistration clientFactory;
|
||||||
|
|
||||||
|
private BundleContext context;
|
||||||
|
|
||||||
|
private final Map<String, ServiceRegistration> registeredConfigurations = new LinkedHashMap<String, ServiceRegistration>();
|
||||||
|
|
||||||
|
private final List<CloseableHttpClient> trackedHttpClients = new LinkedList<CloseableHttpClient>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void start(final BundleContext context) throws Exception {
|
||||||
|
this.context = context;
|
||||||
|
|
||||||
|
// ensure we receive configurations for the proxy selector
|
||||||
|
final Hashtable<String, Object> props = new Hashtable<String, Object>();
|
||||||
|
props.put(Constants.SERVICE_PID, getName());
|
||||||
|
props.put(Constants.SERVICE_VENDOR, context.getBundle().getHeaders(Constants.BUNDLE_VENDOR));
|
||||||
|
props.put(Constants.SERVICE_DESCRIPTION, SERVICE_FACTORY_NAME);
|
||||||
|
|
||||||
|
configurator = context.registerService(ManagedServiceFactory.class.getName(), this, props);
|
||||||
|
clientFactory = context.registerService(HttpClientBuilderFactory.class.getName(),
|
||||||
|
new OSGiClientBuilderFactory(context, registeredConfigurations, trackedHttpClients),
|
||||||
|
props);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void stop(final BundleContext context) throws Exception {
|
||||||
|
// unregister services
|
||||||
|
for (final ServiceRegistration registeredConfiguration : registeredConfigurations.values()) {
|
||||||
|
registeredConfiguration.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
// unregister service factory
|
||||||
|
if (configurator != null) {
|
||||||
|
configurator.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientFactory != null) {
|
||||||
|
clientFactory.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure all http clients - generated with the - are terminated
|
||||||
|
for (final CloseableHttpClient client : trackedHttpClients) {
|
||||||
|
if (null != client) {
|
||||||
|
closeQuietly(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove all tracked services
|
||||||
|
registeredConfigurations.clear();
|
||||||
|
// remove all tracked created clients
|
||||||
|
trackedHttpClients.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return SERVICE_PID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void updated(final String pid, @SuppressWarnings("rawtypes") final Dictionary config) throws ConfigurationException {
|
||||||
|
final ServiceRegistration registration = registeredConfigurations.get(pid);
|
||||||
|
OSGiProxyConfiguration proxyConfiguration;
|
||||||
|
|
||||||
|
if (registration == null) {
|
||||||
|
proxyConfiguration = new OSGiProxyConfiguration();
|
||||||
|
final ServiceRegistration configurationRegistration = context.registerService(ProxyConfiguration.class.getName(),
|
||||||
|
proxyConfiguration,
|
||||||
|
config);
|
||||||
|
registeredConfigurations.put(pid, configurationRegistration);
|
||||||
|
} else {
|
||||||
|
proxyConfiguration = (OSGiProxyConfiguration) context.getService(registration.getReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") // data type is known
|
||||||
|
final
|
||||||
|
Dictionary<String, Object> properties = config;
|
||||||
|
proxyConfiguration.update(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void deleted(final String pid) {
|
||||||
|
final ServiceRegistration registeredConfiguration = registeredConfigurations.get(pid);
|
||||||
|
if (null != registeredConfiguration) {
|
||||||
|
registeredConfiguration.unregister();
|
||||||
|
registeredConfigurations.remove(pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void closeQuietly(final Closeable closeable) {
|
||||||
|
try {
|
||||||
|
closeable.close();
|
||||||
|
} catch (final IOException e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.osgi.services.HttpClientBuilderFactory;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
public final class OSGiClientBuilderFactory implements HttpClientBuilderFactory {
|
||||||
|
|
||||||
|
private final BundleContext bundleContext;
|
||||||
|
|
||||||
|
private final Map<String, ServiceRegistration> registeredConfigurations;
|
||||||
|
|
||||||
|
private final List<CloseableHttpClient> trackedHttpClients;
|
||||||
|
|
||||||
|
public OSGiClientBuilderFactory(
|
||||||
|
final BundleContext bundleContext,
|
||||||
|
final Map<String, ServiceRegistration> registeredConfigurations,
|
||||||
|
final List<CloseableHttpClient> trackedHttpClients) {
|
||||||
|
this.bundleContext = bundleContext;
|
||||||
|
this.registeredConfigurations = registeredConfigurations;
|
||||||
|
this.trackedHttpClients = trackedHttpClients;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpClientBuilder newBuilder() {
|
||||||
|
return new OSGiHttpClientBuilder(bundleContext, registeredConfigurations, trackedHttpClients);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.impl;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.http.auth.AuthScope;
|
||||||
|
import org.apache.http.auth.Credentials;
|
||||||
|
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||||
|
import org.apache.http.client.CredentialsProvider;
|
||||||
|
import org.apache.http.osgi.services.ProxyConfiguration;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
final class OSGiCredentialsProvider implements CredentialsProvider {
|
||||||
|
|
||||||
|
private final BundleContext bundleContext;
|
||||||
|
|
||||||
|
private final Map<String, ServiceRegistration> registeredConfigurations;
|
||||||
|
|
||||||
|
public OSGiCredentialsProvider(
|
||||||
|
final BundleContext bundleContext,
|
||||||
|
final Map<String, ServiceRegistration> registeredConfigurations) {
|
||||||
|
this.bundleContext = bundleContext;
|
||||||
|
this.registeredConfigurations = registeredConfigurations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void setCredentials(final AuthScope authscope, final Credentials credentials) {
|
||||||
|
// do nothing, not used in this version
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Credentials getCredentials(final AuthScope authscope) {
|
||||||
|
// iterate over all active proxy configurations at the moment of getting the credential
|
||||||
|
for (final ServiceRegistration registration : registeredConfigurations.values()) {
|
||||||
|
final Object proxyConfigurationObject = bundleContext.getService(registration.getReference());
|
||||||
|
if (proxyConfigurationObject != null) {
|
||||||
|
final ProxyConfiguration proxyConfiguration = (ProxyConfiguration) proxyConfigurationObject;
|
||||||
|
if (proxyConfiguration.isEnabled()) {
|
||||||
|
final AuthScope actual = new AuthScope(proxyConfiguration.getHostname(), proxyConfiguration.getPort());
|
||||||
|
if (authscope.equals(actual)) {
|
||||||
|
return new UsernamePasswordCredentials(proxyConfiguration.getUsername(),
|
||||||
|
proxyConfiguration.getPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// credentials no longer available!
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void clear() {
|
||||||
|
// do nothing, not used in this version
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
final class OSGiHttpClientBuilder extends HttpClientBuilder {
|
||||||
|
|
||||||
|
private final List<CloseableHttpClient> trackedHttpClients;
|
||||||
|
|
||||||
|
public OSGiHttpClientBuilder(
|
||||||
|
final BundleContext bundleContext,
|
||||||
|
final Map<String, ServiceRegistration> registeredConfigurations,
|
||||||
|
final List<CloseableHttpClient> trackedHttpClients) {
|
||||||
|
this.trackedHttpClients = trackedHttpClients;
|
||||||
|
setDefaultCredentialsProvider(
|
||||||
|
new OSGiCredentialsProvider(bundleContext, registeredConfigurations));
|
||||||
|
setRoutePlanner(
|
||||||
|
new OSGiHttpRoutePlanner(bundleContext, registeredConfigurations));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CloseableHttpClient build() {
|
||||||
|
final CloseableHttpClient httpClient = super.build();
|
||||||
|
trackedHttpClients.add(httpClient);
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,206 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.impl;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.http.HttpException;
|
||||||
|
import org.apache.http.HttpHost;
|
||||||
|
import org.apache.http.HttpRequest;
|
||||||
|
import org.apache.http.impl.conn.DefaultRoutePlanner;
|
||||||
|
import org.apache.http.osgi.services.ProxyConfiguration;
|
||||||
|
import org.apache.http.protocol.HttpContext;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
final class OSGiHttpRoutePlanner extends DefaultRoutePlanner {
|
||||||
|
|
||||||
|
private static final String DOT = ".";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The IP mask pattern against which hosts are matched.
|
||||||
|
*/
|
||||||
|
public static final Pattern IP_MASK_PATTERN = Pattern.compile("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
|
||||||
|
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
|
||||||
|
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
|
||||||
|
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
|
||||||
|
|
||||||
|
private final BundleContext bundleContext;
|
||||||
|
|
||||||
|
private final Map<String, ServiceRegistration> registeredConfigurations;
|
||||||
|
|
||||||
|
public OSGiHttpRoutePlanner(
|
||||||
|
final BundleContext bundleContext,
|
||||||
|
final Map<String, ServiceRegistration> registeredConfigurations) {
|
||||||
|
super(null);
|
||||||
|
this.bundleContext = bundleContext;
|
||||||
|
this.registeredConfigurations = registeredConfigurations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected HttpHost determineProxy(final HttpHost target, final HttpRequest request, final HttpContext context) throws HttpException {
|
||||||
|
ProxyConfiguration proxyConfiguration = null;
|
||||||
|
|
||||||
|
for (final ServiceRegistration registration : registeredConfigurations.values()) {
|
||||||
|
final Object proxyConfigurationObject = bundleContext.getService(registration.getReference());
|
||||||
|
if (proxyConfigurationObject != null) {
|
||||||
|
proxyConfiguration = (ProxyConfiguration) proxyConfigurationObject;
|
||||||
|
if (proxyConfiguration.isEnabled()) {
|
||||||
|
for (final String exception : proxyConfiguration.getProxyExceptions()) {
|
||||||
|
if (createMatcher(exception).matches(target.getHostName())) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return new HttpHost(proxyConfiguration.getHostname(), proxyConfiguration.getPort());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HostMatcher createMatcher(final String name) {
|
||||||
|
final NetworkAddress na = NetworkAddress.parse(name);
|
||||||
|
if (na != null) {
|
||||||
|
return new IPAddressMatcher(na);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.startsWith(DOT)) {
|
||||||
|
return new DomainNameMatcher(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HostNameMatcher(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static interface HostMatcher {
|
||||||
|
|
||||||
|
boolean matches(String host);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class HostNameMatcher implements HostMatcher {
|
||||||
|
|
||||||
|
private final String hostName;
|
||||||
|
|
||||||
|
HostNameMatcher(final String hostName) {
|
||||||
|
this.hostName = hostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matches(final String host) {
|
||||||
|
return hostName.equalsIgnoreCase(host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DomainNameMatcher implements HostMatcher {
|
||||||
|
|
||||||
|
private final String domainName;
|
||||||
|
|
||||||
|
DomainNameMatcher(final String domainName) {
|
||||||
|
this.domainName = domainName.toLowerCase(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matches(final String host) {
|
||||||
|
return host.toLowerCase(Locale.ENGLISH).endsWith(domainName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class IPAddressMatcher implements HostMatcher {
|
||||||
|
|
||||||
|
private final NetworkAddress address;
|
||||||
|
|
||||||
|
IPAddressMatcher(final NetworkAddress address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matches(final String host) {
|
||||||
|
final NetworkAddress hostAddress = NetworkAddress.parse(host);
|
||||||
|
return hostAddress != null && address.address == (hostAddress.address & address.mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NetworkAddress {
|
||||||
|
|
||||||
|
final int address;
|
||||||
|
|
||||||
|
final int mask;
|
||||||
|
|
||||||
|
static NetworkAddress parse(final String adrSpec) {
|
||||||
|
|
||||||
|
if (null != adrSpec) {
|
||||||
|
final Matcher nameMatcher = IP_MASK_PATTERN.matcher(adrSpec);
|
||||||
|
if (nameMatcher.matches()) {
|
||||||
|
try {
|
||||||
|
final int i1 = toInt(nameMatcher.group(1), 255);
|
||||||
|
final int i2 = toInt(nameMatcher.group(2), 255);
|
||||||
|
final int i3 = toInt(nameMatcher.group(3), 255);
|
||||||
|
final int i4 = toInt(nameMatcher.group(4), 255);
|
||||||
|
final int ip = i1 << 24 | i2 << 16 | i3 << 8 | i4;
|
||||||
|
|
||||||
|
int mask = toInt(nameMatcher.group(6), 32);
|
||||||
|
mask = (mask == 32) ? -1 : -1 - (-1 >>> mask);
|
||||||
|
|
||||||
|
return new NetworkAddress(ip, mask);
|
||||||
|
} catch (final NumberFormatException nfe) {
|
||||||
|
// not expected after the pattern match !
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int toInt(final String value, final int max) {
|
||||||
|
if (value == null || value.length() == 0) {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
int number = Integer.parseInt(value);
|
||||||
|
if (number > max) {
|
||||||
|
number = max;
|
||||||
|
}
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkAddress(final int address, final int mask) {
|
||||||
|
this.address = address;
|
||||||
|
this.mask = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.impl;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static org.apache.http.osgi.impl.PropertiesUtils.to;
|
||||||
|
|
||||||
|
import java.util.Dictionary;
|
||||||
|
|
||||||
|
import org.apache.http.osgi.services.ProxyConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
public final class OSGiProxyConfiguration implements ProxyConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property indicating whether this particular proxy is enabled (shall be used or not). Defaults to true.
|
||||||
|
*/
|
||||||
|
private static final String PROPERTYNAME_PROXY_ENABLED = "proxy.enabled";
|
||||||
|
|
||||||
|
private static final boolean PROPERTYDEFAULT_PROXY_ENABLED = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property representing the hostname of the proxy. Defaults to empty.
|
||||||
|
*/
|
||||||
|
private static final String PROPERTYNAME_PROXY_HOSTNAME = "proxy.host";
|
||||||
|
|
||||||
|
private static final String PROPERTYDEFAULT_PROXY_HOSTNAME = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property representing the port of the proxy. Defaults to 0.
|
||||||
|
*/
|
||||||
|
private static final String PROPERTYNAME_PROXY_PORT = "proxy.port";
|
||||||
|
|
||||||
|
private static final int PROPERTYDEFAULT_PROXY_PORT = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property representing the username to authenticate with towards the proxy. Defaults to empty.
|
||||||
|
*/
|
||||||
|
private static final String PROPERTYNAME_PROXY_USERNAME = "proxy.username";
|
||||||
|
|
||||||
|
private static final String PROPERTYDEFAULT_PROXY_USERNAME = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property representing the password to authenticate with towards the proxy. Defaults to empty.
|
||||||
|
*/
|
||||||
|
private static final String PROPERTYNAME_PROXY_PASSWORD = "proxy.password";
|
||||||
|
|
||||||
|
private static final String PROPERTYDEFAULT_PROXY_PASSWORD = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A multivalue property representing host patterns for which no proxy shall be used. By default localhost is
|
||||||
|
* excluded.
|
||||||
|
*/
|
||||||
|
private static final String PROPERTYNAME_PROXY_EXCEPTIONS = "proxy.exceptions";
|
||||||
|
|
||||||
|
private static final String[] PROPERTYDEFAULT_PROXY_EXCEPTIONS = new String[]{"localhost", "127.0.0.1"};
|
||||||
|
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
private String hostname;
|
||||||
|
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String[] proxyExceptions;
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHostname() {
|
||||||
|
return hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getProxyExceptions() {
|
||||||
|
return proxyExceptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(final Dictionary<String, Object> config) {
|
||||||
|
enabled = to(config.get(PROPERTYNAME_PROXY_ENABLED), boolean.class, PROPERTYDEFAULT_PROXY_ENABLED);
|
||||||
|
hostname = to(config.get(PROPERTYNAME_PROXY_HOSTNAME), String.class, PROPERTYDEFAULT_PROXY_HOSTNAME);
|
||||||
|
port = to(config.get(PROPERTYNAME_PROXY_PORT), int.class, PROPERTYDEFAULT_PROXY_PORT);
|
||||||
|
username = to(config.get(PROPERTYNAME_PROXY_USERNAME), String.class, PROPERTYDEFAULT_PROXY_USERNAME);
|
||||||
|
password = to(config.get(PROPERTYNAME_PROXY_PASSWORD), String.class, PROPERTYDEFAULT_PROXY_PASSWORD);
|
||||||
|
proxyExceptions = to(config.get(PROPERTYNAME_PROXY_EXCEPTIONS), String[].class, PROPERTYDEFAULT_PROXY_EXCEPTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return format("ProxyConfiguration [enabled=%s, hostname=%s, port=%s, username=%s, password=%s, proxyExceptions=%s]",
|
||||||
|
proxyExceptions, enabled, hostname, port, username, password, proxyExceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,199 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.impl;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
final class PropertiesUtils {
|
||||||
|
|
||||||
|
private static final Map<Class<?>, PropertyConverter<?>> CONVERTERS_REGISTRY =
|
||||||
|
new HashMap<Class<?>, PropertiesUtils.PropertyConverter<?>>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
register(new BooleanPropertyConverter(), boolean.class, Boolean.class);
|
||||||
|
register(new StringPropertyConverter(), String.class);
|
||||||
|
register(new StringArrayPropertyConverter(), String[].class);
|
||||||
|
register(new IntegerPropertyConverter(), int.class, Integer.class);
|
||||||
|
register(new LongPropertyConverter(), long.class, Long.class);
|
||||||
|
register(new DoublePropertyConverter(), double.class, Double.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void register(PropertyConverter<?> converter, Class<?>...targetTypes) {
|
||||||
|
for (Class<?> targetType : targetTypes) {
|
||||||
|
CONVERTERS_REGISTRY.put(targetType, converter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T to(Object propValue, Class<T> targetType, T defaultValue) {
|
||||||
|
if (propValue == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetType.isArray()) {
|
||||||
|
propValue = toObject(propValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetType.isInstance(propValue)) {
|
||||||
|
return targetType.cast(propValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONVERTERS_REGISTRY.containsKey(targetType)) {
|
||||||
|
@SuppressWarnings("unchecked") // type driven by targetType
|
||||||
|
PropertyConverter<T> converter = (PropertyConverter<T>) CONVERTERS_REGISTRY.get(targetType);
|
||||||
|
try {
|
||||||
|
return converter.to(propValue);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
// don't care, fall through to default value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parameter as a single value. If the
|
||||||
|
* parameter is neither an array nor a <code>java.util.Collection</code> the
|
||||||
|
* parameter is returned unmodified. If the parameter is a non-empty array,
|
||||||
|
* the first array element is returned. If the property is a non-empty
|
||||||
|
* <code>java.util.Collection</code>, the first collection element is returned.
|
||||||
|
*
|
||||||
|
* @param propValue the parameter to convert.
|
||||||
|
*/
|
||||||
|
private static Object toObject(Object propValue) {
|
||||||
|
if (propValue.getClass().isArray()) {
|
||||||
|
Object[] prop = (Object[]) propValue;
|
||||||
|
return prop.length > 0 ? prop[0] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propValue instanceof Collection<?>) {
|
||||||
|
Collection<?> prop = (Collection<?>) propValue;
|
||||||
|
return prop.isEmpty() ? null : prop.iterator().next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return propValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hidden constructor, this class must not be instantiated.
|
||||||
|
*/
|
||||||
|
private PropertiesUtils() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
private static interface PropertyConverter<T> {
|
||||||
|
|
||||||
|
T to(Object propValue);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BooleanPropertyConverter implements PropertyConverter<Boolean> {
|
||||||
|
|
||||||
|
public Boolean to(Object propValue) {
|
||||||
|
return Boolean.valueOf(String.valueOf(propValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class StringPropertyConverter implements PropertyConverter<String> {
|
||||||
|
|
||||||
|
public String to(Object propValue) {
|
||||||
|
return String.valueOf(propValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class StringArrayPropertyConverter implements PropertyConverter<String[]> {
|
||||||
|
|
||||||
|
public String[] to(Object propValue) {
|
||||||
|
if (propValue instanceof String) {
|
||||||
|
// single string
|
||||||
|
return new String[] { (String) propValue };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propValue.getClass().isArray()) {
|
||||||
|
// other array
|
||||||
|
Object[] valueArray = (Object[]) propValue;
|
||||||
|
List<String> values = new ArrayList<String>(valueArray.length);
|
||||||
|
for (Object value : valueArray) {
|
||||||
|
if (value != null) {
|
||||||
|
values.add(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values.toArray(new String[values.size()]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propValue instanceof Collection<?>) {
|
||||||
|
// collection
|
||||||
|
Collection<?> valueCollection = (Collection<?>) propValue;
|
||||||
|
List<String> valueList = new ArrayList<String>(valueCollection.size());
|
||||||
|
for (Object value : valueCollection) {
|
||||||
|
if (value != null) {
|
||||||
|
valueList.add(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valueList.toArray(new String[valueList.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't care, fall through to default value
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class IntegerPropertyConverter implements PropertyConverter<Integer> {
|
||||||
|
|
||||||
|
public Integer to(Object propValue) {
|
||||||
|
return Integer.valueOf(String.valueOf(propValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LongPropertyConverter implements PropertyConverter<Long> {
|
||||||
|
|
||||||
|
public Long to(Object propValue) {
|
||||||
|
return Long.valueOf(String.valueOf(propValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DoublePropertyConverter implements PropertyConverter<Double> {
|
||||||
|
|
||||||
|
public Double to(Object propValue) {
|
||||||
|
return Double.valueOf(String.valueOf(propValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.impl;
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi;
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.services;
|
||||||
|
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
public interface HttpClientBuilderFactory {
|
||||||
|
|
||||||
|
HttpClientBuilder newBuilder();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.services;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
public interface ProxyConfiguration {
|
||||||
|
|
||||||
|
boolean isEnabled();
|
||||||
|
|
||||||
|
String getHostname();
|
||||||
|
|
||||||
|
int getPort();
|
||||||
|
|
||||||
|
String getUsername();
|
||||||
|
|
||||||
|
String getPassword();
|
||||||
|
|
||||||
|
String[] getProxyExceptions();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.services;
|
|
@ -0,0 +1,77 @@
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
proxyconfigurator.name = Apache HTTP Components Proxy Configurator
|
||||||
|
proxyconfigurator.description = Factory configuration for transparent proxies used by every HTTP Client.
|
||||||
|
|
||||||
|
proxyconfig.name = Apache HTTP Components Proxy Configuration
|
||||||
|
proxyconfig.description = Proxy configuration for central and transparent proxying of http client connections.
|
||||||
|
|
||||||
|
proxy.enabled.name = Enable HTTP Proxy
|
||||||
|
proxy.enabled.description = Whether to enable or disable this particular proxy configuration. \
|
||||||
|
The default value is false.
|
||||||
|
|
||||||
|
proxy.host.name = HTTP Proxy Host
|
||||||
|
proxy.host.description = Host name (or IP Address) of the HTTP Proxy. This property is ignored if \
|
||||||
|
this proxy configuration is disabled. This property does not have a default value. Enabling \
|
||||||
|
this proxy but not setting the HTTP Proxy Host effectively disables this configuration.
|
||||||
|
|
||||||
|
proxy.port.name = HTTP Proxy Port
|
||||||
|
proxy.port.description = TCP port of the HTTP Proxy. This property is ignored if \
|
||||||
|
this proxy configuration is disabled. This property does not have a default value. Enabling \
|
||||||
|
this proxy but not setting the HTTP Proxy Port effectively disables this configuration.
|
||||||
|
|
||||||
|
proxy.user.name = HTTP Proxy User
|
||||||
|
proxy.user.description = The name of the user to authenticate as with the HTTP \
|
||||||
|
Proxy Host. If this field is empty, the proxy is considered to not be \
|
||||||
|
authenticated. The default is empty. This property is ignored if proxying is \
|
||||||
|
disabled or the proxy host is not properly configured.
|
||||||
|
|
||||||
|
proxy.password.name = HTTP Proxy Password
|
||||||
|
proxy.password.description = The password of the HTTP Proxy user to authenticate \
|
||||||
|
with. The default is empty. This property is ignored if proxying is \
|
||||||
|
disabled or the proxy host is not properly configured.
|
||||||
|
|
||||||
|
proxy.ntlm.host.name = HTTP Proxy NTLM Host
|
||||||
|
proxy.ntlm.host.description = The host the authentication request is \
|
||||||
|
originating from. Essentially, the computer name for this machine. By default \
|
||||||
|
the credentials assume simple username password authentication. If the proxy \
|
||||||
|
happens to be a Microsoft IIS Server using NTLM authentication this property \
|
||||||
|
must be set to the NT Domain name of the user to authenticate as. This is \
|
||||||
|
not set by default.
|
||||||
|
|
||||||
|
proxy.ntlm.domain.name = HTTP Proxy NTLM Domain
|
||||||
|
proxy.ntlm.domain.description = The NTLM domain to authenticate within. By \
|
||||||
|
default the credentials assume simple username password authentication. If \
|
||||||
|
the proxy happens to be a Microsoft IIS Server using NTLM authentication this \
|
||||||
|
property must be set to the NT Domain name of the user to authenticate as. \
|
||||||
|
This is not set by default.
|
||||||
|
|
||||||
|
proxy.exceptions.name = No Proxy For
|
||||||
|
proxy.exceptions.description = Lists domain names, host names, IP Addresses or \
|
||||||
|
or network addresses for which this proxy configuration should not be used. A domain \
|
||||||
|
name indicating all hosts of a domain is indicated by a leading dot, e.g. \
|
||||||
|
".day.com". A network address is indicated with subnet mask notation indicating \
|
||||||
|
the number of bits make up the network address, e.g 192.168.1.0/24 means the \
|
||||||
|
class C network "192.168.1". Note that for proxy selection, the host name of \
|
||||||
|
URL is not resolved but directly compared to the list of exceptions. For this \
|
||||||
|
reason you might want to indicate both the network address and the domain for \
|
||||||
|
targets which should not be passed through the proxy. This property has no \
|
||||||
|
effect if this proxy configuration is disabled. The default value is [ localhost, \
|
||||||
|
127.0.0.1 ].
|
|
@ -0,0 +1,76 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
====================================================================
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
This software consists of voluntary contributions made by many
|
||||||
|
individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
information on the Apache Software Foundation, please see
|
||||||
|
<http://www.apache.org />.
|
||||||
|
-->
|
||||||
|
<metatype:MetaData xmlns:metatype="http://www.osgi.org/xmlns/metatype/v1.0.0" localization="metatype">
|
||||||
|
|
||||||
|
<OCD id="org.apache.http.proxyconfigurator"
|
||||||
|
name="%proxyconfig.name"
|
||||||
|
description="%proxyconfig.description">
|
||||||
|
|
||||||
|
<AD id="proxy.enabled"
|
||||||
|
type="Boolean"
|
||||||
|
default="false"
|
||||||
|
name="%proxy.enabled.name"
|
||||||
|
description="%proxy.enabled.description" />
|
||||||
|
|
||||||
|
<AD id="proxy.host"
|
||||||
|
type="String"
|
||||||
|
default=""
|
||||||
|
name="%proxy.host.name"
|
||||||
|
description="%proxy.host.description" />
|
||||||
|
|
||||||
|
<AD id="proxy.port"
|
||||||
|
type="Integer"
|
||||||
|
default=""
|
||||||
|
name="%proxy.port.name"
|
||||||
|
description="%proxy.port.description" />
|
||||||
|
|
||||||
|
<AD id="proxy.user"
|
||||||
|
type="String"
|
||||||
|
default=""
|
||||||
|
name="%proxy.user.name"
|
||||||
|
description="%proxy.user.description" />
|
||||||
|
|
||||||
|
<AD id="proxy.password"
|
||||||
|
type="String"
|
||||||
|
default=""
|
||||||
|
name="%proxy.password.name"
|
||||||
|
description="%proxy.password.description" />
|
||||||
|
|
||||||
|
<AD id="proxy.exceptions"
|
||||||
|
type="String"
|
||||||
|
default="localhost,127.0.0.1"
|
||||||
|
cardinality="2147483647"
|
||||||
|
name="%proxy.exceptions.name"
|
||||||
|
description="%proxy.exceptions.description" />
|
||||||
|
|
||||||
|
</OCD>
|
||||||
|
|
||||||
|
<Designate pid="org.apache.http.proxyconfigurator">
|
||||||
|
<Object ocdref="org.apache.http.proxyconfigurator" />
|
||||||
|
</Designate>
|
||||||
|
|
||||||
|
</metatype:MetaData>
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.osgi.impl;
|
||||||
|
|
||||||
|
import static org.apache.http.osgi.impl.PropertiesUtils.to;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
public final class TestPropertiesUtils {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toBoolean() {
|
||||||
|
assertConverted(true, null, boolean.class, true);
|
||||||
|
assertConverted(true, null, Boolean.class, true);
|
||||||
|
assertConverted(false, "false", boolean.class, null);
|
||||||
|
assertConverted(false, "false", Boolean.class, null);
|
||||||
|
// whatever value is interpreted as `false` by Boolean.valueOf
|
||||||
|
assertConverted(false, "not a boolean", boolean.class, true);
|
||||||
|
assertConverted(false, "not a boolean", Boolean.class, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toSingleString() {
|
||||||
|
assertConverted("fallback to default value", null, String.class, "fallback to default value");
|
||||||
|
// use an object which represents the string
|
||||||
|
assertConverted("use the passed value", new StringBuilder("use the passed value"), String.class, null);
|
||||||
|
// use the "identity" converter
|
||||||
|
assertConverted("use the passed value", "use the passed value", String.class, null);
|
||||||
|
// convert another object
|
||||||
|
assertConverted("456789", 456789, String.class, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toStringArray() {
|
||||||
|
assertConvertedArray(new String[]{"fallback to default value"},
|
||||||
|
null,
|
||||||
|
String[].class,
|
||||||
|
new String[]{"fallback to default value"});
|
||||||
|
// a string is converted to an array with 1 element
|
||||||
|
assertConvertedArray(new String[]{"a single string"},
|
||||||
|
"a single string",
|
||||||
|
String[].class,
|
||||||
|
null);
|
||||||
|
// use an object which represents the string
|
||||||
|
assertConvertedArray(new String[]{"null objects", "will be ignored"},
|
||||||
|
new Object[]{new StringBuilder("null objects"), null, new StringBuilder("will be ignored")},
|
||||||
|
String[].class,
|
||||||
|
null);
|
||||||
|
// use the "identity" converter
|
||||||
|
assertConvertedArray(new String[]{"null objects", "will be ignored"},
|
||||||
|
new Object[]{"null objects", null, "will be ignored"},
|
||||||
|
String[].class,
|
||||||
|
null);
|
||||||
|
assertConvertedArray(new String[]{"fallback to default value"},
|
||||||
|
456789,
|
||||||
|
String[].class,
|
||||||
|
new String[]{"fallback to default value"});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toInt() {
|
||||||
|
assertConverted(123, null, int.class, 123);
|
||||||
|
assertConverted(123, null, Integer.class, 123);
|
||||||
|
assertConverted(456, "456", int.class, null);
|
||||||
|
assertConverted(456, "456", Integer.class, null);
|
||||||
|
assertConverted(789, "not an integer", int.class, 789);
|
||||||
|
assertConverted(789, "not an integer", Integer.class, 789);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toLong() {
|
||||||
|
assertConverted(123l, null, long.class, 123l);
|
||||||
|
assertConverted(123l, null, Long.class, 123l);
|
||||||
|
assertConverted(456l, "456", long.class, null);
|
||||||
|
assertConverted(456l, "456", Long.class, null);
|
||||||
|
assertConverted(789l, "not a long", long.class, 789l);
|
||||||
|
assertConverted(789l, "not a long", Long.class, 789l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toDouble() {
|
||||||
|
assertConverted(123d, null, double.class, 123d);
|
||||||
|
assertConverted(123d, null, Double.class, 123d);
|
||||||
|
assertConverted(456d, "456", double.class, null);
|
||||||
|
assertConverted(456d, "456", Double.class, null);
|
||||||
|
assertConverted(789d, "not a double", double.class, 789d);
|
||||||
|
assertConverted(789d, "not a double", Double.class, 789d);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void assertConverted(T expected, Object propValue, Class<T> targetType, T defaultValue) {
|
||||||
|
T actual = to(propValue, targetType, defaultValue);
|
||||||
|
assertEquals(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void assertConvertedArray(T[] expected, Object propValue, Class<T[]> targetType, T[] defaultValue) {
|
||||||
|
T[] actual = to(propValue, targetType, defaultValue);
|
||||||
|
assertArrayEquals(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue