org.linkeddatafragments.servlet.LinkedDataFragmentServlet Maven / Gradle / Ivy
The newest version!
package org.linkeddatafragments.servlet;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.jena.riot.Lang;
import org.linkeddatafragments.config.ConfigReader;
import org.linkeddatafragments.datasource.DataSourceFactory;
import org.linkeddatafragments.datasource.DataSourceTypesRegistry;
import org.linkeddatafragments.datasource.IDataSource;
import org.linkeddatafragments.datasource.IDataSourceType;
import org.linkeddatafragments.datasource.index.IndexDataSource;
import org.linkeddatafragments.exceptions.DataSourceNotFoundException;
import org.linkeddatafragments.fragments.FragmentRequestParserBase;
import org.linkeddatafragments.fragments.ILinkedDataFragment;
import org.linkeddatafragments.fragments.ILinkedDataFragmentRequest;
import org.linkeddatafragments.util.MIMEParse;
import org.linkeddatafragments.views.ILinkedDataFragmentWriter;
import org.linkeddatafragments.views.LinkedDataFragmentWriterFactory;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map.Entry;
/**
* Servlet that responds with a Linked Data Fragment.
*
* @author Ruben Verborgh
* @author Bart Hanssens
* @author Olaf Hartig
*/
public class LinkedDataFragmentServlet extends HttpServlet {
private final static long serialVersionUID = 1L;
// Parameters
/**
*
*/
public final static String CFGFILE = "configFile";
private ConfigReader config;
private final HashMap dataSources = new HashMap<>();
private final Collection mimeTypes = new ArrayList<>();
private File getConfigFile(ServletConfig config) throws IOException {
String path = config.getServletContext().getRealPath("/");
if (path == null) {
// this can happen when running standalone
path = System.getProperty("user.dir");
}
File cfg = new File(path, "config-example.json");
if (config.getInitParameter(CFGFILE) != null) {
cfg = new File(config.getInitParameter(CFGFILE));
}
if (!cfg.exists()) {
throw new IOException("Configuration file " + cfg + " not found.");
}
if (!cfg.isFile()) {
throw new IOException("Configuration file " + cfg + " is not a file.");
}
return cfg;
}
/**
*
* @param servletConfig
* @throws ServletException
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
try {
// load the configuration
File configFile = getConfigFile(servletConfig);
config = new ConfigReader(new FileReader(configFile));
// register data source types
for ( Entry typeEntry : config.getDataSourceTypes().entrySet() ) {
DataSourceTypesRegistry.register( typeEntry.getKey(),
typeEntry.getValue() );
}
// register data sources
for (Entry dataSource : config.getDataSources().entrySet()) {
dataSources.put(dataSource.getKey(), DataSourceFactory.create(dataSource.getValue()));
}
// register content types
MIMEParse.register("text/html");
MIMEParse.register(Lang.TTL.getHeaderString());
MIMEParse.register(Lang.JSONLD.getHeaderString());
MIMEParse.register(Lang.NTRIPLES.getHeaderString());
MIMEParse.register(Lang.RDFXML.getHeaderString());
} catch (Exception e) {
throw new ServletException(e);
}
}
/**
*
*/
@Override
public void destroy()
{
for ( IDataSource dataSource : dataSources.values() ) {
try {
dataSource.close();
}
catch( Exception e ) {
// ignore
}
}
}
/**
* Get the datasource
*
* @param request
* @return
* @throws IOException
*/
private IDataSource getDataSource(HttpServletRequest request) throws DataSourceNotFoundException {
String contextPath = request.getContextPath();
String requestURI = request.getRequestURI();
String path = contextPath == null
? requestURI
: requestURI.substring(contextPath.length());
if (path.equals("/") || path.isEmpty()) {
final String baseURL = FragmentRequestParserBase.extractBaseURL(request, config);
return new IndexDataSource(baseURL, dataSources);
}
String dataSourceName = path.substring(1);
IDataSource dataSource = dataSources.get(dataSourceName);
if (dataSource == null) {
throw new DataSourceNotFoundException(dataSourceName);
}
return dataSource;
}
/**
*
* @param request
* @param response
* @throws ServletException
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
ILinkedDataFragment fragment = null;
try {
// do conneg
String bestMatch = MIMEParse.bestMatch(request.getHeader("Accept"));
// set additional response headers
response.setHeader("Server", "Linked Data Fragments Server");
response.setContentType(bestMatch);
response.setCharacterEncoding("utf-8");
// create a writer depending on the best matching mimeType
ILinkedDataFragmentWriter writer = LinkedDataFragmentWriterFactory.create(config.getPrefixes(), dataSources, bestMatch);
try {
final IDataSource dataSource = getDataSource( request );
final ILinkedDataFragmentRequest ldfRequest =
dataSource.getRequestParser()
.parseIntoFragmentRequest( request, config );
fragment = dataSource.getRequestProcessor()
.createRequestedFragment( ldfRequest );
writer.writeFragment(response.getOutputStream(), dataSource, fragment, ldfRequest);
} catch (DataSourceNotFoundException ex) {
try {
response.setStatus(404);
writer.writeNotFound(response.getOutputStream(), request);
} catch (Exception ex1) {
throw new ServletException(ex1);
}
} catch (Exception e) {
response.setStatus(500);
writer.writeError(response.getOutputStream(), e);
}
} catch (Exception e) {
throw new ServletException(e);
}
finally {
// close the fragment
if ( fragment != null ) {
try {
fragment.close();
}
catch ( Exception e ) {
// ignore
}
}
}
}
}