/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.clerezza.platform.concepts.core;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.Date;
import org.apache.clerezza.rdf.core.Graph;
import org.apache.clerezza.rdf.core.MGraph;
import org.apache.clerezza.rdf.core.UriRef;
import org.apache.clerezza.rdf.core.serializedform.Parser;
import org.apache.clerezza.rdf.core.serializedform.SupportedFormat;
/**
* This implementation of {@link ConceptProvider} provides a functionality
* to query a SPARQL End Point for a given search term. The query is to be
* generated from a template by replacing the place holder for the search term
* with the specified search term.
*
* @author tio, hasan
*/
public class RemoteConceptProvider implements ConceptProvider {
private UriRef sparqlEndPoint = null;
private UriRef defaultGraph = null;
private String queryTemplate = null;
private ConceptCache conceptCache = null;
private RemoteConceptsDescriptionManager remoteConceptsDescriptionManager = null;
/**
* Constructs a {@link RemoteConceptProvider} with the specified parameters.
*
* @param sparqlEndPoint
* the SPARQL End Point to connect to
* @param defaultGraph
* the Graph to query for concepts
* @param queryTemplate
* the template for query containing place holders for the search term.
*/
public RemoteConceptProvider(
UriRef sparqlEndPoint, UriRef defaultGraph, String queryTemplate) {
this.sparqlEndPoint = sparqlEndPoint;
this.defaultGraph = defaultGraph;
this.queryTemplate = queryTemplate;
this.conceptCache = new ConceptCache(sparqlEndPoint, defaultGraph);
this.remoteConceptsDescriptionManager = new RemoteConceptsDescriptionManager();
}
@Override
public Graph retrieveConcepts(String searchTerm) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -30);
Date acceptableOldestCachingDate = calendar.getTime();
MGraph cachedConcepts = conceptCache.retrieve(searchTerm.toLowerCase(),
acceptableOldestCachingDate);
if (cachedConcepts != null) {
return cachedConcepts.getGraph();
} else {
final int connectionTimeout = 4000;
String query = queryTemplate.replace("${searchTerm}", searchTerm);
try {
String param = "query=" + URLEncoder.encode(query, "UTF-8");
if (defaultGraph != null) {
param += "&default-graph-uri=" + defaultGraph.getUnicodeString();
}
final URL url = new URL(sparqlEndPoint.getUnicodeString());
final HttpURLConnection con =
(HttpURLConnection) url.openConnection();
con.setRequestProperty("Accept", "application/rdf+xml");
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setDoInput(true);
con.setUseCaches(false);
con.setConnectTimeout(connectionTimeout);
final OutputStream os = con.getOutputStream();
os.write(param.getBytes());
os.close();
if (con.getResponseCode() < 400) {
final InputStream is = con.getInputStream();
Graph parsedGraph = Parser.getInstance().parse(is,
SupportedFormat.RDF_XML);
is.close();
conceptCache.cache(searchTerm.toLowerCase(), parsedGraph);
remoteConceptsDescriptionManager.storeConceptsDescription(parsedGraph);
return parsedGraph;
} else {
final InputStream es = con.getErrorStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (int ch = es.read(); ch != -1; ch = es.read()) {
baos.write(ch);
}
es.close();
throw new RuntimeException(baos.toString());
}
} catch (ProtocolException ex) {
throw new RuntimeException(ex);
} catch (MalformedURLException ex) {
throw new RuntimeException(ex);
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
}