From 0e17b0edf1c560e1824b93fd935b3d82f91e6b6b Mon Sep 17 00:00:00 2001 From: Dan Shinkai Date: Wed, 18 Sep 2013 12:10:30 -0300 Subject: [PATCH] Adicionado classe JAVA para apresentar dados recuperados pelo Tematres --- .../content/authority/TematresProtocol.java | 256 ++++++++++++++++++ .../authority/TematresSponsorship.java | 52 ++++ 2 files changed, 308 insertions(+) create mode 100644 dspace/modules/additions/src/main/java/org/dspace/content/authority/TematresProtocol.java create mode 100644 dspace/modules/additions/src/main/java/org/dspace/content/authority/TematresSponsorship.java diff --git a/dspace/modules/additions/src/main/java/org/dspace/content/authority/TematresProtocol.java b/dspace/modules/additions/src/main/java/org/dspace/content/authority/TematresProtocol.java new file mode 100644 index 000000000000..14c881f36e72 --- /dev/null +++ b/dspace/modules/additions/src/main/java/org/dspace/content/authority/TematresProtocol.java @@ -0,0 +1,256 @@ +/** + * 170913 - Dan Shinkai + * Classe desenvolvida baseada na classe SHERPARMEOProtocol para carregar dados a partir do Tematres. + */ +package org.dspace.content.authority; + +import java.io.IOException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.XMLReader; +import org.xml.sax.InputSource; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import org.apache.log4j.Logger; + +import org.dspace.core.ConfigurationManager; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.util.EncodingUtil; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.HttpException; + +/** + * # URL do servidor de servicos + * tematres.url = http://[dspace.url]/a/tematres/vocab/services.php + * + * IMPORTANTE: A classe foi desenvolvida especificamente para ler os dados informados pelo Tematres. As informacoes apresentadas pelo Tematres ou qualquer + * outro web service devera, obrigatoriamente, apresentar o numero de ocorrencias retornadas antes da leitura das tags contendo informacoes + * do resultado da busca. No caso do Tematres, essa informacoes esta definida pela tag cant_result, no qual foi alterada para ser apresentada + * no inicio das tags. + * + */ +public abstract class TematresProtocol implements ChoiceAuthority +{ + private static Logger log = Logger.getLogger(TematresProtocol.class); + + // contact URL from configuration + private static String url = null; + + public TematresProtocol() + { + if (url == null) + { + url = ConfigurationManager.getProperty("tematres.url"); + + // sanity check + if (url == null) + { + throw new IllegalStateException("Missing DSpace configuration keys for Tematres Query"); + } + } + } + + // this implements the specific Tematres API args and XML tag naming + public abstract Choices getMatches(String text, int collection, int start, int limit, String locale); + + public Choices getBestMatch(String field, String text, int collection, String locale) + { + return getMatches(field, text, collection, 0, 2, locale); + } + + // XXX FIXME just punt, returning value, never got around to + // implementing a reverse query. + public String getLabel(String field, String key, String locale) + { + return key; + } + + // NOTE - ignore limit and start for now + protected Choices query(String result, String label, String authority, + NameValuePair[] args, int start, int limit) + { + HttpClient hc = new HttpClient(); + String srUrl = url + "?" + EncodingUtil.formUrlEncode(args, "UTF8"); + GetMethod get = new GetMethod(srUrl); + + log.debug("Trying Tematres Query, URL="+srUrl); + + try + { + int status = hc.executeMethod(get); + if (status == 200) + { + SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParser sp = spf.newSAXParser(); + XMLReader xr = sp.getXMLReader(); + TematresHandler handler = new TematresHandler(result, label, authority); + + // XXX FIXME: should turn off validation here explicitly, but + // it seems to be off by default. + xr.setFeature("http://xml.org/sax/features/namespaces", true); + xr.setContentHandler(handler); + xr.setErrorHandler(handler); + xr.parse(new InputSource(get.getResponseBodyAsStream())); + + int confidence; + + if (handler.total == 0) + { + confidence = Choices.CF_NOTFOUND; + } + else if (handler.total == 1) + { + confidence = Choices.CF_UNCERTAIN; + } + else + { + confidence = Choices.CF_AMBIGUOUS; + } + return new Choices(handler.result, start, handler.total, confidence, false); + } + } + catch (HttpException e) + { + log.error("Tematres query failed: ", e); + return null; + } + catch (IOException e) + { + log.error("Tematres query failed: ", e); + return null; + } + catch (ParserConfigurationException e) + { + log.warn("Failed parsing Tematres result: ", e); + return null; + } + catch (SAXException e) + { + log.warn("Failed parsing Tematres result: ", e); + return null; + } + finally + { + get.releaseConnection(); + } + return null; + } + + // SAX handler to grab Tematres (and eventually other details) from result + private static class TematresHandler + extends DefaultHandler + { + private Choice result[] = null; + int rindex = 0; // result index + int total = 0; + + // name of element containing a result, e.g. + private String resultElement = null; + + // name of element containing the label e.g. + private String labelElement = null; + + // name of element containing the authority value e.g. + private String authorityElement = null; + + protected String textValue = null; + + public TematresHandler(String result, String label, String authority) + { + super(); + resultElement = result; + labelElement = label; + authorityElement = authority; + } + + // NOTE: text value MAY be presented in multiple calls, even if + // it all one word, so be ready to splice it together. + // BEWARE: subclass's startElement method should call super() + // to null out 'value'. (Don't you miss the method combination + // options of a real object system like CLOS?) + public void characters(char[] ch, int start, int length) + throws SAXException + { + String newValue = new String(ch, start, length); + + if (newValue.length() > 0) + { + if (textValue == null) + { + textValue = newValue; + } + else + { + textValue += newValue; + } + } + } + + // if this was the FIRST "numhits" element, it's size of results: + public void endElement(String namespaceURI, String localName, + String qName) + throws SAXException + { + if (localName.equals("cant_result")) + { + String stotal = textValue.trim(); + + if (stotal.length() > 0) + { + total = Integer.parseInt(stotal); + result = new Choice[total]; + if (total > 0) + { + result[0] = new Choice(); + log.debug("Got "+total+" records in results."); + } + } + } + else if (localName.equals(resultElement)) + { + // after start of result element, get next hit ready + if (++rindex < result.length) + { + result[rindex] = new Choice(); + } + } + else if (localName.equals(labelElement) && textValue != null) + { + // plug in label value + result[rindex].value = textValue.trim(); + result[rindex].label = result[rindex].value; + } + else if (authorityElement != null && localName.equals(authorityElement) && textValue != null) + { + // plug in authority value + result[rindex].authority = textValue.trim(); + } + } + + // subclass overriding this MUST call it with super() + public void startElement(String namespaceURI, String localName, + String qName, Attributes atts) + throws SAXException + { + textValue = null; + } + + public void error(SAXParseException exception) + throws SAXException + { + throw new SAXException(exception); + } + + public void fatalError(SAXParseException exception) + throws SAXException + { + throw new SAXException(exception); + } + } +} diff --git a/dspace/modules/additions/src/main/java/org/dspace/content/authority/TematresSponsorship.java b/dspace/modules/additions/src/main/java/org/dspace/content/authority/TematresSponsorship.java new file mode 100644 index 000000000000..ea4fdce55d16 --- /dev/null +++ b/dspace/modules/additions/src/main/java/org/dspace/content/authority/TematresSponsorship.java @@ -0,0 +1,52 @@ +/** + * 170913 - Dan Shinkai + * Classe desenvolvida baseada na classe SHERPARMEOJournal para carregar dados a partir do Tematres. + */ +package org.dspace.content.authority; + +import org.apache.commons.httpclient.NameValuePair; + +/** + * As informacoes nos quais serao recuperadas do Tematres deverao ser especificadas nas variaveis RESULT, LABEL e AUTHORITY. + * O RESULT determina a tag contendo todas as informacoes de uma determinada busca. + * O LABEL e a tag no qual estara a informacoes a ser apresentada na pagina. + * O AUTHORITY esta relacionado com o authority propriamente dito. + */ +public class TematresSponsorship extends TematresProtocol +{ + private static final String RESULT = "term"; + private static final String LABEL = "string"; + private static final String AUTHORITY = "term_id"; + + + public TematresSponsorship() + { + super(); + } + + public Choices getMatches(String text, int collection, int start, int limit, String locale) + { + // punt if there is no query text + if (text == null || text.trim().length() == 0) + { + return new Choices(true); + } + + // query args to add to Tematres request URL + NameValuePair args[] = new NameValuePair[2]; + args[0] = new NameValuePair("arg", text); + args[1] = new NameValuePair("task","search"); // OR: starts, exact + + Choices result = query(RESULT, LABEL, AUTHORITY, args, start, limit); + if (result == null) + { + result = new Choices(true); + } + return result; + } + + @Override + public Choices getMatches(String field, String text, int collection, int start, int limit, String locale) { + return getMatches(text, collection, start, limit, locale); + } +}