package com.google.gwt.ricordo.server;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.owllink.builtin.response.SetOfClasses;
import uk.ac.ebi.miriam.lib.MiriamLink;
import uk.ac.ebi.ontocat.OntologyService;
import uk.ac.ebi.ontocat.OntologyServiceException;
import uk.ac.ebi.ontocat.OntologyTerm;
import uk.ac.ebi.ontocat.OntologyService.SearchOptions;
import uk.ac.ebi.ontocat.ols.OlsOntologyService;
import uk.ac.ebi.ontocat.virtual.CachedServiceDecorator;
import com.google.gwt.ricordo.client.QueryService;
import com.google.gwt.ricordo.client.exception.AnnotVariableException;
import com.google.gwt.ricordo.client.exception.ManchesterQueryException;
import com.google.gwt.ricordo.client.exception.RemoteOntologyServiceException;
import com.google.gwt.ricordo.shared.CompositeDetails;
import com.google.gwt.ricordo.shared.CompositeDetailsLight;
import com.google.gwt.ricordo.shared.ModelDetails;
import com.google.gwt.ricordo.shared.ModelDetailsLight;
import com.google.gwt.ricordo.shared.ModelSearch;
import com.google.gwt.ricordo.shared.OntologyTermData;
import com.google.gwt.ricordo.shared.VariableDetails;
import com.google.gwt.ricordo.shared.VariableDetailsLight;
import com.google.gwt.ricordo.shared.VariableSearch;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
@SuppressWarnings("serial")
public class QueryServiceImpl extends RemoteServiceServlet implements
QueryService {
public static final String[] ONTOLIST = new String[] { "FMA", "PATO", "GO", "CHEBI", "HP" };
private OntologyHandler ontologyHandler;
private OntologyService os = null;
private RDFHandler rdfHandler= new RDFHandler();
private ConfigHandler configHandler;
public QueryServiceImpl() {
configHandler = new ConfigHandler();
ontologyHandler = new OntologyHandler(OntologyHandler.DOCUMENT_IRI, configHandler);
setUpOntologyService();
}
private void setUpOntologyService(){
try {
os = CachedServiceDecorator.getService(new OlsOntologyService());
} catch (OntologyServiceException e) {
e.printStackTrace();
}
}
public ArrayList<VariableDetailsLight> getVariableList(ModelSearch modelSearch) {
/* PREFIX bqbiol: <http://biomodels.net/biology-qualifiers/>
PREFIX rcmd: <http://www.ebi.ac.uk/ricordo/model#>
SELECT DISTINCT ?s { ?s rcmd:modelElementOf <ModelIDClickedOn> . ?s
bqbiol:isVersionOf <urn:miriam:obo.go:GO%3A0005892> }
*/
ArrayList<VariableDetailsLight> variableDetailsLight = new ArrayList<VariableDetailsLight>();
int i = 1;
for(OntologyTermData termData: modelSearch.getTermList()){
ResultSet results = rdfHandler.getVariableQuery(modelSearch.getModelURL(), termData.getMiriamURN());
while (results.hasNext()) {
QuerySolution solution = results.next();
String variableName = "";
String predicate = "";
if (solution.getResource("?s") != null) {
variableName = solution.getResource("?s").getURI();
}
if (solution.getResource("?p") != null) {
predicate = solution.getResource("?p").getLocalName();
}
VariableDetails variableDetails = new VariableDetails(String.valueOf(i++),modelSearch.getModelURL(),variableName, predicate,termData.getMiriamURN());
variableDetailsLight.add(variableDetails.getLightWeightContact());
}
}
return variableDetailsLight;
}
public ArrayList<VariableDetailsLight> getVariableListForAnnotation(VariableSearch variableSearch){
ArrayList<VariableDetailsLight> variableDetailsLight = new ArrayList<VariableDetailsLight>();
ResultSet results = rdfHandler.getVariableQuery(variableSearch.getModelUrl());
int i=0;
while (results.hasNext()) {
QuerySolution solution = results.next();
String variableName = "";
String predicate = "";
if (solution.getResource("?s") != null) {
variableName = solution.getResource("?s").getURI();
}
String id = String.valueOf(i++);
VariableDetails variableDetails = new VariableDetails(id,variableName);
variableDetailsLight.add(variableDetails.getLightWeightVariableName());
}
return variableDetailsLight;
}
private String getMiriam(String ontologyAccession, String termAccession){
MiriamLink link = new MiriamLink();
// Sets the address to access the Web Services
link.setAddress("http://www.ebi.ac.uk/miriamws/main/MiriamWebServices");
return link.getURI(ontologyAccession, termAccession);
}
public ArrayList<String> getManQueryTypes() {
return configHandler.valueList(ConfigHandler.TEMPLATE);
}
public ArrayList<String> getRelations() {
return configHandler.valueList(ConfigHandler.PROPERTY);
}
@Override
public LinkedList<String> getOntoTerms(String ontoTerm) throws RemoteOntologyServiceException {
LinkedList<String> suggestions = new LinkedList<String>();
for(int i=0;i<ONTOLIST.length;i++){
suggestions = addSuggestions(ONTOLIST[i],suggestions, ontoTerm);
}
if(suggestions.size()>20){
return new LinkedList<String>(suggestions.subList(0, 20));
}
else
return suggestions;
}
private LinkedList<String> addSuggestions(String ontoAssersion, LinkedList<String> suggestions, String ontoTerm) throws RemoteOntologyServiceException{
List<OntologyTerm> termList;
try {
termList = os.searchOntology(ontoAssersion, ontoTerm, SearchOptions.INCLUDE_PROPERTIES);
for (OntologyTerm ot : termList) {
String term = ot.getLabel() + " (" + ot.getAccession() + ")";
// System.out.println(term);
if (ot.getLabel().toLowerCase().equals(ontoTerm.toLowerCase())) {
suggestions.addFirst(term);
} else if (ot.getLabel().toLowerCase().startsWith(ontoTerm.toLowerCase()))
suggestions.add(term);
}
} catch (OntologyServiceException e) {
throw new RemoteOntologyServiceException("Error in connecting to OLS",e.getMessage());
}
return suggestions;
}
public ModelSearch setOntoTerms(ModelSearch modelSearch) throws ManchesterQueryException{
OWLClassExpression classExp = ontologyHandler.runManchesterQuery(modelSearch.getManQueryText());
ArrayList<OntologyTermData> termList = ontologyHandler.getOntologyTerms(classExp);
for (OntologyTermData term : termList) {
if(term.getOntologyAccession().equals("RICORDO")){
term.setMiriamURN("urn:miriam:ricordo:RICORDO_"+term.getTermAccession().substring(term.getTermAccession().indexOf(":")+1));
// System.out.println(term.getMiriamURN());
}
else if(term.getOntologyAccession().equals("HP")){
term.setMiriamURN("urn:miriam:hp:HP_"+term.getTermAccession().substring(term.getTermAccession().indexOf(":")+1));
// System.out.println(term.getMiriamURN());
}
else{
term.setMiriamURN(getMiriam(term.getOntologyAccession(), term.getTermAccession()));
}
}
modelSearch.setTermList(termList);
return modelSearch;
}
@Override
public ArrayList<ModelDetailsLight> searchModelData(ModelSearch modelSearch) {
/*
* PREFIX bqbiol: <http://biomodels.net/biology-qualifiers/> PREFIX
* rcmd: <http://www.ebi.ac.uk/ricordo/model#> SELECT DISTINCT ?m
* count(?s) { ?s rcmd:modelElementOf ?m . ?s bqbiol:isVersionOf
* <urn:miriam:obo.go:GO%3A0005892> } GROUP BY ?m
*/
HashMap<String, ModelDetails> modelDetailsList = new HashMap<String, ModelDetails>();
int i = 1;
for (OntologyTermData term : modelSearch.getTermList()) {
ResultSet results = rdfHandler.getModelQuery(term.getMiriamURN());
while (results.hasNext()) {
QuerySolution solution = results.next();
String modelName = "";
int frequency = 0;
if (solution.getResource("?m") != null) {
modelName = solution.getResource("?m").getURI();
}
if (solution.getLiteral("?callret-1") != null) {
frequency = solution.getLiteral("?callret-1").getInt();
}
if(modelName!=""){
ModelDetails modelDetails = modelDetailsList.get(modelName);
if(modelDetails == null){
modelDetails = new ModelDetails(String.valueOf(i++), modelName);
modelDetails.setFrequency(modelDetails.getFrequency()+ frequency);
modelDetailsList.put(modelName, modelDetails);
}
}
}
}
return getContactDetails(modelDetailsList);
}
private ArrayList<ModelDetailsLight> getContactDetails(HashMap<String, ModelDetails> modelDetailsList) {
ArrayList<ModelDetailsLight> modelDetailsLight = new ArrayList<ModelDetailsLight>();
Iterator<String> it = modelDetailsList.keySet().iterator();
while (it.hasNext()) {
ModelDetailsLight modelDetails = modelDetailsList.get(it.next()).getLightWeightContact();
modelDetailsLight.add(modelDetails);
}
return modelDetailsLight;
}
@Override
public ArrayList<CompositeDetailsLight> getCompoistes(ModelSearch modelSearch) throws ManchesterQueryException {
OWLClassExpression classExp = ontologyHandler.runManchesterQuery(modelSearch.getManQueryText());
ArrayList<CompositeDetailsLight> compositeList = new ArrayList<CompositeDetailsLight>();
SetOfClasses eqclasses = ontologyHandler.equivalentClasses(classExp);
int i = 1;
Iterator<OWLClass> eqiIterator = eqclasses.iterator();
while(eqiIterator.hasNext()){
OWLClass eqClass = eqiIterator.next();
compositeList.add(new CompositeDetails(""+(i++), eqClass.toStringID(), "Existing composites").getLightWeightContact());
}
if (eqclasses.isEmpty()){
OWLClass eqClass = ontologyHandler.addNewClass(classExp);
compositeList.add(new CompositeDetails(""+(i++), eqClass.toStringID(), "Newly added").getLightWeightContact());
}
return compositeList;
}
public String getTermToAnnotate(String manQuery)throws ManchesterQueryException {
OWLClassExpression classExp = ontologyHandler.runManchesterQuery(manQuery);
SetOfClasses eqclasses = ontologyHandler.equivalentClasses(classExp);
OWLClass eqClass;
if (eqclasses.isEmpty()){
eqClass = ontologyHandler.addNewClass(classExp);
}else{
eqClass = eqclasses.iterator().next();
}
return eqClass.toStringID().substring(eqClass.toStringID().indexOf("#")+1);
}
public ArrayList<VariableDetailsLight> getVariableAnnotationList(VariableSearch variableSearch){
ArrayList<VariableDetailsLight> variableDetailsLight = new ArrayList<VariableDetailsLight>();
ResultSet results = rdfHandler.getVariableAnnotationQuery(variableSearch.getVariableUrl());
int i=0;
while (results.hasNext()) {
QuerySolution solution = results.next();
String predicate = "";
String annotation = "";
if (solution.getResource("?p") != null) {
predicate = solution.getResource("?p").getLocalName();
}
if (solution.getResource("?o") != null) {
annotation = solution.getResource("?o").getURI();
}
VariableDetails variableDetails = new VariableDetails(String.valueOf(i++),variableSearch.getModelUrl(),variableSearch.getVariableUrl(),predicate,annotation);
variableDetailsLight.add(variableDetails.getLightWeightAnnotation());
}
return variableDetailsLight;
}
public ArrayList<String> getMiriamQualifiers() {
ArrayList<String> suggestions = new ArrayList<String>();
suggestions.add("isVersionOf");
suggestions.add("is");
return suggestions;
}
public void addAnnotation(String variableURL, String property, String annotValue) throws AnnotVariableException{
annotValue = annotValue.replace("_", ":");
String [] annotValArray = annotValue.split(":");
if(annotValArray.length!=2){
throw new AnnotVariableException("Invalid term ID");
}
String miriumURN="";
if(annotValArray[0].equals("RICORDO")){
miriumURN = "urn:miriam:ricordo:RICORDO_"+annotValArray[1];
}
else{
miriumURN= getMiriam(annotValArray[0], annotValue);
if(miriumURN==null){
throw new AnnotVariableException("Invalid MIRIAM URN or no MIRIAM URN returned");
}
}
rdfHandler.insertAnnotString(variableURL, property, miriumURN);
}
}