Java tutorial
/* * 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); } } }