eu.europeanaconnect.erds.HTTPResolver.java Source code

Java tutorial

Introduction

Here is the source code for eu.europeanaconnect.erds.HTTPResolver.java

Source

/**********************************************************************
 * Class HTTPResolver
 * Copyright (c) 2010, German National Library / Deutsche Nationalbibliothek
 * Adickesallee 1, D-60322 Frankfurt am Main, Federal Republic of Germany 
 *
 * This program is free software.
 * For your convenience it is dual licensed.
 * You can redistribute it and/or modify it under the terms of
 * one of the following licenses:
 * 
 * 1.)
 * The GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 * You should have received a copy of the GNU General Public License
 * along with this program (gpl-3.0.txt); if not please read
 * http://www.gnu.org/licenses/gpl.html
 * 
 * 2.)
 * The European Union Public Licence as published by
 * The European Commission (executive body of the European Union);
 * either version 1.1 of the License, or (at your option) any later version.
 * You should have received a copy of the European Union Public Licence
 * along with this program (eupl_v1.1_en.pdf); if not please read
 * http://www.osor.eu/eupl
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the above licenses for more details.
 * 
 * Jrgen Kett, Kadir Karaca Kocer -- German National Library
 * 
 **********************************************************************/

/* ********************************************************************
 * CHANGELOG:
 * 
 * 2010-05-05 Refactoring + new package structure by Karaca Kocer
 * 2010-04-25 Code formatting, comments and license text by Karaca Kocer
 * Created on 2010-03-17 by Jrgen Kett
 ********************************************************************/

package eu.europeanaconnect.erds;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.Logger;

import eu.europeanaconnect.erds.ResolverException.ResolverExceptionCode;

/**
 * Simple Resolver that queries a remote server via HTTP.
 * It fetches the URL by reading the header of the
 * redirect-response of the remote resolver
 * (DEPRECATED! Please use the Multi-Threaded-Version)
 * 
 * @author Jrgen Kett (Original code)
 * @author Kadir Karaca Kocer (Refactoring, license text, comments & JavaDoc)
 * @author Nuno Freire (Refactoring)
 */

public class HTTPResolver implements DataProvider<ResolverResponse> {
    private final static Logger logger = Logger.getLogger(HTTPResolver.class);
    protected String requestUrlPattern;
    protected String id;
    protected String label;
    protected List<String> supportedNamespaces;
    protected String identifierPattern;
    protected DefaultHttpClient httpClient = null;

    /**
     * Fetches the URL out of the header of the redirect response
     * of the remote resolver using the "Location" attribute
     * 
     * @see DataProvider#getResponse(ResolverRequest)
     * @since 17.03.2010
     */
    @Override
    public ResolverResponse getResponse(ResolverRequest resolverRequest) throws ResolverException {
        this.httpClient = new DefaultHttpClient();
        ResolverResponse resolverResponse = new ResolverResponse();
        HttpResponse httpResponse = null;
        String url = getRequestUrl(resolverRequest);
        logger.debug("URL = " + url);
        HttpGet getMethod = new HttpGet(url);
        this.httpClient.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
        this.httpClient.getParams().setBooleanParameter(ClientPNames.REJECT_RELATIVE_REDIRECT, false);

        try {
            httpResponse = this.httpClient.execute(getMethod);
            logger.debug("Operation GET successfull");
        } catch (ClientProtocolException e) {
            logger.error("A ClientProtocolException occured!\nStacktrace:\n" + e.getMessage());
            e.printStackTrace();
            throw new ResolverException(this.id, ResolverExceptionCode.HTTP_PROTOCOL_ERROR, e);
        } catch (IOException e) {
            logger.error("An IOException occured!\nStacktrace:\n" + e.getMessage());
            e.printStackTrace();
            throw new ResolverException(this.id, ResolverExceptionCode.IO_ERROR, e);
        } catch (RuntimeException e) {
            logger.error("A RuntimeException occured!\nStacktrace:\n" + e.getMessage());
            e.printStackTrace();
            throw new ResolverException(this.id, ResolverExceptionCode.SEVERE_RUNTIME_ERROR, e);
        } catch (Exception e) {
            logger.error("An Exception occured!\nStacktrace:\n" + e.getMessage());
            e.printStackTrace();
            throw new ResolverException(this.id, ResolverExceptionCode.UNKNOWN_ERROR, e);
        }

        StatusLine statusLine = httpResponse.getStatusLine();
        int statusCode = statusLine.getStatusCode();

        logger.debug("HTTP Status-code: " + statusCode);
        if ((statusCode > 299) && (statusCode < 400)) {
            //It is a redirect See: http://www.w3.org/Protocols/rfc2616/rfc2616.html
            logger.debug("Analyzing HTTP Header");
            //logger.debug(getMethod.)
            if (!httpResponse.containsHeader("Location")) {
                logger.error("Header does not contain Location attribute!");
                throw new ResolverException(this.id, ResolverExceptionCode.NO_REDIRECT_ERROR);
            }
            logger.debug("Analyzing redirect location");
            Header location = httpResponse.getFirstHeader("Location");
            if (location == null) {
                logger.error("No redirect header for URL: " + url);
                throw new ResolverException(this.id, ResolverExceptionCode.NO_REDIRECT_ERROR);
            }
            logger.debug("Location: " + location.getValue());
            resolverResponse.setUrl(location.getValue());
        } else {
            //It should be a redirect but it is NOT! Analyse the Response
            handleHttpErrorCodes(statusCode);
        }

        //TODO: find a better way
        this.httpClient.getConnectionManager().closeExpiredConnections();
        this.httpClient.getConnectionManager().closeIdleConnections(5, TimeUnit.SECONDS);
        return resolverResponse;
    }

