se.kb.oai.pmh.OaiPmhServer.java Source code

Java tutorial

Introduction

Here is the source code for se.kb.oai.pmh.OaiPmhServer.java

Source

/*
 * Copyright 2008 National Library of Sweden Licensed 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 se.kb.oai.pmh;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import se.kb.oai.OAIException;
import se.kb.xml.EntityToEmptyResolver;

import com.google.common.base.Charsets;

import de.fhg.iais.cortex.harvester.IOaiPmhServer;

/**
 * Class that acts as a facade for an OAI-PMH server. Has methods that corresponds to the different verbs in
 * the OAI-PMH specification and that will return appropriate objects based on the response.
 * <p>
 * For more about the different verbs, requests and responses in the OAI-PMH specification, see <a
 * href="http://www.openarchives.org/OAI/openarchivesprotocol.html"> http://www.openarchives.org/OAI/openarchivesprotocol.html</a>.
 * 
 * @author Oskar Grenholm, National Library of Sweden
 */
public class OaiPmhServer implements IOaiPmhServer {
    private static final Logger LOGGER = LoggerFactory.getLogger(OaiPmhServer.class);

    private final QueryBuilder builder;
    private final SAXReader reader;
    private HttpClient client;

    /**
     * Creates an <code>OaiPmhServer</code> with the given base URL.
     * 
     * @param url base URL that points to an OAI-PMH server
     */
    public OaiPmhServer(String url) {
        this.builder = new QueryBuilder(url);
        this.reader = new SAXReader();

        setupReader();
    }

    private void setupReader() {
        this.reader.setValidation(false);
        this.reader.setIncludeExternalDTDDeclarations(false);
        this.reader.setEntityResolver(EntityToEmptyResolver.INSTANCE);

        try {
            XMLReader xmlReader = this.reader.getXMLReader();
            xmlReader.setEntityResolver(EntityToEmptyResolver.INSTANCE);
        } catch (SAXException e) {
            LOGGER.warn("Can't set entity resolver of XML reader - default entity resolver might be slow!", e);
        }
    }

    public OaiPmhServer(HttpClient client, String url) {
        this(url);
        this.client = client;
    }

    //    /**
    //     * Creates an <code>OaiPmhServer</code> with the given base URL.
    //     *
    //     * @param url base URL that points to an OAI-PMH server
    //     */
    //    public OaiPmhServer(URL url) {
    //        this(url.toString());
    //    }

    //    /**
    //     * Get the base URL to the OAI-PMH server.
    //     * 
    //     * @return the base URL
    //     */
    //    public String getBaseUrl() {
    //        return this.builder.getBaseUrl();
    //    }

    /**
     * Send a GetRecord request to the OAI-PMH server with the specified parameters.
     * 
     * @param identifier id to get a Record for
     * @param metadataPrefix which metadata format
     * @return the response from the server
     * @throws OAIException
     */
    @Override
    public Record getRecord(String identifier, String metadataPrefix) throws OAIException {
        try {
            String query = this.builder.buildGetRecordQuery(identifier, metadataPrefix);
            Document document = executeQuery(query);
            return new Record(document);
        } catch (Exception e) {
            throw new OAIException("", e);
        }
    }

    private Document executeQuery(String query) throws OAIException, IOException {
        LOGGER.info(" --->  Sending query to OAI-PMH-server: ---> \n {}", query);
        if (this.client == null) {
            // if there is no special client initialized use the default one
            try {
                return this.reader.read(query);
            } catch (DocumentException e) {
                LOGGER.error("Problem parsing OAI-PMH result from query {}", query);
                throw new OAIException("", e);
            }
        } else {
            HttpGet httpget = new HttpGet(query);
            HttpResponse response = this.client.execute(httpget);
            String message = "";
            try {
                InputStream en = response.getEntity().getContent();

                if (en != null) {
                    Writer writer = new StringWriter();
                    char[] buffer = new char[1024];
                    try {
                        Reader reader = new BufferedReader(new InputStreamReader(en, Charsets.UTF_8));
                        int n;
                        while ((n = reader.read(buffer)) != -1) {
                            writer.write(buffer, 0, n);
                            message = writer.toString();
                        }
                    } finally {
                        en.close();
                    }
                }

                StringReader sr = new StringReader(message);
                LOGGER.info("<--- Received result from OAI-PMH-server: <---\n {}", message);
                return this.reader.read(sr);
            } catch (DocumentException de) {
                LOGGER.error("Problem parsing OAI-PMH result from query {} with result {}", query, message);
                throw new OAIException("", de);
            }
        }
    }

    //    /**
    //     * Send a request for the OAI-PMH server to Identify it self.
    //     * 
    //     * @return the response from the server
    //     * @throws OAIException
    //     */
    //    public Identification identify() throws OAIException {
    //        try {
    //            String query = this.builder.buildIdentifyQuery();
    //            Document document = executeQuery(query);
    //            return new Identification(document);
    //        } catch ( Exception e ) {
    //            throw new OAIException("", e);
    //        }
    //    }

