/* Copyright (c) 2008, Centre for Educational Technology, Tallinn University Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ package ee.tlu.htk.waramu.servlets; import ee.tlu.htk.waramu.annotations.Transformers; import ee.tlu.htk.waramu.base.BaseType; import ee.tlu.htk.waramu.db.DataLoaderLocal; import ee.tlu.htk.waramu.server.Catalogs; import ee.tlu.htk.waramu.server.DBLocal; import ee.tlu.htk.waramu.utils.GenerateId; import ee.tlu.htk.waramu.utils.UTCTime; import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.EJB; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Content restrctions: type must have field created. * @author vahur */ public class OAIHandler extends HttpServlet { @EJB private DataLoaderLocal dataLoaderBean; @EJB private DBLocal dBBean; private static final String oai_prefix = "oai:ait.opetaja.ee:"; private static final Integer maxListSize = 50; private static final String[] verbs = new String[]{ "Identify", "GetRecord", "ListMetadataFormats", "ListRecords", "ListSets", "ListIdentifiers" }; private HashMap resumptions = new HashMap(); private HashMap resumptionOptions = new HashMap(); /** * Processes requests for both HTTP GET and POST methods. * @param request servlet request * @param response servlet response */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/xml;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println(""); String reqVerb = request.getParameter("verb"); String verb = ""; if (reqVerb == null) { out.println("verb is empty"); out.close(); return; } boolean isValidVerb = false; for (String v : verbs) { if (reqVerb.equals(v)) { isValidVerb = true; verb = v; break; } } out.println(""); out.println("" + new UTCTime(new Date()) + ""); if (isValidVerb) { if (verb.equals("Identify")) { Identify(out, request); } if (verb.equals("GetRecord")) { GetRecord(out, request); } if (verb.equals("ListMetadataFormats")) { ListMetadataFormats(out, request); } if (verb.equals("ListRecords")) { ListRecords(out, request); } if (verb.equals("ListSets")) { ListSets(out, request); } if (verb.equals("ListIdentifiers")) { ListIdentifiers(out, request); } } else { out.println("Not valid verb"); } out.println(""); out.close(); } // done public void ListSets(PrintWriter out, HttpServletRequest request) { /* * badArgument * badResumptionToken * noSetHierarchy */ out.println("" + request.getRequestURL() + ""); out.println(""); List catList = dBBean.getCatalogs(); for (Catalogs c : catList) { out.println(""); out.println("" + c.getCid() + ""); out.println("" + c.getCatalogName() + ""); out.println(""); } out.println(""); } // done, TODO: transformers! public void ListRecords(PrintWriter out, HttpServletRequest request) { String from = request.getParameter("from"); String until = request.getParameter("until"); String mdPrefix = request.getParameter("metadataPrefix"); // * String set = request.getParameter("set"); Integer setint = null; String resumptionToken = request.getParameter("resumptionToken"); /* * badArgument * badResumptionToken * cannotDisseminateFormat * noRecordsMatch * noSetHierarchy */ if (mdPrefix == null && resumptionToken == null) { out.println("Not enough arguments"); return; } if (resumptionToken != null && !resumptions.containsKey(resumptionToken)) { out.println("Not enough arguments"); return; } if (set != null) { /* TODO Catalog c = catalogFacade.findByName(set); if (c == null) { out.println("Invalid set"); return; } * */ setint = new Integer(set); } if (from != null) { from = from.replace("T", " "); from = from.replace("Z", ""); } if (until != null) { until = until.replace("T", " "); until = until.replace("Z", ""); } // get list from resumption if exists; List fulllist = null; if (resumptionToken == null) { // TODO: FIX! fulllist = dataLoaderBean.getObjectsBy(setint, from, until); } else { fulllist = (List) resumptions.get(resumptionToken); String[] resOpts = (String[]) resumptionOptions.get(resumptionToken); from = resOpts[0]; until = resOpts[1]; mdPrefix = resOpts[2]; set = resOpts[3]; } if (fulllist.size() == 0) { out.println("No records"); return; } List mdlist = new ArrayList(); String resumToken = ""; if (fulllist.size() > maxListSize) { // generate resumption if (resumptionToken != null) { resumToken = resumptionToken; } else { resumToken = GenerateId.getUID(); } List tmp = fulllist.subList(0, maxListSize); for (BaseType m : tmp) { mdlist.add(m); } for (BaseType m : mdlist) { fulllist.remove(m); } resumptions.put(resumToken, fulllist); resumptionOptions.put(resumToken, new String[]{from, until, mdPrefix, set}); } else { if (resumptionToken != null) { List tmp = fulllist; for (BaseType m : tmp) { mdlist.add(m); } for (BaseType m : mdlist) { fulllist.remove(m); } } else { mdlist = fulllist; } } out.println("" + request.getRequestURL() + ""); out.println(""); String fullurl = request.getRequestURL().toString(); String[] parts = fullurl.split("OAIHandler"); String url = parts[0] + request.getContextPath() + "/"; url = parts[0]; for (BaseType obj : mdlist) { Object transformer = obj.getTransformer(mdPrefix); if (transformer == null) { continue; } Method meth; String objres = ""; try { meth = transformer.getClass().getMethod("transform", new Class[]{BaseType.class}); objres = (String) meth.invoke(transformer, new Object[]{obj}); } catch (SecurityException ex) { ex.printStackTrace(); } catch (NoSuchMethodException ex) { ex.printStackTrace(); } catch (IllegalArgumentException ex) { ex.printStackTrace(); } catch (IllegalAccessException ex) { ex.printStackTrace(); } catch (InvocationTargetException ex) { ex.printStackTrace(); } objres = objres.replace("REPLACE_FULL_PATH_HERE", url); out.println(""); out.println("
"); out.println("" + oai_prefix + obj.getInternalId() + ""); String dateval = obj.getValue("created").toString(); String[] datesplit = dateval.split(" "); String timeval = datesplit[1].split("\\.")[0]; String newDateVal = datesplit[0] + "T" + timeval + "Z"; out.println("" + newDateVal + ""); out.println("" + obj.getCatalogId() + ""); out.println("
"); out.println(""); out.println(objres); out.println(""); out.println("
"); } if (fulllist != null && fulllist.size() > 0) { out.println("" + resumToken + ""); } out.println("
"); } // done public void ListMetadataFormats(PrintWriter out, HttpServletRequest request) { String identifier = parseIdentifier(request); /* * badArgument * idDoesNotExist * noMetadataFormats */ boolean dc_support = false; boolean lom_support = false; if (identifier == null) { dc_support = true; lom_support = true; } else { BaseType bt = dataLoaderBean.getObjectById(identifier); if (bt == null) { out.println("Id not found"); return; } Transformers trfs = bt.getClass().getAnnotation(Transformers.class); if (trfs != null) { Class[] cls = trfs.transformers(); for (Class tf : cls) { try { Object transf = tf.newInstance(); Method m = tf.getMethod("supports", new Class[]{String.class}); System.out.println("Method::" + m); if (!dc_support) { dc_support = (Boolean) m.invoke(transf, new Object[]{"oai_dc"}); } if (!lom_support) { lom_support = (Boolean) m.invoke(transf, new Object[]{"oai_lom"}); } } catch (InstantiationException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchMethodException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (SecurityException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalArgumentException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (InvocationTargetException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } } } } if (!lom_support && !dc_support) { out.println("Id not found"); return; } out.println("" + request.getRequestURL() + "" + ""); if (dc_support) { out.println("" + "oai_dc" + "http://www.openarchives.org/OAI/2.0/oai_dc.xsd" + "http://www.openarchives.org/OAI/2.0/oai_dc/" + "" + ""); } if (lom_support) { out.println("" + "oai_lom" + "http://standards.ieee.org/reading/ieee/downloads/LOM/lomv1.0/xsd/lom.xsd" + "http://ltsc.ieee.org/xsd/LOM" + "" + ""); } out.println(""); } // done with TODOs public void ListIdentifiers(PrintWriter out, HttpServletRequest request) { String from = request.getParameter("from"); String until = request.getParameter("until"); String mdPrefix = request.getParameter("metadataPrefix"); String set = request.getParameter("set"); Integer setint = null; String resumptionToken = request.getParameter("resumptionToken"); /* * badArgument * badResumptionToken * cannotDisseminateFormat * noRecordsMatch * noSetHierarchy */ if (mdPrefix == null && resumptionToken == null) { out.println("Not enough arguments"); return; } if (resumptionToken != null && !resumptions.containsKey(resumptionToken)) { out.println("Not enough arguments"); return; } //String query = "SELECT * FROM metadata WHERE 1=1 "; if (set != null) { /* Catalog c = catalogFacade.findByName(set); if (c == null) { out.println("Invalid set"); return; } * */ setint = new Integer(set); } if (from != null) { from = from.replace("T", " "); from = from.replace("Z", ""); } if (until != null) { until = until.replace("T", " "); until = until.replace("Z", ""); } List fulllist = null; if (resumptionToken == null) { fulllist = fulllist = dataLoaderBean.getObjectsBy(setint, from, until); } else { fulllist = (List) resumptions.get(resumptionToken); String[] resOpts = (String[]) resumptionOptions.get(resumptionToken); from = resOpts[0]; until = resOpts[1]; mdPrefix = resOpts[2]; set = resOpts[3]; } if (fulllist.size() == 0) { out.println("No records"); return; } List mdlist = new ArrayList(); String resumToken = ""; if (fulllist.size() > maxListSize) { // generate resumption if (resumptionToken != null) { resumToken = resumptionToken; } else { resumToken = GenerateId.getUID(); } List tmp = fulllist.subList(0, maxListSize); for (BaseType m : tmp) { mdlist.add(m); } for (BaseType m : mdlist) { fulllist.remove(m); } resumptions.put(resumToken, fulllist); resumptionOptions.put(resumToken, new String[]{from, until, mdPrefix, set}); } else { List tmp = fulllist; for (BaseType m : tmp) { mdlist.add(m); } for (BaseType m : mdlist) { fulllist.remove(m); } } out.println("" + request.getRequestURL() + ""); out.println(""); for (BaseType m : mdlist) { out.println("
"); out.println("" + oai_prefix + m.getInternalId() + ""); String dateval = m.getValue("created").toString(); String[] datesplit = dateval.split(" "); String timeval = datesplit[1].split("\\.")[0]; String newDateVal = datesplit[0] + "T" + timeval + "Z"; out.println("" + newDateVal + ""); out.println("" + m.getCatalogId() + ""); out.println("
"); } // resumption token here! if (fulllist != null && fulllist.size() > 0) { out.println("" + resumToken + ""); } out.println("
"); } // done with TODOs public void GetRecord(PrintWriter out, HttpServletRequest request) { String identifier = parseIdentifier(request); String mdPrefix = request.getParameter("metadataPrefix"); /* * badArgument * cannotDisseminateFormat * idDoesNotExist */ if (identifier == null || mdPrefix == null) { out.println("Not enough arguments"); return; } BaseType obj = dataLoaderBean.getObjectById(identifier); if (obj == null) { out.println("Id not found"); return; } Object transformer = obj.getTransformer(mdPrefix); if (transformer == null) { out.println("Error"); return; } String objres = ""; Method meth; try { meth = transformer.getClass().getMethod("transform", new Class[]{BaseType.class}); objres = (String) meth.invoke(transformer, new Object[]{obj}); } catch (NoSuchMethodException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (SecurityException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalArgumentException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (InvocationTargetException ex) { Logger.getLogger(OAIHandler.class.getName()).log(Level.SEVERE, null, ex); } String fullurl = request.getRequestURL().toString(); String[] parts = fullurl.split("OAIHandler"); String url = parts[0] + request.getContextPath() + "/"; url = parts[0]; objres = objres.replace("REPLACE_FULL_PATH_HERE", url); out.println("" + request.getRequestURL() + ""); out.println(""); out.println(""); out.println("
"); out.println("" + oai_prefix + obj.getInternalId() + ""); String dateval = obj.getValue("created").toString(); String[] datesplit = dateval.split(" "); String timeval = datesplit[1].split("\\.")[0]; String newDateVal = datesplit[0] + "T" + timeval + "Z"; out.println("" + newDateVal + ""); out.println("" + obj.getCatalogId() + ""); out.println("
"); out.println(""); // TODO: transformed object here! out.println(objres); out.println(""); out.println("
"); out.println("
"); } // done public void Identify(PrintWriter out, HttpServletRequest request) { /* * badArgument */ out.println("" + request.getRequestURL() + ""); out.println(""); // repositoryName out.println("TLÜ Repository"); // baseURL out.println("" + request.getRequestURL() + ""); // protocolVersion out.println("2.0"); // earliestDatestamp out.println("1990-02-01T12:00:00Z"); // deletedRecord out.println("no"); // granularity out.println("YYYY-MM-DDThh:mm:ssZ"); // adminEmail out.println("vahur@tlu.ee"); out.println("" + "" + "oai" + "ait.opetaja.ee" + ":" + "oai:ait.opetaja.ee:1513" + "" + ""); out.println(""); } public String parseIdentifier(HttpServletRequest request) { String identifier = request.getParameter("identifier"); if (identifier == null) { return null; } identifier = identifier.replace(oai_prefix, ""); return identifier; } // /** * Handles the HTTP GET method. * @param request servlet request * @param response servlet response */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP POST method. * @param request servlet request * @param response servlet response */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. */ @Override public String getServletInfo() { return "Waramu OAI target."; }// }