/*
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.";
}//
}