    //    /**
    //     * Send a request to the OAI-PMH server that it should list all identifiers that has metadata in the
    //     * specified format.
    //     * 
    //     * @param metadataPrefix which metadata format
    //     * @return a list of identifiers
    //     * @throws OAIException
    //     */
    //    public IdentifiersList listIdentifiers(String metadataPrefix) throws OAIException {
    //        return listIdentifiers(metadataPrefix, null, null, null);
    //    }

    /**
     * Send a request to the OAI-PMH server that it should list all identifiers that matches the given
     * parameters.
     * 
     * @param metadataPrefix which metadata format
     * @param from a start date, optional (may be <code>null</code>)
     * @param until a stop date, optional (may be <code>null</code>)
     * @param set a specific set, optional (may be <code>null</code>)
     * @return a list of identifiers
     * @throws OAIException
     */
    @Override
    public IdentifiersList listIdentifiers(String metadataPrefix, String from, String until, String set)
            throws OAIException {
        try {
            String query = this.builder.buildListIdentifiersQuery(metadataPrefix, from, until, set);
            Document document = executeQuery(query);
            return new IdentifiersList(document);
        } catch (ErrorResponseException e) {
            throw e;
        } catch (Exception e) {
            throw new OAIException("", e);
        }
    }

    /**
     * List next set of identifiers not returned in the previous response from a call to listIdentifiers().
     * 
     * @param resumptionToken a resumption token returned from a previous call
     * @return a list of identifiers
     * @throws OAIException
     */
    public IdentifiersList listIdentifiers(ResumptionToken resumptionToken) throws OAIException {
        try {
            String query = this.builder.buildListIdentifiersQuery(resumptionToken);
            Document document = executeQuery(query);
            return new IdentifiersList(document);
        } catch (ErrorResponseException e) {
            throw e;
        } catch (Exception e) {
            throw new OAIException("", e);
        }
    }

    /**
     * Send a request for the OAI-PMH server to return a list of Records.
     * 
     * @param metadataPrefix which metadata format
     * @return a list of records
     * @throws OAIException
     */
    @Override
    public RecordsList listRecords(String metadataPrefix) throws OAIException {
        return listRecords(metadataPrefix, null, null, null);
    }

    /**
     * Send a request for the OAI-PMH server to return a list of Records.
     * 
     * @param metadataPrefix which metadata format
     * @param from a start date, optional (may be <code>null</code>)
     * @param until a stop date, optional (may be <code>null</code>)
     * @param set a specific set, optional (may be <code>null</code>)
     * @return a lsit of records
     * @throws OAIException
     */
    @Override
    public RecordsList listRecords(String metadataPrefix, String from, String until, String set)
            throws OAIException {
        try {
            String query = this.builder.buildListRecordsQuery(metadataPrefix, from, until, set);
            Document document = executeQuery(query);
            return new RecordsList(document);
        } catch (ErrorResponseException e) {
            throw e;
        } catch (Exception e) {
            throw new OAIException("", e);
        }
    }

    /**
     * List next set of records not returned in the previous response from a call to listRecords().
     * 
     * @param resumptionToken a resumption token returned from a previous call
     * @return a list of records
     * @throws OAIException
     */
    @Override
    public RecordsList listRecords(ResumptionToken resumptionToken) throws OAIException {
        try {
            String query = this.builder.buildListRecordsQuery(resumptionToken);
            Document document = executeQuery(query);
            return new RecordsList(document);
        } catch (ErrorResponseException e) {
            throw e;
        } catch (Exception e) {
            throw new OAIException("", e);
        }
    }

    /**
     * Ask the OAI-PMH server to list all metadata formats it holds.
     * 
     * @return a list of available metadata formats
     * @throws OAIException
     */
    public MetadataFormatsList listMetadataFormats() throws OAIException {
        return listMetadataFormats(null);
    }

    /**
     * Ask the OAI-PMH server to list all metadata formats it holds for the specified identifier.
     * 
     * @return a list of available metadata formats
     * @throws OAIException
     */
    @Override
    public MetadataFormatsList listMetadataFormats(String identifier) throws OAIException {
        try {
            String query = this.builder.buildListMetadataFormatsQuery(identifier);
            Document document = executeQuery(query);
            if (document == null) {
                return null;
            }
            return new MetadataFormatsList(document);
        } catch (ErrorResponseException e) {
            throw e;
        } catch (Exception e) {
            throw new OAIException("", e);
        }
    }

    /**
     * List all sets the OAI-PMH server has.
     * 
     * @return a list of sets
     * @throws OAIException
     */
    public SetsList listSets() throws OAIException {
        try {
            String query = this.builder.buildListSetsQuery();
            Document document = executeQuery(query);
            if (document == null) {
                return null;
            }
            return new SetsList(document);
        } catch (Exception e) {
            throw new OAIException("", e);
        }
    }

    /**
     * List next set of sets not returned in the previous response from a call to listSets().
     * 
     * @param resumptionToken
     * @return a list of sets
     * @throws OAIException
     */
    public SetsList listSets(ResumptionToken resumptionToken) throws OAIException {
        try {
            String query = this.builder.buildListSetsQuery(resumptionToken);
            Document document = executeQuery(query);
            return new SetsList(document);
        } catch (Exception e) {
            throw new OAIException("", e);
        }
    }

}