    /**
     * Handles the HTTP status codes that are different than redirect (3xx)
     * @param statusCode HTTP Status code (See RFC 2616)
     * {@link "http://www.w3.org/Protocols/rfc2616/rfc2616.html"}
     * @throws ResolverException
     */
    public void handleHttpErrorCodes(int statusCode) throws ResolverException {
        //TODO: make this better!
        //See: http://www.w3.org/Protocols/rfc2616/rfc2616.html
        if (statusCode >= 500) {
            throw new ResolverException(this.id, ResolverExceptionCode.REMOTE_RESOLVER_ERROR);
        }
        if (statusCode >= 400) {
            throw new ResolverException(this.id, ResolverExceptionCode.INVALID_IDENTIFIER);
        }
        //It is not a server error (5xx), not a client error (4xx), not a redirect (3xx)
        //what to do?
    }

    /**
     * @return The label.
     */
    public String getLabel() {
        return this.label;
    }

    /**
     * @param label Set the label.
     */
    public void setLabel(String label) {
        this.label = label;
    }

    /**
     * @return Returns the HTTP Client that connects to the server.
     * @see org.apache.http.client.HttpClient
     */
    public HttpClient getHttpClient() {
        return this.httpClient;
    }

    /**
     * @param resolverRequest
     * @return The URL of the request.
     */
    public String getRequestUrl(ResolverRequest resolverRequest) {
        return this.requestUrlPattern.replace("$identifier", resolverRequest.getIdentifier());
    }

    /**
     * @return The pattern of the request.
     */
    public String getRequestUrlPattern() {
        return this.requestUrlPattern;
    }

    /**
     * @param requestUrlPattern
     */
    public void setRequestUrlPattern(String requestUrlPattern) {
        this.requestUrlPattern = requestUrlPattern;
    }

    /**
     * {@inheritDoc} 
     */
    @Override
    public List<String> getSupportedNamespaces() {
        return this.supportedNamespaces;
    }

    /**
     * @param supportedNamespaces
     */
    public void setSupportedNamespaces(List<String> supportedNamespaces) {
        this.supportedNamespaces = supportedNamespaces;
    }

    /**
     * {@inheritDoc} 
     */
    @Override
    public String getIdentifierPattern() {
        return this.identifierPattern;
    }

    /**
     * @param identifierPattern
     */
    public void setIdentifierPattern(String identifierPattern) {
        this.identifierPattern = identifierPattern;
    }

    /**
     * {@inheritDoc} 
     */
    @Override
    public String getId() {
        return this.id;
    }

    /**
     * @param id
     */
    public void setId(String id) {
        this.id = id;
    }

}