package org.deri.grefine.reconcile.commands; import java.io.IOException; import java.io.PrintWriter; import java.util.HashSet; import java.util.Set; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.http.HttpEntity; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import org.deri.grefine.rdf.utils.HttpUtils; import org.deri.grefine.reconcile.model.ReconciliationStanbolSite; import org.json.JSONArray; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.refine.commands.Command; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; /** * Command for adding Stanbol Reconciliation services * * @author Sergio Fernández <sergio.fernandez@salzburgresearch.at> * */ public class AddStanbolServiceCommand extends Command { private static Logger log = LoggerFactory.getLogger(AddStanbolServiceCommand.class); private static String ENTITYHUB_PATH = "/entityhub/sites/referenced"; private static String RECONCILE_SUFFIX = "reconcile"; private static final String JSON = "application/json"; private static final String RDFXML = "application/rdf+xml"; /** * Processes the pre-registration of an instance of Apache Stanbol, * returning the list of suitable reconciliation services available * */ @Override public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String uri = req.getParameter("uri") + ENTITYHUB_PATH; log.debug("Requesting referenced site to Stanbol EntityHub '" + uri + "'..."); Set<ReconciliationStanbolSite> reconciliations = retrieveReconciliations(uri); this.serializeReconciliations(res, reconciliations); } private Set<ReconciliationStanbolSite> retrieveReconciliations(String uri) throws IOException, JsonParseException, JsonMappingException { HttpEntity entity = HttpUtils.get(uri, JSON); ObjectMapper mapper = new ObjectMapper(); Set<String> sites = mapper.readValue(entity.getContent(), new TypeReference<Set<String>>(){}); Set<ReconciliationStanbolSite> reconciliations = new HashSet<ReconciliationStanbolSite>(); for (String site : sites) { ReconciliationStanbolSite reconciliation = this.buildReconciliation(site); if (reconciliation != null) { reconciliations.add(reconciliation); } else { log.error("'" + site + "' can't be correctly retrieved, so not going to be registered"); } } log.info("Retrieved " + reconciliations.size() + " suitable sites"); return reconciliations; } private ReconciliationStanbolSite buildReconciliation(String site) throws IOException { HttpEntity entity = HttpUtils.get(site, RDFXML); Model model = ModelFactory.createDefaultModel(); model.read(entity.getContent(), site); String query = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> " + "PREFIX entityhub: <http://stanbol.apache.org/ontology/entityhub/entityhub#> " + "SELECT ?name ?local " + "WHERE { " + " <" + site + "> rdfs:label ?name ; " + " entityhub:localMode ?local . " + "} "; QueryExecution qe = QueryExecutionFactory.create(query, model); ResultSet results = qe.execSelect(); if (results.hasNext()) { QuerySolution qs = results.nextSolution(); ReconciliationStanbolSite reconciliation = new ReconciliationStanbolSite(); reconciliation.setUri(site + RECONCILE_SUFFIX); reconciliation.setName(qs.getLiteral("name").getString()); reconciliation.setLocal("true".equalsIgnoreCase(qs.getLiteral("local").getString())); return reconciliation; } else { return null; } } private void serializeReconciliations(HttpServletResponse res, Set<ReconciliationStanbolSite> reconciliations) throws IOException { JSONArray json = new JSONArray(); for (ReconciliationStanbolSite reconciliation : reconciliations) { json.put(reconciliation.getJSON()); } res.setStatus(HttpServletResponse.SC_OK); res.setContentType(JSON); PrintWriter writer = res.getWriter(); writer.println(json); } }