001: //=============================================================================
002: //=== Copyright (C) 2001-2007 Food and Agriculture Organization of the
003: //=== United Nations (FAO-UN), United Nations World Food Programme (WFP)
004: //=== and United Nations Environment Programme (UNEP)
005: //===
006: //=== This program is free software; you can redistribute it and/or modify
007: //=== it under the terms of the GNU General Public License as published by
008: //=== the Free Software Foundation; either version 2 of the License, or (at
009: //=== your option) any later version.
010: //===
011: //=== This program is distributed in the hope that it will be useful, but
012: //=== WITHOUT ANY WARRANTY; without even the implied warranty of
013: //=== MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: //=== General Public License for more details.
015: //===
016: //=== You should have received a copy of the GNU General Public License
017: //=== along with this program; if not, write to the Free Software
018: //=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
019: //===
020: //=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
021: //=== Rome - Italy. email: geonetwork@osgeo.org
022: //==============================================================================
023:
024: package org.fao.geonet.csw.common.requests;
025:
026: import java.io.IOException;
027: import java.util.Iterator;
028: import java.util.List;
029: import org.fao.geonet.csw.common.Csw;
030: import org.fao.geonet.csw.common.exceptions.CatalogException;
031: import org.fao.geonet.csw.common.exceptions.NoApplicableCodeEx;
032: import org.fao.geonet.csw.common.util.Xml;
033: import org.jdom.Element;
034: import org.jdom.JDOMException;
035: import org.jdom.Namespace;
036: import org.apache.commons.httpclient.HttpClient;
037: import org.apache.commons.httpclient.HttpState;
038: import org.apache.commons.httpclient.Cookie;
039: import org.apache.commons.httpclient.cookie.CookiePolicy;
040: import org.apache.commons.httpclient.methods.PostMethod;
041: import org.apache.commons.httpclient.HttpMethodBase;
042: import org.apache.commons.httpclient.methods.GetMethod;
043: import org.apache.commons.httpclient.NameValuePair;
044: import java.util.ArrayList;
045: import java.net.URLEncoder;
046: import org.apache.commons.httpclient.methods.StringRequestEntity;
047: import org.jdom.Document;
048: import java.io.UnsupportedEncodingException;
049: import java.io.ByteArrayInputStream;
050: import java.io.InputStream;
051: import org.apache.commons.httpclient.HttpStatus;
052: import org.apache.commons.httpclient.Header;
053: import java.net.URL;
054: import org.apache.commons.httpclient.Credentials;
055: import org.apache.commons.httpclient.UsernamePasswordCredentials;
056: import org.apache.commons.httpclient.auth.AuthScope;
057:
058: //=============================================================================
059:
060: public abstract class CatalogRequest {
061: public enum Method {
062: GET, POST
063: }
064:
065: //---------------------------------------------------------------------------
066: //---
067: //--- Constructor
068: //---
069: //---------------------------------------------------------------------------
070:
071: public CatalogRequest() {
072: this (null);
073: }
074:
075: //---------------------------------------------------------------------------
076:
077: public CatalogRequest(String host) {
078: this (host, 80);
079: }
080:
081: //---------------------------------------------------------------------------
082:
083: public CatalogRequest(String host, int port) {
084: this .host = host;
085: this .port = port;
086:
087: setMethod(Method.POST);
088: state.addCookie(cookie);
089: client.setState(state);
090: client.getParams().setCookiePolicy(
091: CookiePolicy.BROWSER_COMPATIBILITY);
092: }
093:
094: //---------------------------------------------------------------------------
095: //---
096: //--- API methods
097: //---
098: //---------------------------------------------------------------------------
099:
100: public String getHost() {
101: return host;
102: }
103:
104: public int getPort() {
105: return port;
106: }
107:
108: public String getAddress() {
109: return address;
110: }
111:
112: public Method getMethod() {
113: return method;
114: }
115:
116: public String getSentData() {
117: return sentData;
118: }
119:
120: public String getReceivedData() {
121: return receivedData;
122: }
123:
124: //---------------------------------------------------------------------------
125:
126: public void setHost(String host) {
127: this .host = host;
128: }
129:
130: //---------------------------------------------------------------------------
131:
132: public void setPort(int port) {
133: this .port = port;
134: }
135:
136: //---------------------------------------------------------------------------
137:
138: public void setAddress(String address) {
139: this .address = address;
140: }
141:
142: //---------------------------------------------------------------------------
143:
144: public void setUrl(URL url) {
145: this .host = url.getHost();
146: this .port = url.getPort();
147: this .address = url.getPath();
148:
149: if (this .port == -1)
150: this .port = 80;
151: }
152:
153: //---------------------------------------------------------------------------
154:
155: public void setMethod(Method m) {
156: method = m;
157: }
158:
159: //---------------------------------------------------------------------------
160:
161: public void setLoginAddress(String address) {
162: loginAddr = address;
163: }
164:
165: //---------------------------------------------------------------------------
166:
167: public void setUseSOAP(boolean yesno) {
168: useSOAP = yesno;
169: }
170:
171: //---------------------------------------------------------------------------
172:
173: public boolean login(String username, String password)
174: throws IOException, CatalogException, JDOMException,
175: Exception
176:
177: {
178: Element request = new Element("request").addContent(
179: new Element("username").setText(username)).addContent(
180: new Element("password").setText(password));
181:
182: PostMethod post = new PostMethod();
183:
184: postData = Xml.getString(new Document(request));
185:
186: post.setRequestEntity(new StringRequestEntity(postData,
187: "application/xml", "UTF8"));
188: // post.setFollowRedirects(true);
189: post.setPath(loginAddr);
190:
191: Element response = doExecute(post);
192:
193: if (Csw.NAMESPACE_ENV.getURI().equals(
194: response.getNamespace().getURI()))
195: response = soapUnembed(response);
196:
197: return response.getName().equals("ok");
198: }
199:
200: //---------------------------------------------------------------------------
201:
202: public Element execute() throws IOException, CatalogException,
203: JDOMException, Exception {
204: HttpMethodBase httpMethod = setupHttpMethod();
205:
206: Element response = doExecute(httpMethod);
207:
208: if (useSOAP)
209: response = soapUnembed(response);
210:
211: //--- raises an exception if the case
212: CatalogException.unmarshal(response);
213:
214: return response;
215: }
216:
217: //---------------------------------------------------------------------------
218:
219: public void setCredentials(String username, String password) {
220: this .useAuthent = true;
221: this .username = username;
222: this .password = password;
223: }
224:
225: //---------------------------------------------------------------------------
226: //---
227: //--- Abstract methods
228: //---
229: //---------------------------------------------------------------------------
230:
231: protected abstract String getRequestName();
232:
233: protected abstract void setupGetParams();
234:
235: protected abstract Element getPostParams();
236:
237: //---------------------------------------------------------------------------
238: //---
239: //--- Protected methods
240: //---
241: //---------------------------------------------------------------------------
242:
243: //---------------------------------------------------------------------------
244: //--- GET fill methods
245: //---------------------------------------------------------------------------
246:
247: protected void fill(String param, Iterable iter) {
248: fill(param, iter, "");
249: }
250:
251: //---------------------------------------------------------------------------
252:
253: protected void fill(String param, Iterable iter, String prefix) {
254: Iterator i = iter.iterator();
255:
256: if (!i.hasNext())
257: return;
258:
259: StringBuffer sb = new StringBuffer();
260:
261: while (i.hasNext()) {
262: sb.append(prefix + i.next());
263:
264: if (i.hasNext())
265: sb.append(",");
266: }
267:
268: addParam(param, sb.toString());
269: }
270:
271: //---------------------------------------------------------------------------
272: //--- POST fill methods
273: //---------------------------------------------------------------------------
274:
275: protected void fill(Element root, String parentName,
276: String childName, Iterable iter, Namespace ns) {
277: Iterator i = iter.iterator();
278:
279: if (!i.hasNext())
280: return;
281:
282: Element parent = new Element(parentName, ns);
283:
284: while (i.hasNext()) {
285: Element el = new Element(childName, ns);
286: el.setText(i.next().toString());
287:
288: parent.addContent(el);
289: }
290:
291: root.addContent(parent);
292: }
293:
294: //---------------------------------------------------------------------------
295:
296: protected void fill(Element root, String childName, Iterable iter) {
297: Iterator i = iter.iterator();
298:
299: if (!i.hasNext())
300: return;
301:
302: while (i.hasNext()) {
303: Element el = new Element(childName, root.getNamespace());
304: el.setText(i.next().toString());
305:
306: root.addContent(el);
307: }
308: }
309:
310: //---------------------------------------------------------------------------
311: //--- Attribute facilities
312: //---------------------------------------------------------------------------
313:
314: protected void setAttrib(Element el, String name, Object value) {
315: setAttrib(el, name, value, "");
316: }
317:
318: //---------------------------------------------------------------------------
319:
320: protected void setAttrib(Element el, String name, Object value,
321: String prefix) {
322: if (value != null)
323: el.setAttribute(name, prefix + value.toString());
324: }
325:
326: //---------------------------------------------------------------------------
327:
328: protected void setAttrib(Element el, String name, Iterable iter,
329: String prefix) {
330: Iterator i = iter.iterator();
331:
332: if (!i.hasNext())
333: return;
334:
335: StringBuffer sb = new StringBuffer();
336:
337: while (i.hasNext()) {
338: sb.append(prefix + i.next().toString());
339:
340: if (i.hasNext())
341: sb.append(" ");
342: }
343:
344: el.setAttribute(name, sb.toString());
345: }
346:
347: //--------------------------------------------------------------------------
348: //--- Parameters facilities (POST)
349: //---------------------------------------------------------------------------
350:
351: protected void addParam(Element root, String name, Object value) {
352: if (value != null)
353: root.addContent(new Element(name, Csw.NAMESPACE_CSW)
354: .setText(value.toString()));
355: }
356:
357: //---------------------------------------------------------------------------
358: //--- Parameters facilities (GET)
359: //--------------------------------------------------------------------------
360:
361: protected void addParam(String name, Object value) {
362: addParam(name, value, "");
363: }
364:
365: //--------------------------------------------------------------------------
366:
367: protected void addParam(String name, Object value, String prefix) {
368: if (value != null)
369: alGetParams.add(new NameValuePair(name, prefix
370: + value.toString()));
371: }
372:
373: //---------------------------------------------------------------------------
374: //---
375: //--- Private methods
376: //---
377: //---------------------------------------------------------------------------
378:
379: private Element doExecute(HttpMethodBase httpMethod)
380: throws IOException, JDOMException {
381: client.getHostConfiguration().setHost(host, port, "http");
382:
383: byte[] data = null;
384:
385: try {
386: client.executeMethod(httpMethod);
387: data = httpMethod.getResponseBody();
388:
389: return Xml.loadStream(new ByteArrayInputStream(data));
390: } finally {
391: httpMethod.releaseConnection();
392:
393: setupSentData(httpMethod);
394: setupReceivedData(httpMethod, data);
395: }
396: }
397:
398: //---------------------------------------------------------------------------
399:
400: private HttpMethodBase setupHttpMethod()
401: throws UnsupportedEncodingException {
402: HttpMethodBase httpMethod;
403:
404: if (method == Method.GET) {
405: alGetParams = new ArrayList<NameValuePair>();
406: setupGetParams();
407: httpMethod = new GetMethod();
408: httpMethod.setQueryString(alGetParams
409: .toArray(new NameValuePair[1]));
410:
411: if (useSOAP)
412: httpMethod.addRequestHeader("Accept",
413: "application/soap+xml");
414: } else {
415: Element params = getPostParams();
416: PostMethod post = new PostMethod();
417:
418: if (!useSOAP) {
419: postData = Xml.getString(new Document(params));
420: post.setRequestEntity(new StringRequestEntity(postData,
421: "application/xml", "UTF8"));
422: } else {
423: postData = Xml
424: .getString(new Document(soapEmbed(params)));
425: post.setRequestEntity(new StringRequestEntity(postData,
426: "application/soap+xml", "UTF8"));
427: }
428:
429: httpMethod = post;
430: }
431:
432: // httpMethod.setFollowRedirects(true);
433: httpMethod.setPath(address);
434:
435: if (useAuthent) {
436: Credentials cred = new UsernamePasswordCredentials(
437: username, password);
438: AuthScope scope = new AuthScope(AuthScope.ANY_HOST,
439: AuthScope.ANY_PORT, AuthScope.ANY_REALM);
440:
441: client.getState().setCredentials(scope, cred);
442: httpMethod.setDoAuthentication(true);
443: }
444:
445: return httpMethod;
446: }
447:
448: //---------------------------------------------------------------------------
449:
450: private void setupSentData(HttpMethodBase httpMethod) {
451: sentData = httpMethod.getName() + " " + httpMethod.getPath();
452:
453: if (httpMethod.getQueryString() != null)
454: sentData += "?" + httpMethod.getQueryString();
455:
456: sentData += "\r\n";
457:
458: for (Header h : httpMethod.getRequestHeaders())
459: sentData += h;
460:
461: sentData += "\r\n";
462:
463: if (httpMethod instanceof PostMethod)
464: sentData += postData;
465: }
466:
467: //---------------------------------------------------------------------------
468:
469: private void setupReceivedData(HttpMethodBase httpMethod,
470: byte[] response) {
471: receivedData = httpMethod.getStatusText() + "\r\r";
472:
473: for (Header h : httpMethod.getResponseHeaders())
474: receivedData += h;
475:
476: receivedData += "\r\n";
477:
478: try {
479: if (response != null)
480: receivedData += new String(response, "UTF8");
481: } catch (UnsupportedEncodingException e) {
482: }
483: }
484:
485: //---------------------------------------------------------------------------
486:
487: private Element soapEmbed(Element elem) {
488: Element envl = new Element("Envelope", Csw.NAMESPACE_ENV);
489: Element body = new Element("Body", Csw.NAMESPACE_ENV);
490:
491: envl.addContent(body);
492: body.addContent(elem);
493:
494: return envl;
495: }
496:
497: //---------------------------------------------------------------------------
498:
499: private Element soapUnembed(Element envelope) throws Exception {
500: Namespace ns = envelope.getNamespace();
501: Element body = envelope.getChild("Body", ns);
502:
503: if (body == null)
504: throw new Exception("Bad SOAP response");
505:
506: List list = body.getChildren();
507:
508: if (list.size() == 0)
509: throw new Exception("Bas SOAP response");
510:
511: return (Element) list.get(0);
512: }
513:
514: //---------------------------------------------------------------------------
515: //---
516: //--- Variables
517: //---
518: //---------------------------------------------------------------------------
519:
520: private String host;
521: private int port;
522: private String address;
523: private String loginAddr;
524: private Method method;
525: private boolean useSOAP;
526: private boolean useAuthent;
527: private String username;
528: private String password;
529:
530: private HttpClient client = new HttpClient();
531: private HttpState state = new HttpState();
532: private Cookie cookie = new Cookie();
533:
534: private ArrayList<NameValuePair> alGetParams;
535:
536: //--- transient vars
537:
538: private String sentData;
539: private String receivedData;
540: private String postData;
541: }
542:
543: //=============================================================================
|