Mercurial > hg > fulltextSearchServer
diff src/de/mpiwg/dwinter/fulltextSearchServer/SearchTicket.java @ 0:db87c1b7eb6d
initial
author | dwinter |
---|---|
date | Wed, 03 Nov 2010 12:18:46 +0100 |
parents | |
children | 83e9a828e794 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/dwinter/fulltextSearchServer/SearchTicket.java Wed Nov 03 12:18:46 2010 +0100 @@ -0,0 +1,223 @@ +package de.mpiwg.dwinter.fulltextSearchServer; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Properties; +import java.util.concurrent.ConcurrentMap; + +import org.apache.log4j.Logger; +import org.apache.lucene.index.CorruptIndexException; +import org.apache.lucene.store.LockObtainFailedException; +import org.restlet.Context; +import org.restlet.data.Form; +import org.restlet.data.MediaType; +import org.restlet.data.Status; +import org.restlet.representation.Representation; +import org.restlet.representation.StringRepresentation; +import org.restlet.resource.Options; +import org.restlet.resource.Post; +import org.restlet.resource.Get; +import org.restlet.resource.ServerResource; + +import sun.misc.UUEncoder; +import sun.security.provider.MD5; + +import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility; + + +import de.mpiwg.dwinter.fulltext.search.FulltextSearchDocsLines; +import de.mpiwg.dwinter.fulltext.ticket.TicketWriter; +import de.mpiwg.dwinter.fulltextSearchServer.Utils.ConfigurationManager; +import de.mpiwg.dwinter.fulltextSearchServer.searchThreads.SearchInlinesThread; + + +/** + * REST-Klasse, die die eigentliche Suche startet. + * @author dwinter + * + */ +public class SearchTicket extends ServerResource { + + + private File lineDir; + private File docIndex; + private Logger logger = Logger.getRootLogger(); + private String ticketIdentifier; + + + /** + * Initialisiert die Methode, die Indixes fŸr die Dokumente und Zeilen werden aus dem Konfigurationsfile gelesen. + * @throws IOException + */ + public SearchTicket() throws IOException{ + Properties defaultProperties = ConfigurationManager.getConfig(); + lineDir = new File(defaultProperties.getProperty("lineIndex")); + docIndex = new File(defaultProperties.getProperty("docIndex")); + ticketIdentifier = defaultProperties.getProperty("ticketIdentifier"); +; } + //need options for crossdomain scripting + /** + * Erlaubt Cross-Domain Scripting + * @param entity + */ + @Options + public void doOptions(Representation entity) { + Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers"); + if (responseHeaders == null) { + responseHeaders = new Form(); + getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders); + } + responseHeaders.add("Access-Control-Allow-Origin", "*"); + responseHeaders.add("Access-Control-Allow-Methods", "POST,OPTIONS,GET"); + responseHeaders.add("Access-Control-Allow-Headers", "Content-Type"); + responseHeaders.add("Access-Control-Allow-Credentials", "false"); + responseHeaders.add("Access-Control-Max-Age", "60"); + } + + /** + * Methode wird aufgerufen, wenn Ÿber REST mit POST auf diese zurueckgegriffen wird. search muss eine FORM mit Wert + * fuer "searchString" enthalten, sonst wird null zurueckgegeben. Weitere Felder in sind "languages" welches einen String + * mit den Sprachen, in denen gesucht werden soll, enthaelt. Dieser hat die Form "lang1_lang2_...". Ausserdem kann ein + * Feld "searchMetaData" uebergeben werden, dann wird die Suche auf Texte eingeschraenkt, die die ensprechenden Metadaten enthalten. + * + * Zurueck gegeben wird <html><body><a href=\"tickets/"+ticket+"\">"+ticket+"</a></html>. Wobeit ticket die entsprechende ticketnummer der Suche ist. + * Auf dem Server wird ein entsprechendes Ticket angelegt und kann dann mit REST abgefragt werden. + * @param search + * @return + */ + @Post + public Representation getTicketHTML(Representation search){ + + // response header fuer cross-site.scripting + Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers"); + if (responseHeaders == null) { + responseHeaders = new Form(); + getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders); + } + responseHeaders.add("Access-Control-Allow-Origin", "*"); + + + //now do the search + Form searchForm = new Form(search); + + //String ticket = generateTicket(); + String searchString=searchForm.getValues("searchString"); + String languages=searchForm.getValues("languages"); // language der form la1_la2_la3___ + String searchMetaData=searchForm.getValues("searchMetaData"); + //no Searchstring + if (searchString==null || languages==null ) + return null; + + logger.debug("SearchTicket:"+searchString); + logger.debug("Languages:"+languages); + logger.debug("SearchMetaData:"+searchMetaData); + + String ticket = generateTicket(searchString,languages,searchMetaData); + + + // ticket alreaday exist, then no new search is needed + if (TicketWriter.exists(ticket)){ + String htmlTicket = wrapHTML(ticket); + Representation representation = new StringRepresentation(htmlTicket,MediaType.TEXT_HTML); + return representation; + } + + + //add the searcher to the context, if there is none + Context context = Context.getCurrent(); + ConcurrentMap<String, Object> attrs = context.getAttributes(); + FulltextSearchDocsLines fulltextSearcher = null; + if (!attrs.containsKey("searcher")){ + try { + fulltextSearcher = new FulltextSearchDocsLines(docIndex,lineDir); + } catch (CorruptIndexException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (LockObtainFailedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + fulltextSearcher = (FulltextSearchDocsLines) attrs.get("searcher"); + } + + + + String[] langs = languages.split("_"); + + for (String lang: langs){ + SearchInlinesThread st = new SearchInlinesThread(fulltextSearcher, searchString, searchMetaData,lang,ticket); + st.start(); + } + + String htmlTicket = wrapHTML(ticket); + Representation representation = new StringRepresentation(htmlTicket,MediaType.TEXT_HTML); + return representation; + } + +// @Post("xml") +// public Representation getTicketXML(Representation search){ +// +// Form searchForm = new Form(search); +// +// String ticket = generateTicket(); +// String searchString=searchForm.getValues("searchString"); +// +// SearchInlinesThread st = new SearchInlinesThread(docIndex, lineDir, searchString, "de",ticket); +// st.start(); +// String xmlTicket = wrapXML(ticket); +// Representation representation = new StringRepresentation(xmlTicket,MediaType.TEXT_XML); +// return representation; +// } +// + + + private String wrapHTML(String ticket) { + String ret ="<html><body><a href=\"tickets/"+ticket+"\">"+ticket+"</a></html>";// TODO Auto-generated method stub + return ret; + } + + private String wrapXML(String ticket) { + String ret ="<xml><ticketnr xlink=\"tickets/"+ticket+"\">"+ticket+"</ticketnr></xml>"; + return ret; + } + + private String generateTicket() { + return TicketWriter.getNewTicket(); + + } + + /** + * Erzeugt ein Ticket aus den Strings (aus den Strings wird ein MD5 hash erzeugt, + * so dass fŸr jede Suche mit den gleichen Perametern das Ticket, gleich ist. + * @param searchString + * @param languages + * @param searchMetaData + * @return + */ + private String generateTicket(String searchString, String languages, + String searchMetaData) { + + //return generateTicket(); + + String tmpString= ticketIdentifier+"|"+searchMetaData+"|"+searchString+"|"+languages; + + + return String.valueOf(tmpString.hashCode()); + + + } + + /** + * Methode wird aufgerufen bei GET auf diese Klasse und gibt alle gespeicherten Tickets zurueck. + * @return + */ + @Get("XML") + public Representation getAllTickets(){ + return new StringRepresentation(TicketWriter.getAllTickets(),MediaType.TEXT_XML); + } +}