Java tutorial
/** * Copyright (C) 2008 MediaShelf <http://www.yourmediashelf.com/> * * This file is part of funapi. * * funapi is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * funapi 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 * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with funapi. If not, see <http://www.gnu.org/licenses/>. */ package org.fedoracommons.funapi.pmh; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.URL; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.apache.http.HttpVersion; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.params.ConnManagerPNames; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.fedoracommons.funapi.FormatException; import org.fedoracommons.funapi.IdentifierException; import org.fedoracommons.funapi.ObjectResolver; import org.fedoracommons.funapi.UnapiException; import org.fedoracommons.funapi.UnapiFormat; import org.fedoracommons.funapi.UnapiFormats; import org.fedoracommons.funapi.UnapiObject; import org.fedoracommons.funapi.utilities.NamespaceContextImpl; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; /** * * @author Edwin Shin * @since 0.1 */ public abstract class AbstractPmhResolver implements ObjectResolver { private final static String FORMATS = "%s?verb=ListMetadataFormats"; private final static String RECORD = "%s?verb=GetRecord&metadataPrefix=%s&identifier=%s"; private NamespaceContextImpl nsCtx; private HttpClient httpClient; private HttpGet httpGet; /** * {@inheritDoc} */ public UnapiFormats getFormats() throws UnapiException { String mdFormats = listMetadataFormats(); UnapiFormats formats = new UnapiFormats(null); XPath xpath = getXPath(); NodeList nodelist = null; try { nodelist = (NodeList) xpath.evaluate("//oai:metadataFormat", new InputSource(new StringReader(mdFormats)), XPathConstants.NODESET); for (int i = 0; i < nodelist.getLength(); i++) { Node node = nodelist.item(i); String format = xpath.evaluate("oai:metadataPrefix", node); String docs = xpath.evaluate("oai:schema", node); UnapiFormat uFormat = new UnapiFormat(format, "application/xml", docs); formats.addFormat(uFormat); } } catch (XPathExpressionException e) { throw new UnapiException(e.getMessage(), e); } return formats; } /** * {@inheritDoc} */ public UnapiFormats getFormats(String id) throws UnapiException { UnapiFormats formats = getFormats(); formats.setId(id); return formats; } /** * {@inheritDoc} */ public UnapiObject getObject(String id, String format) throws UnapiException { try { String record = getRecord(id, format); XPath xpath = getXPath(); Node pmh = (Node) xpath.evaluate("//oai:OAI-PMH", new InputSource(new StringReader(record)), XPathConstants.NODE); Node metadata = (Node) xpath.evaluate("//oai:metadata/*", pmh, XPathConstants.NODE); if (metadata == null) { String error = xpath.evaluate("//oai:error/@code", pmh); if (error.equalsIgnoreCase("idDoesNotExist")) { throw new IdentifierException(error); } else if (error.equalsIgnoreCase("cannotDisseminateFormat")) { throw new FormatException(error); } else { throw new UnapiException(error); } } TransformerFactory xformFactory = TransformerFactory.newInstance(); Transformer transformer = xformFactory.newTransformer(); Source source = new DOMSource(metadata); StringWriter sw = new StringWriter(); transformer.transform(source, new StreamResult(sw)); InputStream in = new ByteArrayInputStream(sw.toString().getBytes("UTF-8")); return new UnapiObject(in, "application/xml"); } catch (XPathExpressionException e) { throw new UnapiException(e.getMessage(), e); } catch (TransformerException e) { throw new UnapiException(e.getMessage(), e); } catch (UnsupportedEncodingException e) { throw new UnapiException(e.getMessage(), e); } } private XPath getXPath() { XPathFactory xpFactory = XPathFactory.newInstance(); XPath xpath = xpFactory.newXPath(); if (nsCtx == null) { nsCtx = new NamespaceContextImpl(); nsCtx.addNamespace("oai", "http://www.openarchives.org/OAI/2.0/"); nsCtx.addNamespace("oai_dc", "http://www.openarchives.org/OAI/2.0/oai_dc/"); nsCtx.addNamespace("dc", "http://purl.org/dc/elements/1.1/"); } xpath.setNamespaceContext(nsCtx); return xpath; } protected HttpClient getHttpClient() { if (httpClient != null) { return httpClient; } SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); HttpParams params = new BasicHttpParams(); // Increase max total connection to 200 params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 200); params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, 20); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry); DefaultHttpClient httpClient = new DefaultHttpClient(cm, params); if (getUsername() != null && getPassword() != null) { httpClient.getCredentialsProvider().setCredentials( new AuthScope(getPmhBaseUrl().getHost(), getPmhBaseUrl().getPort()), new UsernamePasswordCredentials(getUsername(), getPassword())); } this.httpClient = httpClient; return httpClient; } private String listMetadataFormats() throws UnapiException { String url = String.format(FORMATS, getPmhBaseUrl()); return getResponse(url); } private String getRecord(String id, String format) throws UnapiException { String url = String.format(RECORD, getPmhBaseUrl(), format, getPmhId(id)); return getResponse(url); } private String getResponse(String url) throws UnapiException { HttpGet getMethod; if (httpGet == null) { getMethod = new HttpGet(url); } else { getMethod = httpGet; } try { return getHttpClient().execute(getMethod, new BasicResponseHandler()); } catch (IOException e) { throw new UnapiException(e.getMessage(), e); } } /** * @param id an unAPI identifier * @return the corresponding OAI-PMH identifier */ protected abstract String getPmhId(String id); /** * * @return The base URL of the OAI-PMH service, e.g. http://localhost:8080/oai/request. */ protected abstract URL getPmhBaseUrl(); /** * @return The username, if any, required to access the OAI-PMH service. */ protected abstract String getUsername(); /** * @return The password, if any, required to access the OAI-PMH service. */ protected abstract String getPassword(); }