package com.nicusa.service;
import com.nicusa.domain.AdverseEffectDescription;
import com.nicusa.util.HttpSlurper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.xml.parsers.DocumentBuilder;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Collection;
@Service(AdverseEffectService.NAME)
@Transactional
public class AdverseEffectService
{
Logger log = LoggerFactory.getLogger(AdverseEffectService.class);
public static final String NAME = "adverseEffectService";
@PersistenceContext
EntityManager entityManager;
@Autowired
DocumentBuilder documentBuilder;
@Autowired
HttpSlurper slurper;
@Autowired
@Value("${merriam.webster.key:}")
String merriamWebsterKey;
@Autowired
@Value("${meriam.webster.medical.url:http://www.dictionaryapi.com/api/v1/references/medical/xml/}")
String meriamWebsterUrl;
public String findEffectDescription(String effectName) throws IOException {
String retval = null;
AdverseEffectDescription desc = findEventDescriptionInCache(effectName);
if(desc == null)
{
desc = retrieveDescriptionFromDictionary(effectName);
}
return desc.getDescription();
}
@Transactional
private AdverseEffectDescription retrieveDescriptionFromDictionary(String effectName) throws IOException
{
AdverseEffectDescription desc = new AdverseEffectDescription();
desc.setFdaName(effectName);
desc.setDescription(effectName.toLowerCase());
try {
if(merriamWebsterKey != null && merriamWebsterKey.length() > 0)
{
String eval = URLEncoder.encode(effectName, "UTF-8");
String s = slurper.getData(meriamWebsterUrl+eval+"?key="+merriamWebsterKey);
String definition = null;
definition = parseDefinition(s);
if(definition != null)
{
desc.setDescription(definition.substring(0, definition.length() > 512 ? 512 : definition.length()));
}
entityManager.persist(desc);
}
} catch (IOException | SAXException ioe)
{
log.warn("Unable to parse definition for "+effectName);
}
return desc;
}
private AdverseEffectDescription findEventDescriptionInCache(String fdaEventName) {
AdverseEffectDescription retval = null;
Query q = entityManager.createQuery("SELECT a FROM AdverseEffectDescription a WHERE a.fdaName = :fdaName");
Collection<AdverseEffectDescription> aeDescriptions = q.setParameter("fdaName", fdaEventName).getResultList();
if(aeDescriptions.size() > 0)
{
retval = (AdverseEffectDescription)aeDescriptions.toArray()[0];
}
return retval;
}
private String parseDefinition(String xml) throws IOException, SAXException
{
String retval = null;
InputStream is = new ByteArrayInputStream(xml.getBytes());
Document dom = documentBuilder.parse(is);
Element root = dom.getDocumentElement();
NodeList dts = root.getElementsByTagName("dt");
if(dts != null && dts.getLength() > 0)
{
Element dt = (Element)dts.item(0);
retval = dt.getTextContent();
}
return retval;
}
}