Mercurial > hg > fulltextSearchServer
view src/de/mpiwg/dwinter/fulltextSearchServer/SearchTicket.java @ 1:83e9a828e794
Version mit integrierter Suche ?ber XML-Volltexte
author | dwinter |
---|---|
date | Wed, 26 Jan 2011 14:41:34 +0100 |
parents | db87c1b7eb6d |
children |
line wrap: on
line source
package de.mpiwg.dwinter.fulltextSearchServer; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.List; import java.util.Properties; import java.util.concurrent.ConcurrentMap; import org.apache.log4j.Logger; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.search.Query; 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.search.IFulltextSearchDocsLines; import de.mpiwg.dwinter.fulltext.search.utils.OCRDoc; import de.mpiwg.dwinter.fulltext.search.xmlsearchadapter.XMLSearchServerAdapter; 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; try { languages = URLDecoder.decode(searchForm.getValues("languages"),"utf-8"); } catch (UnsupportedEncodingException e1) { // TODO Auto-generated catch block e1.printStackTrace(); 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"); } IFulltextSearchDocsLines[] fulltextSearchers = new IFulltextSearchDocsLines[]{fulltextSearcher, new XMLSearchServerAdapter()}; String[] langs = languages.split("_"); for (String lang: langs){ SearchInlinesThread st = new SearchInlinesThread(fulltextSearchers, 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); } }