package edu.isi.karma.webserver; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.eclipse.jetty.http.HttpMethods; import edu.isi.karma.linkedapi.server.GetRequestManager; import edu.isi.karma.linkedapi.server.PostRequestManager; import edu.isi.karma.linkedapi.server.ResourceType; import edu.isi.karma.model.serialization.MimeType; import edu.isi.karma.model.serialization.SerializationLang; public class LinkedApiServiceHandler extends HttpServlet { private static final long serialVersionUID = 1L; private static Logger logger = Logger.getLogger(LinkedApiServiceHandler.class); private static String DEFAULT_FORMAT = SerializationLang.N3; private class RestRequest { private String guidRegex = "([A-Za-z0-9]{8}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{12})"; private String serviceIdRegex = guidRegex + "#?"; private String formatRegex = "\\?format=(RDF/XML|RDF/XML-ABBREV|N-TRIPLE|N3|TTL|TURTLE)"; private String ioFormatRegex = "\\?format=(RDF/XML|RDF/XML-ABBREV|N-TRIPLE|N3|TTL|TURTLE|SPARQL)"; private String simpleUrlRegex = "/" + serviceIdRegex + "/?"; private String urlWithFormatRegex = "/" + serviceIdRegex + formatRegex + "/?"; private String getInputOrOutputRegex = "/" + serviceIdRegex + "/" + "(input|output)" + "/?"; private String getInputOrOutputWithFormatRegex = "/" + serviceIdRegex + "/" + "(input|output)" + ioFormatRegex + "/?"; Pattern simpleUrlPattern = Pattern.compile(simpleUrlRegex, Pattern.CASE_INSENSITIVE); Pattern urlWithFormatPattern = Pattern.compile(urlWithFormatRegex, Pattern.CASE_INSENSITIVE); Pattern getInputOrOutputPattern = Pattern.compile(getInputOrOutputRegex, Pattern.CASE_INSENSITIVE); Pattern getInputOrOutputWithFormatPattern = Pattern.compile(getInputOrOutputWithFormatRegex, Pattern.CASE_INSENSITIVE); private String id; private String format; private String resource; public RestRequest(String pathInfo, String method) throws ServletException { // regex parse pathInfo Matcher matcher; if (pathInfo == null || pathInfo.trim().length() == 0) return; if (method == HttpMethods.GET) { matcher = getInputOrOutputWithFormatPattern.matcher(pathInfo); if (matcher.find()) { logger.debug(getInputOrOutputWithFormatRegex); id = matcher.group(1); resource = matcher.group(2); format = matcher.group(3); return; } matcher = getInputOrOutputPattern.matcher(pathInfo); if (matcher.find()) { logger.debug(getInputOrOutputRegex); id = matcher.group(1); resource = matcher.group(2); format = DEFAULT_FORMAT; return; } } matcher = urlWithFormatPattern.matcher(pathInfo); if (matcher.find()) { logger.debug(urlWithFormatRegex); id = matcher.group(1); format = matcher.group(2); resource = null; return; } matcher = simpleUrlPattern.matcher(pathInfo); if (matcher.find()) { logger.debug(simpleUrlRegex); id = matcher.group(1); format = DEFAULT_FORMAT; resource = null; return; } throw new ServletException("Invalid URI"); } public String getId() { return id; } public String getFormat() { // I don't know why Jena gives error for turtle. if (format.equalsIgnoreCase("TTL") || format.equalsIgnoreCase("TURTLE")) format = DEFAULT_FORMAT; return format.toUpperCase(); } public String getResource() { return resource; } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.debug("Request URL: " + request.getRequestURI()); logger.debug("Request Path Info: " + request.getPathInfo()); logger.debug("Request Param: " + request.getQueryString()); RestRequest restRequest = null; try { String url = request.getPathInfo(); if (request.getQueryString() != null) url += "?" + request.getQueryString(); restRequest = new RestRequest(url , HttpMethods.GET); } catch (ServletException e) { response.setContentType(MimeType.TEXT_PLAIN); response.getWriter().write("Invalid URL!"); return; } String serviceId = restRequest.getId(); String format = restRequest.getFormat(); String resource = restRequest.getResource(); logger.debug("Id: " + serviceId); logger.debug("Format: " + format); logger.debug("Resource: " + resource); ResourceType resourceType = ResourceType.Service; if (resource != null && resource.trim().toString().equalsIgnoreCase("input")) resourceType = ResourceType.Input; if (resource != null && resource.trim().toString().equalsIgnoreCase("output")) resourceType = ResourceType.Output; new GetRequestManager(serviceId, resourceType, format, response).HandleRequest(); response.flushBuffer(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.debug("Request URL: " + request.getRequestURI()); logger.debug("Request Path Info: " + request.getPathInfo()); logger.debug("Request Param: " + request.getQueryString()); RestRequest restRequest = null; try { String url = request.getPathInfo(); if (request.getQueryString() != null) url += "?" + request.getQueryString(); restRequest = new RestRequest(url, HttpMethods.POST); } catch (ServletException e) { response.setContentType(MimeType.TEXT_PLAIN); response.getWriter().write("Invalid URL!"); return; } String serviceId = restRequest.getId(); String format = restRequest.getFormat(); // for (String s : request.getParameterMap().keySet()) // System.out.println(s + " --- " + request.getParameterMap().get(s).toString()); // logger.debug("Id: " + serviceId); // logger.debug("Format: " + format); //request.setCharacterEncoding(CharEncoding.ISO_8859_1); logger.info("Content-Type: " + request.getContentType()); String formData = null; String inputLang = ""; if (request.getContentType().startsWith(MimeType.APPLICATION_RDF_XML)) inputLang = SerializationLang.XML; if (request.getContentType().startsWith(MimeType.TEXT_XML)) inputLang = SerializationLang.XML; else if (request.getContentType().startsWith(MimeType.APPLICATION_XML)) inputLang = SerializationLang.XML; else if (request.getContentType().startsWith(MimeType.APPLICATION_RDF_N3)) inputLang = SerializationLang.N3; if (request.getContentType().startsWith(MimeType.APPLICATION_FORM_URLENCODED)) { inputLang = SerializationLang.N3; // default for html forms formData = request.getParameter("rdf"); logger.debug(formData); } else { response.setContentType(MimeType.TEXT_PLAIN); response.getWriter().write("The content type is neither rdf+xml nor rdf+n3"); return; } InputStream in = request.getInputStream(); if (formData != null) { in = new ByteArrayInputStream(formData.getBytes()); } new PostRequestManager(serviceId, in, inputLang, format, response).HandleRequest(); response.flushBuffer(); } // public static Document loadXMLFromString(String xml) throws Exception // { // DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // DocumentBuilder builder = factory.newDocumentBuilder(); // InputSource is = new InputSource(new StringReader(xml)); // return builder.parse(is); // } }