View Javadoc
1   /*
2    * Copyright (c) 2013, Dienst Landelijk Gebied - Ministerie van Economische Zaken
3    * 
4    * Gepubliceerd onder de BSD 2-clause licentie, 
5    * zie https://github.com/MinELenI/CBSviewer/blob/master/LICENSE.md voor de volledige licentie. 
6    */
7   package nl.mineleni.cbsviewer.servlet.gazetteer.lusclient;
8   
9   import static javax.servlet.http.HttpServletResponse.SC_OK;
10  import static nl.mineleni.cbsviewer.servlet.gazetteer.lusclient.OpenLSClientAddress.APPEND_GEMEENTE;
11  import static nl.mineleni.cbsviewer.servlet.gazetteer.lusclient.OpenLSClientAddress.APPEND_PLAATS;
12  import static nl.mineleni.cbsviewer.servlet.gazetteer.lusclient.OpenLSClientAddress.APPEND_PROVINCIE;
13  
14  import java.io.IOException;
15  import java.io.UnsupportedEncodingException;
16  import java.net.URLEncoder;
17  import java.util.ArrayList;
18  import java.util.List;
19  import java.util.Map;
20  import java.util.Map.Entry;
21  
22  import nl.mineleni.openls.databinding.openls.GeocodeRequest;
23  import nl.mineleni.openls.databinding.openls.GeocodeResponse;
24  import nl.mineleni.openls.databinding.openls.ReverseGeocodeResponse;
25  import nl.mineleni.openls.parser.OpenLSGeocodeResponseParser;
26  import nl.mineleni.openls.parser.OpenLSReverseGeocodeResponseParser;
27  
28  import org.apache.http.HttpHost;
29  import org.apache.http.HttpResponse;
30  import org.apache.http.NameValuePair;
31  import org.apache.http.client.ClientProtocolException;
32  import org.apache.http.client.config.CookieSpecs;
33  import org.apache.http.client.config.RequestConfig;
34  import org.apache.http.client.entity.UrlEncodedFormEntity;
35  import org.apache.http.client.methods.HttpGet;
36  import org.apache.http.client.methods.HttpPost;
37  import org.apache.http.entity.ContentType;
38  import org.apache.http.entity.StringEntity;
39  import org.apache.http.impl.client.CloseableHttpClient;
40  import org.apache.http.impl.client.HttpClients;
41  import org.apache.http.message.BasicNameValuePair;
42  import org.apache.http.util.EntityUtils;
43  import org.slf4j.Logger;
44  import org.slf4j.LoggerFactory;
45  
46  /**
47   * OpenLSClient.
48   * 
49   * @author mprins
50   */
51  public class OpenLSClient {
52  
53  	/** logger. */
54  	private static final Logger LOGGER = LoggerFactory
55  			.getLogger(OpenLSClient.class);
56  
57  	/** de http client voor communicatie met de LUS. */
58  	private final CloseableHttpClient client;
59  
60  	/** De open ls response parser. */
61  	private final OpenLSGeocodeResponseParser openLSResponseParser;
62  
63  	/** http request configuratie. */
64  	private RequestConfig requestConfig;
65  
66  	/** De open ls response parser. */
67  	private final OpenLSReverseGeocodeResponseParser openLSReverseResponseParser;
68  
69  	/**
70  	 * Maakt een nieuwe instance van de LUS client. Stelt de http proxy in mits
71  	 * deze in de omgevingsvariabelen is gedefinieerd middels
72  	 * {@code http.proxyHost} en {@code http.proxyPort}.
73  	 */
74  	public OpenLSClient() {
75  		this.client = HttpClients.createSystem();
76  		this.requestConfig = RequestConfig.custom()
77  				.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
78  
79  		final String pHost = System.getProperty("http.proxyHost");
80  		int pPort = -1;
81  		try {
82  			pPort = Integer.valueOf(System.getProperty("http.proxyPort"));
83  		} catch (final NumberFormatException e) {
84  			LOGGER.debug("Geen proxy poort gedefinieerd.");
85  		}
86  		if ((null != pHost) && (pPort > 0)) {
87  			LOGGER.info("Instellen van proxy config: " + pHost + ":" + pPort);
88  			final HttpHost proxy = new HttpHost(pHost, pPort, "http");
89  			this.requestConfig = RequestConfig.copy(this.requestConfig)
90  					.setProxy(proxy).build();
91  		} else {
92  			LOGGER.info("Er wordt geen proxy ingesteld.");
93  		}
94  		this.openLSResponseParser = new OpenLSGeocodeResponseParser();
95  		this.openLSReverseResponseParser = new OpenLSReverseGeocodeResponseParser();
96  	}
97  
98  	/**
99  	 * Do get open ls request.
100 	 * 
101 	 * @param url
102 	 *            the url
103 	 * @param getParams
104 	 *            the get params
105 	 * @return the geocode response, will be null if something went wrong in the
106 	 *         process of getting an openls response and parsing it
107 	 */
108 	public GeocodeResponse doGetOpenLSRequest(final String url,
109 			final Map<String, String> getParams) {
110 		final String queryString = url.endsWith("?") ? url : url + "?";
111 		final StringBuilder qs = new StringBuilder(queryString);
112 		try {
113 			for (final Entry<String, String> getParam : getParams.entrySet()) {
114 				qs.append(URLEncoder.encode(getParam.getKey(), "UTF-8"))
115 						.append("=")
116 						.append(URLEncoder.encode(
117 								(getParam.getValue())
118 										.replaceAll(APPEND_GEMEENTE, "")
119 										.replaceAll(APPEND_PLAATS, "")
120 										.replaceAll(APPEND_PROVINCIE, ""),
121 								"UTF-8")).append("&");
122 			}
123 		} catch (final UnsupportedEncodingException e) {
124 			LOGGER.error("De gebruikte Java VM ondersteunt geen UTF-8 encoding: "
125 					+ e);
126 		}
127 		LOGGER.debug("GETting OLS query:\n\t" + qs.toString());
128 
129 		try {
130 			final HttpGet httpget = new HttpGet(qs.toString());
131 			httpget.setConfig(this.requestConfig);
132 			final HttpResponse getResp = this.client.execute(httpget);
133 			if (getResp.getStatusLine().getStatusCode() == SC_OK) {
134 				final String responseBody = EntityUtils.toString(
135 						getResp.getEntity(), "UTF-8").trim();
136 				return this.openLSResponseParser
137 						.parseOpenLSResponse(responseBody);
138 			} else {
139 				LOGGER.error("OpenLS server get error response: "
140 						+ getResp.getStatusLine());
141 			}
142 		} catch (final ClientProtocolException e) {
143 			LOGGER.error(
144 					"Versturen get request naar OpenLS server is mislukt: ", e);
145 		} catch (final IOException e) {
146 			LOGGER.error(
147 					"Ontvangen get response van OpenLS server is mislukt: ", e);
148 
149 		}
150 		return null;
151 	}
152 
153 	/**
154 	 * Do post open ls request.
155 	 * 
156 	 * @param url
157 	 *            the url
158 	 * @param request
159 	 *            the request
160 	 * @return the geocode response, will be null if something went wrong in the
161 	 *         process of getting an openls response and parsing it
162 	 */
163 	public GeocodeResponse doPostOpenLSRequest(final String url,
164 			final GeocodeRequest request) {
165 		if (LOGGER.isDebugEnabled()) {
166 			LOGGER.debug("POSTting OLS query:\n\t" + request.toXML());
167 		}
168 		try {
169 			final StringEntity str = new StringEntity(request.toXML(),
170 					ContentType.TEXT_XML);
171 			final HttpPost httppost = new HttpPost(url);
172 			httppost.setEntity(str);
173 			httppost.setConfig(this.requestConfig);
174 			final HttpResponse resp = this.client.execute(httppost);
175 			if (resp.getStatusLine().getStatusCode() == SC_OK) {
176 				final String responseBody = EntityUtils.toString(
177 						resp.getEntity(), "UTF-8").trim();
178 				return this.openLSResponseParser
179 						.parseOpenLSResponse(responseBody);
180 			} else {
181 				LOGGER.error("OpenLS server post error response: "
182 						+ resp.getStatusLine());
183 			}
184 		} catch (final UnsupportedEncodingException e) {
185 			LOGGER.error("De gebruikte Java VM ondersteunt geen UTF-8 encoding: "
186 					+ e);
187 		} catch (final ClientProtocolException e) {
188 			LOGGER.error(
189 					"Versturen post request naar OpenLS server is mislukt: ", e);
190 		} catch (final IOException e) {
191 			LOGGER.error(
192 					"Ontvangen post response van OpenLS server is mislukt: ", e);
193 		}
194 		return null;
195 	}
196 
197 	/**
198 	 * post a freeform open ls request. eg. to openrouteservice.org.
199 	 * 
200 	 * @param url
201 	 *            the url
202 	 * @param getParams
203 	 *            the post params
204 	 * @return the geocode response, will be null if something went wrong in the
205 	 *         process of getting an openls response and parsing it
206 	 */
207 	public GeocodeResponse doPostOpenLSRequest(final String url,
208 			final Map<String, String> getParams) {
209 		final HttpPost httppost = new HttpPost(url);
210 		try {
211 			final List<NameValuePair> nvps = new ArrayList<>();
212 			for (final Entry<String, String> getParam : getParams.entrySet()) {
213 				nvps.add(new BasicNameValuePair(URLEncoder.encode(
214 						getParam.getKey(), "UTF-8"), URLEncoder.encode(
215 						(getParam.getValue()).replaceAll(APPEND_GEMEENTE, "")
216 								.replaceAll(APPEND_PLAATS, "")
217 								.replaceAll(APPEND_PROVINCIE, ""), "UTF-8")));
218 			}
219 			httppost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
220 			httppost.setConfig(this.requestConfig);
221 
222 			final HttpResponse resp = this.client.execute(httppost);
223 			if (resp.getStatusLine().getStatusCode() == SC_OK) {
224 				final String responseBody = EntityUtils.toString(
225 						resp.getEntity(), "UTF-8").trim();
226 				return this.openLSResponseParser
227 						.parseOpenLSResponse(responseBody);
228 			} else {
229 				LOGGER.error("OpenLS server get error response: "
230 						+ resp.getStatusLine());
231 			}
232 		} catch (final UnsupportedEncodingException e) {
233 			LOGGER.error("De gebruikte Java VM ondersteunt geen UTF-8 encoding: "
234 					+ e);
235 		} catch (final ClientProtocolException e) {
236 			LOGGER.error(
237 					"Versturen post request naar OpenLS server is mislukt: ", e);
238 
239 		} catch (final IOException e) {
240 			LOGGER.error(
241 					"Ontvangen get response van OpenLS server is mislukt: ", e);
242 		}
243 		return null;
244 	}
245 
246 	/**
247 	 * post a freeform open ls request. eg. to openrouteservice.org.
248 	 * 
249 	 * @param url
250 	 *            the url
251 	 * @param getParams
252 	 *            the post params
253 	 * @return the geocode response, will be null if something went wrong in the
254 	 *         process of getting an openls response and parsing it
255 	 */
256 	public ReverseGeocodeResponse doPostOpenLSReverseGeocodeRequest(
257 			final String url, final Map<String, String> getParams) {
258 		final HttpPost httppost = new HttpPost(url);
259 		try {
260 			final List<NameValuePair> nvps = new ArrayList<>();
261 			for (final Entry<String, String> getParam : getParams.entrySet()) {
262 				nvps.add(new BasicNameValuePair(URLEncoder.encode(
263 						getParam.getKey(), "UTF-8"), URLEncoder.encode(
264 						getParam.getValue(), "UTF-8")));
265 			}
266 			httppost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
267 
268 			final HttpResponse resp = this.client.execute(httppost);
269 			if (resp.getStatusLine().getStatusCode() == SC_OK) {
270 				final String responseBody = EntityUtils.toString(
271 						resp.getEntity(), "UTF-8").trim();
272 				return this.openLSReverseResponseParser
273 						.parseOpenLSReverseGeocodeResponse(responseBody);
274 			} else {
275 				LOGGER.error("OpenLS server get error response: "
276 						+ resp.getStatusLine());
277 			}
278 
279 		} catch (final UnsupportedEncodingException e) {
280 			LOGGER.error("De gebruikte Java VM ondersteunt geen UTF-8 encoding: "
281 					+ e);
282 		} catch (final ClientProtocolException e) {
283 			LOGGER.error(
284 					"Versturen post request naar OpenLS server is mislukt: ", e);
285 
286 		} catch (final IOException e) {
287 			LOGGER.error(
288 					"Ontvangen get response van OpenLS server is mislukt: ", e);
289 		}
290 		return null;
291 	}
292 }