org.lareferencia.provider.controller.ProviderController.java Source code

Java tutorial

Introduction

Here is the source code for org.lareferencia.provider.controller.ProviderController.java

Source

/*******************************************************************************
 * Copyright (c) 2013 lmatas.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Lautaro Matas (lmatas@gmail.com) - Desarrollo e implementacin
 *     Emiliano Marmonti(emarmonti@gmail.com) - Coordinacin del componente III
 * 
 * Este software fue desarrollado en el marco de la consultora "Desarrollo e implementacin de las soluciones - Prueba piloto del Componente III -Desarrollador para las herramientas de back-end" del proyecto Estrategia Regional y Marco de Interoperabilidad y Gestin para una Red Federada Latinoamericana de Repositorios Institucionales de Documentacin Cientfica? financiado por Banco Interamericano de Desarrollo (BID) y ejecutado por la Cooperacin Latino Americana de Redes Avanzadas, CLARA.
 ******************************************************************************/
package org.lareferencia.provider.controller;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.lareferencia.backend.stats.ProviderStatsManager;
import org.lareferencia.provider.domain.MetadataFormat;
import org.lareferencia.provider.domain.Record;
import org.lareferencia.provider.exceptions.BadArgumentException;
import org.lareferencia.provider.exceptions.CannotDisseminateFormatException;
import org.lareferencia.provider.exceptions.NoMetadataFormatsException;
import org.lareferencia.provider.exceptions.ProtocolException;
import org.lareferencia.provider.exceptions.ServerException;
import org.lareferencia.provider.providers.IProvider;
import org.lareferencia.provider.providers.StateHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

public class ProviderController extends MultiActionController implements MessageSourceAware {
    //private final Log log = LogFactory.getLog(getClass());

    @Autowired
    private ProviderStatsManager statsManager;

    @Autowired
    @Qualifier("adminEmail")
    private String adminEmail;

    private MessageSource messages = null;
    private IProvider provider = null;
    private Map<String, MetadataFormat> metadataFormatMap = new HashMap<String, MetadataFormat>();

    private static SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    public ProviderController() {
        super();
    }

    /* Accessors/Mutators
     **************************************************************************/

    public void setMessageSource(final MessageSource messages) {
        this.messages = messages;
    }

    public MessageSource getMessageSource() {
        return this.messages;
    }

    public void setProvider(final IProvider provider) {
        this.provider = provider;
    }

    public IProvider getProvider() {
        return this.provider;
    }

    public List<MetadataFormat> getMetadataFormats() throws NoMetadataFormatsException, ProtocolException {
        final List<MetadataFormat> formats = new ArrayList<MetadataFormat>();
        formats.addAll(this.metadataFormatMap.values());
        return formats;
    }

    public void setMetadataFormats(final List<MetadataFormat> formats) {
        if (formats == null)
            throw new IllegalArgumentException(
                    "'setMetadataFormats()' expects a non-null Collection of MetadataFormat instances.");

        this.metadataFormatMap.clear();

        for (MetadataFormat format : formats)
            this.metadataFormatMap.put(format.getMetadataPrefix(), format);
    }

    /* MultiActionController Methods
     **************************************************************************/

    @Override
    protected void initBinder(final HttpServletRequest request, final ServletRequestDataBinder binder) {
        binder.registerCustomEditor(String.class, null, new StringTrimmerEditor(true));
    }

