/**
* 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.camel.component.geocoder;
import java.security.InvalidKeyException;
import com.google.code.geocoder.AdvancedGeoCoder;
import com.google.code.geocoder.Geocoder;
import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.component.geocoder.http.AuthenticationHttpClientConfigurer;
import org.apache.camel.component.geocoder.http.AuthenticationMethod;
import org.apache.camel.component.geocoder.http.CompositeHttpConfigurer;
import org.apache.camel.component.geocoder.http.HttpClientConfigurer;
import org.apache.camel.impl.DefaultEndpoint;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriPath;
import org.apache.camel.util.ObjectHelper;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
/**
* The geocoder component is used for looking up geocodes (latitude and longitude) for a given address, or reverse lookup.
*/
@UriEndpoint(firstVersion = "2.12.0", scheme = "geocoder", title = "Geocoder", syntax = "geocoder:address:latlng", producerOnly = true, label = "api,location")
public class GeoCoderEndpoint extends DefaultEndpoint {
@UriPath
private String address;
@UriPath
private String latlng;
@UriParam(defaultValue = "en")
private String language = "en";
@UriParam
private String clientId;
@UriParam
private String clientKey;
@UriParam
private boolean headersOnly;
@UriParam(label = "proxy")
private String proxyHost;
@UriParam(label = "proxy")
private Integer proxyPort;
@UriParam(label = "proxy")
private String proxyAuthMethod;
@UriParam(label = "proxy")
private String proxyAuthUsername;
@UriParam(label = "proxy")
private String proxyAuthPassword;
@UriParam(label = "proxy")
private String proxyAuthDomain;
@UriParam(label = "proxy")
private String proxyAuthHost;
@UriParam(label = "advanced")
private HttpClientConfigurer httpClientConfigurer;
@UriParam(label = "advanced")
private HttpConnectionManager httpConnectionManager;
public GeoCoderEndpoint() {
}
public GeoCoderEndpoint(String uri, GeoCoderComponent component) {
super(uri, component);
}
public Producer createProducer() throws Exception {
return new GeoCoderProducer(this);
}
public Consumer createConsumer(Processor processor) throws Exception {
throw new UnsupportedOperationException("Cannot consume from this component");
}
public boolean isSingleton() {
return true;
}
public String getLanguage() {
return language;
}
/**
* The language to use.
*/
public void setLanguage(String language) {
this.language = language;
}
public String getAddress() {
return address;
}
/**
* The geo address which should be prefixed with <tt>address:</tt>
*/
public void setAddress(String address) {
this.address = address;
}
public String getLatlng() {
return latlng;
}
/**
* The geo latitude and longitude which should be prefixed with <tt>latlng:</tt>
*/
public void setLatlng(String latlng) {
this.latlng = latlng;
}
public boolean isHeadersOnly() {
return headersOnly;
}
/**
* Whether to only enrich the Exchange with headers, and leave the body as-is.
*/
public void setHeadersOnly(boolean headersOnly) {
this.headersOnly = headersOnly;
}
public String getClientId() {
return clientId;
}
/**
* To use google premium with this client id
*/
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientKey() {
return clientKey;
}
/**
* To use google premium with this client key
*/
public void setClientKey(String clientKey) {
this.clientKey = clientKey;
}
/**
* The proxy host name
*/
public void setProxyHost(String proxyHost) {
this.proxyHost = proxyHost;
}
public int getProxyPort() {
return proxyPort;
}
/**
* The proxy port number
*/
public void setProxyPort(int proxyPort) {
this.proxyPort = proxyPort;
}
public String getProxyAuthMethod() {
return proxyAuthMethod;
}
/**
* Authentication method for proxy, either as Basic, Digest or NTLM.
*/
public void setProxyAuthMethod(String proxyAuthMethod) {
this.proxyAuthMethod = proxyAuthMethod;
}
public String getProxyAuthUsername() {
return proxyAuthUsername;
}
/**
* Username for proxy authentication
*/
public void setProxyAuthUsername(String proxyAuthUsername) {
this.proxyAuthUsername = proxyAuthUsername;
}
public String getProxyAuthPassword() {
return proxyAuthPassword;
}
/**
* Password for proxy authentication
*/
public void setProxyAuthPassword(String proxyAuthPassword) {
this.proxyAuthPassword = proxyAuthPassword;
}
public String getProxyAuthDomain() {
return proxyAuthDomain;
}
/**
* Domain for proxy NTML authentication
*/
public void setProxyAuthDomain(String proxyAuthDomain) {
this.proxyAuthDomain = proxyAuthDomain;
}
public String getProxyAuthHost() {
return proxyAuthHost;
}
/**
* Optional host for proxy NTML authentication
*/
public void setProxyAuthHost(String proxyAuthHost) {
this.proxyAuthHost = proxyAuthHost;
}
public HttpClientConfigurer getHttpClientConfigurer() {
return httpClientConfigurer;
}
/**
* Register a custom configuration strategy for new {@link HttpClient} instances
* created by producers or consumers such as to configure authentication mechanisms etc
*
* @param httpClientConfigurer the strategy for configuring new {@link HttpClient} instances
*/
public void setHttpClientConfigurer(HttpClientConfigurer httpClientConfigurer) {
this.httpClientConfigurer = httpClientConfigurer;
}
public HttpConnectionManager getHttpConnectionManager() {
return httpConnectionManager;
}
/**
* To use a custom HttpConnectionManager to manage connections
*/
public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) {
this.httpConnectionManager = httpConnectionManager;
}
Geocoder createGeocoder() throws InvalidKeyException {
HttpConnectionManager connectionManager = this.httpConnectionManager;
if (connectionManager == null) {
connectionManager = new MultiThreadedHttpConnectionManager();
}
HttpClient httpClient = new HttpClient(connectionManager);
if (proxyHost != null && proxyPort != null) {
httpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);
}
// validate that if proxy auth username is given then the proxy auth method is also provided
if (proxyAuthUsername != null && proxyAuthMethod == null) {
throw new IllegalArgumentException("Option proxyAuthMethod must be provided to use proxy authentication");
}
CompositeHttpConfigurer configurer = new CompositeHttpConfigurer();
if (proxyAuthMethod != null) {
configureProxyAuth(configurer, proxyAuthMethod, proxyAuthUsername, proxyAuthPassword, proxyAuthDomain, proxyAuthHost);
}
if (httpClientConfigurer != null) {
configurer.addConfigurer(httpClientConfigurer);
}
configurer.configureHttpClient(httpClient);
Geocoder geocoder;
if (clientId != null) {
geocoder = new AdvancedGeoCoder(httpClient, clientId, clientKey);
} else {
geocoder = new AdvancedGeoCoder(httpClient);
}
return geocoder;
}
/**
* Configures the proxy authentication method to be used
*
* @return configurer to used
*/
protected CompositeHttpConfigurer configureProxyAuth(CompositeHttpConfigurer configurer,
String authMethod, String username, String password, String domain, String host) {
// no proxy auth is in use
if (username == null && authMethod == null) {
return configurer;
}
// validate mandatory options given
if (username != null && authMethod == null) {
throw new IllegalArgumentException("Option proxyAuthMethod must be provided to use proxy authentication");
}
ObjectHelper.notNull(authMethod, "proxyAuthMethod");
ObjectHelper.notNull(username, "proxyAuthUsername");
ObjectHelper.notNull(password, "proxyAuthPassword");
AuthenticationMethod auth = getCamelContext().getTypeConverter().convertTo(AuthenticationMethod.class, authMethod);
if (auth == AuthenticationMethod.Basic || auth == AuthenticationMethod.Digest) {
configurer.addConfigurer(AuthenticationHttpClientConfigurer.basicAutenticationConfigurer(true, username, password));
return configurer;
} else if (auth == AuthenticationMethod.NTLM) {
// domain is mandatory for NTML
ObjectHelper.notNull(domain, "proxyAuthDomain");
configurer.addConfigurer(AuthenticationHttpClientConfigurer.ntlmAutenticationConfigurer(true, username, password, domain, host));
return configurer;
}
throw new IllegalArgumentException("Unknown proxyAuthMethod " + authMethod);
}
}