    public ModelAndView defaultHandler(final HttpServletRequest request, final HttpServletResponse response,
            final Arguments arguments) {
        final Map<String, Object> model = new HashMap<String, Object>();

        // Debugging.
        response.setContentType("text/xml; charset=UTF-8");

        // registro de la ip para estadsticas
        statsManager.countIPAccess(request.getRemoteAddr());

        // The OAI protocol includes the original HTTP request.
        final String requestURL = request.getRequestURL().toString();
        model.put("RequestURL", requestURL);

        // responseDate
        String dateString = dateFormater.format(new DateTime().toDate());
        System.out.println(dateString);
        model.put("ResponseDate", dateString);

        // adminEmail
        model.put("AdminEmail", adminEmail);

        try {
            if (this.getProvider() == null)
                throw new ServerException(
                        "There was a configuration problem. ProviderController expects a non-null 'provider'.");

            // The 'verb' parameter must be set.
            if (arguments.getVerb() == null)
                throw new BadArgumentException("A 'verb' argument is required.");

            // Restrict arguments just to the ones defined by the spec.
            final String[] allowedArguments = { "from", "identifier", "metadataPrefix", "resumptionToken", "set",
                    "until", "verb" };

            final Set<String> allowedArgumentSet = new HashSet<String>();
            for (String argument : allowedArguments)
                allowedArgumentSet.add(argument);

            Set<String> requestParameters = (Set<String>) request.getParameterMap().keySet();
            for (String parameter : requestParameters) {
                if (!allowedArgumentSet.contains(parameter))
                    throw new BadArgumentException("Unknown argument '" + parameter + "'.");
            }

            IProvider provider = this.getProvider();
            final String verb = arguments.getVerb();

            if (verb.equals("GetRecord")) {
                // Check required arguments.
                if (arguments.getIdentifier() == null)
                    throw new BadArgumentException("An 'identifier' argument is required for this verb.");
                if (arguments.getMetadataPrefix() == null)
                    throw new BadArgumentException("A 'metadataPrefix' argument is required for this verb.");

                // Check unsupported arguments.
                if (arguments.getFrom() != null || arguments.getUntil() != null
                        || arguments.getResumptionToken() != null || arguments.getSet() != null)
                    throw new BadArgumentException(
                            "Only the 'identifier' and 'metadataPrefix' arguments are valid for this verb.");

                // Retrieve the requested Record.
                final MetadataFormat format = this.metadataFormatMap.get(arguments.getMetadataPrefix());
                if (format == null)
                    throw new CannotDisseminateFormatException();

                model.put("GetRecord", provider.getRecord(arguments.getIdentifier(), format));
            } else if (verb.equals("ListRecords") || verb.equals("ListIdentifiers")) {

                //log.info("ListRecords/ListIdentifiers Request / RT: " + arguments.getResumptionToken());
                System.out.println("ListRecords/ListIdentifiers Request / RT: " + arguments.getResumptionToken());

                // Check unsupported arguments.
                if (arguments.getIdentifier() != null)
                    throw new BadArgumentException("The 'identifier' argument is not valid for this verb.");

                StateHolder state = null;

                if (StringUtils.isNotEmpty(arguments.getResumptionToken())) {
                    if (arguments.getFrom() != null || arguments.getUntil() != null
                            || arguments.getIdentifier() != null || arguments.getSet() != null
                            || arguments.getMetadataPrefix() != null)
                        throw new BadArgumentException(
                                "A 'resumptionToken' argument cannot be used in conjunction with any others.");

                    state = new StateHolder(arguments.getResumptionToken()); // el estado se obtiene del RT
                } else {
                    // Check required arguments.
                    if (StringUtils.isEmpty(arguments.getMetadataPrefix()))
                        throw new BadArgumentException("A 'metadataPrefix' argument is required for this verb.");

                    state = new StateHolder(); // si no hay rt  es un estado inicial
                }

                // list records actualiza el state, que queda conteniendo la informacin para generar RT
                List<Record> records = provider.listRecords(arguments.getSet(), state,
                        !verb.equals("ListIdentifiers"));

                model.put("ResumptionToken", state.getResumptionToken());
                model.put("ListRecords", records);
            } else if (verb.equals("ListSets")) {
                // Check unsupported arguments.
                if (arguments.getFrom() != null || arguments.getUntil() != null || arguments.getSet() != null
                        || arguments.getIdentifier() != null || arguments.getMetadataPrefix() != null)
                    throw new BadArgumentException(
                            "No arguments are allowed for this verb other than an optional 'resumptionToken'.");

                // TODO: This model dispenses with the ability to use resumption tokens
                // to iterate over sets, which may not be a bad thing.
                model.put("ListSets", provider.listSets());
            } else if (verb.equals("Identify")) {
                if (requestParameters.size() > 1)
                    throw new BadArgumentException("No additional arguments are allowed for this verb.");

                model.put("Origins", provider.listOrigins());
            } else if (verb.equals("ListMetadataFormats")) {
                // Check required arguments.
                if (arguments.getFrom() != null || arguments.getUntil() != null
                        || arguments.getResumptionToken() != null || arguments.getSet() != null
                        || arguments.getMetadataPrefix() != null)
                    throw new BadArgumentException(
                            "Only the 'identifier' argument (or no argument) is valid for this verb.");

                // Get the list of allowed metadata formats.
                List<MetadataFormat> formats = null;
                /*
                if(arguments.getIdentifier() != null)
                {
                   formats = new ArrayList<MetadataFormat>();
                    
                   // Collect matching prefixes and populate a List with matching
                   // MetadataFormat instances.
                   final String[] prefixes = provider.getMetadataPrefixes(arguments.getIdentifier());
                   for(String prefix : prefixes)
                   {
                      final MetadataFormat format = metadataFormatMap.get(prefix);
                      if(format != null)
                 formats.add(format);
                   }
                }
                else*/
                formats = this.getMetadataFormats();

                if (formats != null && formats.size() == 0)
                    throw new NoMetadataFormatsException();

                model.put("ListMetadataFormats", formats);
            } else {
                throw new BadArgumentException(
                        "The 'verb' argument must be one of (GetRecord|Identify|ListIdentifiers|ListMetadataFormats|ListRecords|ListSets).");
            }

            return new ModelAndView("oai/" + verb, model);
        } catch (ProtocolException e) {

            //log.warn("Protocol error", e);

            model.put("ErrorCode", e.getCode());
            model.put("ErrorMessage", e.getMessage());
            return new ModelAndView("oai/Error", model);

        } catch (ServerException e) {
            try {
                //log.warn("OAI Service Error: " + e.getMessage(), e);
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                        "OAI Service Error: " + e.getMessage());
            } catch (IOException ioe) {
                //log.warn("Could not send error to client", ioe);
            }
        } catch (Throwable th) {
            try {
                //log.warn("Unexpected Error", th);
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unexpected error");
            } catch (IOException ioe) {
                //log.warn("Could not send error to client", ioe);
            }
        }

        return new ModelAndView("oai/Error", model);
    }
}