d787df6f4ab5c52ac9233c4c511e3a0ce821728e
[mir.git] / source / mircoders / servlet / ServletModuleOpenIndy.java
1 /*
2  * Copyright (C) 2001, 2002  The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with the com.oreilly.servlet library, any library
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24  * the above that use the same license as the above), and distribute linked
25  * combinations including the two.  You must obey the GNU General Public
26  * License in all respects for all of the code used other than the above
27  * mentioned libraries.  If you modify this file, you may extend this exception
28  * to your version of the file, but you are not obligated to do so.  If you do
29  * not wish to do so, delete this exception statement from your version.
30  */
31
32 package mircoders.servlet;
33
34 import java.io.ByteArrayOutputStream;
35 import java.io.File;
36 import java.io.FileNotFoundException;
37 import java.io.FileReader;
38 import java.io.IOException;
39 import java.io.PrintWriter;
40 import java.io.StringWriter;
41 import java.util.ArrayList;
42 import java.util.Collections;
43 import java.util.Enumeration;
44 import java.util.GregorianCalendar;
45 import java.util.HashMap;
46 import java.util.Iterator;
47 import java.util.ListIterator;
48 import java.util.Locale;
49 import java.util.Map;
50 import java.util.Random;
51 import java.util.Set;
52
53 import javax.servlet.http.HttpServletRequest;
54 import javax.servlet.http.HttpServletResponse;
55 import javax.servlet.http.HttpSession;
56
57 import mir.entity.Entity;
58 import mir.entity.EntityList;
59 import mir.log.LoggerWrapper;
60 import mir.misc.FileHandler;
61 import mir.misc.FileHandlerUserException;
62 import mir.misc.HTMLTemplateProcessor;
63 import mir.misc.StringUtil;
64 import mir.misc.WebdbMultipartRequest;
65 import mir.module.ModuleException;
66 import mir.servlet.ServletModule;
67 import mir.servlet.ServletModuleExc;
68 import mir.servlet.ServletModuleFailure;
69 import mir.servlet.ServletModuleUserExc;
70 import mir.storage.StorageObjectFailure;
71 import mir.util.StringRoutines;
72 import mircoders.entity.EntityComment;
73 import mircoders.entity.EntityContent;
74 import mircoders.global.MirGlobal;
75 import mircoders.media.MediaRequest;
76 import mircoders.module.ModuleComment;
77 import mircoders.module.ModuleContent;
78 import mircoders.module.ModuleImages;
79 import mircoders.module.ModuleTopics;
80 import mircoders.search.AudioSearchTerm;
81 import mircoders.search.ContentSearchTerm;
82 import mircoders.search.ImagesSearchTerm;
83 import mircoders.search.KeywordSearchTerm;
84 import mircoders.search.TextSearchTerm;
85 import mircoders.search.TopicSearchTerm;
86 import mircoders.search.UnIndexedSearchTerm;
87 import mircoders.search.VideoSearchTerm;
88 import mircoders.storage.DatabaseComment;
89 import mircoders.storage.DatabaseContent;
90 import mircoders.storage.DatabaseContentToMedia;
91 import mircoders.storage.DatabaseContentToTopics;
92 import mircoders.storage.DatabaseImages;
93 import mircoders.storage.DatabaseLanguage;
94 import mircoders.storage.DatabaseTopics;
95
96 import org.apache.commons.net.smtp.SMTPClient;
97 import org.apache.commons.net.smtp.SMTPReply;
98 import org.apache.fop.apps.Driver;
99 import org.apache.fop.apps.XSLTInputHandler;
100 import org.apache.log.Hierarchy;
101 import org.apache.log.Priority;
102 import org.apache.lucene.analysis.standard.StandardAnalyzer;
103 import org.apache.lucene.document.Document;
104 import org.apache.lucene.queryParser.QueryParser;
105 import org.apache.lucene.search.Hits;
106 import org.apache.lucene.search.IndexSearcher;
107 import org.apache.lucene.search.Query;
108 import org.apache.lucene.search.Searcher;
109
110 import freemarker.template.SimpleHash;
111 import freemarker.template.SimpleList;
112 import freemarker.template.SimpleScalar;
113 import freemarker.template.TemplateModelRoot;
114
115 /*
116  *  ServletModuleOpenIndy -
117  *   is the open-access-servlet, which is responsible for
118  *    adding comments to articles &
119  *    open-postings to the newswire
120  *
121  * @author mir-coders group
122  * @version $Id: ServletModuleOpenIndy.java,v 1.64 2003/03/08 17:18:19 idfx Exp $
123  *
124  */
125
126 public class ServletModuleOpenIndy extends ServletModule
127 {
128
129   private String        commentFormTemplate, commentFormDoneTemplate,
130     commentFormDupeTemplate;
131   private String        postingFormTemplate, postingFormDoneTemplate,
132     postingFormDupeTemplate;
133   private String        searchResultsTemplate;
134   private String        prepareMailTemplate,sentMailTemplate;
135   private ModuleContent contentModule;
136   private ModuleComment commentModule;
137   private ModuleImages  imageModule;
138   private ModuleTopics  themenModule;
139   private String        directOp ="yes";
140   private String        passwdProtection ="yes";
141   // Singelton / Kontruktor
142   private static ServletModuleOpenIndy instance = new ServletModuleOpenIndy();
143   public static ServletModule getInstance() { return instance; }
144
145   private ServletModuleOpenIndy() {
146     super();
147     try {
148       logger = new LoggerWrapper("ServletModule.OpenIndy");
149
150       commentFormTemplate = configuration.getString("ServletModule.OpenIndy.CommentTemplate");
151       commentFormDoneTemplate = configuration.getString("ServletModule.OpenIndy.CommentDoneTemplate");
152       commentFormDupeTemplate = configuration.getString("ServletModule.OpenIndy.CommentDupeTemplate");
153       postingFormTemplate = configuration.getString("ServletModule.OpenIndy.PostingTemplate");
154       postingFormDoneTemplate = configuration.getString("ServletModule.OpenIndy.PostingDoneTemplate");
155       postingFormDupeTemplate = configuration.getString("ServletModule.OpenIndy.PostingDupeTemplate");
156       searchResultsTemplate = configuration.getString("ServletModule.OpenIndy.SearchResultsTemplate");
157       prepareMailTemplate = configuration.getString("ServletModule.OpenIndy.PrepareMailTemplate");
158       sentMailTemplate = configuration.getString("ServletModule.OpenIndy.SentMailTemplate");
159       directOp = configuration.getString("DirectOpenposting").toLowerCase();
160       passwdProtection = configuration.getString("PasswdProtection").toLowerCase();
161       mainModule = new ModuleComment(DatabaseComment.getInstance());
162       contentModule = new ModuleContent(DatabaseContent.getInstance());
163       themenModule = new ModuleTopics(DatabaseTopics.getInstance());
164       imageModule = new ModuleImages(DatabaseImages.getInstance());
165       defaultAction="addposting";
166
167     }
168     catch (StorageObjectFailure e) {
169       logger.error("servletmoduleopenindy could not be initialized: " + e.getMessage());
170     }
171   }
172
173
174   /**
175    *  Method for making a comment
176    */
177
178   public void addcomment(HttpServletRequest req, HttpServletResponse res)
179       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
180   {
181     String aid = req.getParameter("aid"); // the article id the comment will belong to
182     String language = req.getParameter("language");
183
184     if (aid!=null && !aid.equals("")) {
185       try {
186         SimpleHash mergeData = new SimpleHash();
187
188         // onetimepasswd
189         if (passwdProtection.equals("yes")) {
190           String passwd = this.createOneTimePasswd();
191           HttpSession session = req.getSession(false);
192           session.setAttribute("passwd", passwd);
193           mergeData.put("passwd", passwd);
194         }
195
196         if (language != null) {
197           HttpSession session = req.getSession(false);
198           session.setAttribute("Locale", new Locale(language, ""));
199           session.setAttribute("passwd", language);
200         }
201
202         mergeData.put("aid", aid);
203
204         SimpleHash extraInfo = new SimpleHash();
205         extraInfo.put("languagePopUpData", DatabaseLanguage.getInstance().getPopupData());
206
207         deliver(req, res, mergeData, extraInfo, commentFormTemplate);
208       }
209       catch (Throwable t) {
210         throw new ServletModuleFailure("ServletModuleOpenIndy.addcomment: " + t.getMessage(), t);
211       }
212     }
213     else throw new ServletModuleExc("aid not set!");
214   }
215
216   /**
217    *  Method for inserting a comment into the Database and delivering
218    *  the commentDone Page
219    */
220
221   public void inscomment(HttpServletRequest req, HttpServletResponse res)
222     throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
223   {
224     String aid = req.getParameter("to_media"); // the article id the comment will belong to
225     if (aid!=null && !aid.equals(""))
226       {
227         // ok, collecting data from form
228         try {
229           Map withValues = getIntersectingValues(req, DatabaseComment.getInstance());
230
231           //no html in comments(for now)
232           for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
233             String k=(String)i.next();
234             String v=(String)withValues.get(k);
235
236             withValues.put(k,StringUtil.removeHTMLTags(v));
237           }
238           withValues.put("is_published","1");
239           withValues.put("to_comment_status","1");
240
241           //checking the onetimepasswd
242           if(passwdProtection.equals("yes")){
243             HttpSession session = req.getSession(false);
244             String sessionPasswd = (String)session.getAttribute("passwd");
245             if ( sessionPasswd == null){
246               throw new ServletModuleUserExc("Lost password");
247             }
248             String passwd = req.getParameter("passwd");
249             if ( passwd == null || (!sessionPasswd.equals(passwd))) {
250               throw new ServletModuleUserExc("Missing password");
251             }
252             session.invalidate();
253           }
254
255           // inserting into database
256           String id = mainModule.add(withValues);
257           logger.debug("id: "+id);
258           //insert was not successfull
259           if(id==null){
260             deliver(req, res, new SimpleHash(), commentFormDupeTemplate);
261           } else {
262             DatabaseContent.getInstance().setUnproduced("id="+aid);
263
264             try {
265               EntityComment comment = (EntityComment) DatabaseComment.getInstance().selectById(id);
266               MirGlobal.localizer().openPostings().afterCommentPosting(comment);
267             }
268             catch (Throwable t) {
269               throw new ServletModuleExc(t.getMessage());
270             }
271           }
272
273           // redirecting to url
274           // should implement back to article
275           SimpleHash mergeData = new SimpleHash();
276           deliver(req, res, mergeData, commentFormDoneTemplate);
277         }
278         catch (Throwable e) {
279           throw new ServletModuleFailure(e);
280         }
281       }
282     else throw new ServletModuleExc("aid not set!");
283
284   }
285
286   /**
287    *  Method for delivering the form-Page for open posting
288    */
289
290   public void addposting(HttpServletRequest req, HttpServletResponse res)
291       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
292   {
293     SimpleHash mergeData = new SimpleHash();
294
295     // onetimepasswd
296     if(passwdProtection.equals("yes")){
297       String passwd = this.createOneTimePasswd();
298       HttpSession session = req.getSession(false);
299       session.setAttribute("passwd",passwd);
300       mergeData.put("passwd", passwd);
301     }
302
303     String maxMedia = configuration.getString("ServletModule.OpenIndy.MaxMediaUploadItems");
304     String defaultMedia = configuration.getString("ServletModule.OpenIndy.DefaultMediaUploadItems");
305     String numOfMedia = req.getParameter("medianum");
306
307     if(numOfMedia==null||numOfMedia.equals("")){
308       numOfMedia=defaultMedia;
309     }
310     else if(Integer.parseInt(numOfMedia) > Integer.parseInt(maxMedia)) {
311       numOfMedia = maxMedia;
312     }
313
314     int mediaNum = Integer.parseInt(numOfMedia);
315     SimpleList mediaFields = new SimpleList();
316     for(int i =0; i<mediaNum;i++){
317       Integer mNum = new Integer(i+1);
318       mediaFields.add(mNum.toString());
319     }
320     mergeData.put("medianum",numOfMedia);
321     mergeData.put("mediafields",mediaFields);
322
323
324     SimpleHash extraInfo = new SimpleHash();
325     try{
326       extraInfo.put("languagePopUpData", DatabaseLanguage.getInstance().getPopupData() );
327       extraInfo.put("themenPopupData", themenModule.getTopicsAsSimpleList());
328
329       extraInfo.put("topics", themenModule.getTopicsList());
330
331     }
332     catch (Exception e) {
333       logger.error("languagePopUpData or getTopicslist failed "+e.toString());
334
335       throw new ServletModuleFailure("OpenIndy -- failed getting language or topics: "+e.toString(), e);
336     }
337
338
339
340     deliver(req, res, mergeData, extraInfo, postingFormTemplate);
341   }
342
343   /**
344    *  Method for inserting an open posting into the Database and delivering
345    *  the postingDone Page
346    */
347
348   public void insposting(HttpServletRequest req, HttpServletResponse res)
349       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
350   {
351     SimpleHash mergeData = new SimpleHash();
352     boolean setMedia=false;
353     boolean setTopic = false;
354
355     try {
356
357       WebdbMultipartRequest mp = null;
358       EntityList mediaList = null;
359       try {
360         // new MediaRequest, "1" is the id for the openPosting user
361         MediaRequest mediaReq = new MediaRequest("1", true);
362         mp = new WebdbMultipartRequest(req, (FileHandler)mediaReq);
363         mediaList = mediaReq.getEntityList();
364       }
365       catch (FileHandlerUserException e) {
366         throw new ServletModuleFailure(e);
367       }
368
369       Map withValues = mp.getParameters();
370
371       //checking the onetimepasswd
372       if(passwdProtection.equals("yes")){
373         HttpSession session = req.getSession(false);
374         String sessionPasswd = (String)session.getAttribute("passwd");
375         if ( sessionPasswd == null){
376           throw new ServletModuleUserExc("Lost password");
377         }
378         String passwd = (String)withValues.get("passwd");
379         if ( passwd == null || (!sessionPasswd.equals(passwd))) {
380           throw new ServletModuleUserExc("Missing password");
381         }
382         session.invalidate();
383       }
384
385       if ((((String)withValues.get("title")).length() == 0) ||
386           (((String)withValues.get("description")).length() == 0) ||
387           (((String)withValues.get("content_data")).length() == 0))
388         throw new ServletModuleUserExc("Missing field");
389
390       // call the routines that escape html
391
392       for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
393         String k=(String)i.next();
394         String v=(String)withValues.get(k);
395
396         if (k.equals("content_data")){
397           //this doesn't quite work yet, so for now, all html goes
398           //withValues.put(k,StringUtil.approveHTMLTags(v));
399           withValues.put(k,StringUtil.deleteForbiddenTags(v));
400         } else if (k.equals("description")) {
401           String tmp = StringUtil.deleteForbiddenTags(v);
402           withValues.put(k,StringUtil.deleteHTMLTableTags(tmp));
403         } else {
404           withValues.put(k,StringUtil.removeHTMLTags(v));
405         }
406
407       }
408
409       withValues.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
410       withValues.put("publish_path", StringUtil.webdbDate2path((String)withValues.get("date")));
411       withValues.put("is_produced", "0");
412       // by default stuff is published, they can be un-published through the
413       // admin interface.
414       withValues.put("is_published","1");
415       // if op direct article-type == newswire
416       if (directOp.equals("yes")) withValues.put("to_article_type","1");
417
418       withValues.put("to_publisher","1");
419
420       // owner is openposting user
421       //      ML: this is not multi-language friendly and this can be done in a template
422       //      if (withValues.get("creator").toString().equals(""))
423       //        withValues.put("creator","Anonym");
424
425       // inserting  content into database
426       String cid = contentModule.add(withValues);
427       logger.debug("id: "+cid);
428       //insert was not successfull
429       if(cid==null){
430         //How do we know that it was not succesful cause of a
431         //dupe, what if it failed cause of "No space left on device"?
432         //Or is there something I am missing? Wouldn't it be better
433         //to have an explicit dupe check and then insert? I have no
434         //idea what I am talking about. this comment is in case
435         //I forget to explicitely ask. -mh
436         deliver(req, res, mergeData, postingFormDupeTemplate);
437       }
438
439       String[] to_topicsArr = mp.getParameterValues("to_topic");
440
441       if (to_topicsArr != null && to_topicsArr.length > 0) {
442         try{
443           DatabaseContentToTopics.getInstance().setTopics(cid,to_topicsArr);
444           setTopic = true;
445         }
446         catch (Exception e) {
447           logger.error("setting content_x_topic failed");
448           contentModule.deleteById(cid);
449           throw new ServletModuleExc("smod - openindy :: insposting: setting content_x_topic failed: "+e.toString());
450         } //end try
451       } //end if
452
453       //if we're here all is ok... associate the media to the article
454       for(int i=0;i<mediaList.size();i++) {
455         Entity mediaEnt = (Entity)mediaList.elementAt(i);
456         DatabaseContentToMedia.getInstance().addMedia(cid,mediaEnt.getId());
457       }
458
459       try {
460         MirGlobal.localizer().openPostings().afterContentPosting(
461                                                                  (EntityContent)contentModule.getById(cid));
462       }
463       catch (Throwable t) {
464         throw new ServletModuleFailure(t);
465       }
466     }
467     catch (Throwable e) {
468       throw new ServletModuleFailure(e);
469     }
470
471     deliver(req, res, mergeData, postingFormDoneTemplate);
472   }
473
474     /*
475    * Method for preparing and sending a content as an email message
476    */
477
478   public void mail(HttpServletRequest req, HttpServletResponse res)
479       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
480   {
481     String aid = req.getParameter("mail_aid");
482     if (aid == null){
483       throw new ServletModuleUserExc("An article id must be specified in requests to email an article.  Something therefore went badly wrong....");
484     }
485
486     String to = req.getParameter("mail_to");
487     String from = req.getParameter("mail_from");
488     String from_name = req.getParameter("mail_from_name");
489     String comment = req.getParameter("mail_comment");
490     String mail_language = req.getParameter("mail_language");
491
492     SimpleHash mergeData = new SimpleHash();
493
494     if (to == null || from == null || from_name == null|| to.equals("") || from.equals("") || from_name.equals("") || mail_language == null || mail_language.equals("")){
495
496       for (Enumeration theParams = req.getParameterNames(); theParams.hasMoreElements() ;) {
497         String pName=(String)theParams.nextElement();
498         if (pName.startsWith("mail_")){
499           mergeData.put(pName,new SimpleScalar(req.getParameter(pName)));
500         }
501       }
502       deliver(req,res,mergeData,prepareMailTemplate);
503     }
504     else {
505       //run checks on to and from and mail_language to make sure no monkey business occurring
506       if (mail_language.indexOf('.') != -1 || mail_language.indexOf('/') != -1 ){
507         throw new ServletModuleUserExc("Sorry, you've entered an illegal character into the language field.  Go back and try again, asshole.");
508       }
509       if (to.indexOf('\n') != -1
510           || to.indexOf('\r') != -1
511           || to.indexOf(',') != -1
512           || from.indexOf('\n') != -1
513           || from.indexOf('\r') != -1
514           || from.indexOf(',') != -1 ){
515         throw new ServletModuleUserExc("Sorry, you've entered an illegal character into the from or to field.  Go back and try again.");
516       }
517       EntityContent contentEnt;
518       try{
519         contentEnt = (EntityContent)contentModule.getById(aid);
520       }
521       catch (Throwable e){
522         throw new ServletModuleFailure("Couldn't get content for article "+aid + ": " + e.getMessage(), e);
523       }
524       String producerStorageRoot=configuration.getString("Producer.StorageRoot");
525       String producerDocRoot=configuration.getString("Producer.DocRoot");
526       String publishPath = contentEnt.getValue("publish_path");
527       String txtFilePath = producerStorageRoot + producerDocRoot + "/" + mail_language +
528                                                                                                          publishPath + "/" + aid + ".txt";
529
530
531       File inputFile = new File(txtFilePath);
532       String content;
533
534       try{
535         FileReader in = new FileReader(inputFile);
536         StringWriter out = new StringWriter();
537         int c;
538         while ((c = in.read()) != -1)
539           out.write(c);
540         in.close();
541         content= out.toString();
542       }
543       catch (FileNotFoundException e){
544         throw new ServletModuleFailure("No text file found in " + txtFilePath, e);
545       }
546       catch (IOException e){
547         throw new ServletModuleFailure("Problem reading file in " + txtFilePath, e);
548       }
549       // add some headers
550       content = "To: " + to + "\nReply-To: "+ from + "\n" + content;
551       // put in the comment where it should go
552       if (comment != null) {
553         String commentTextToInsert = "\n\nAttached comment from " + from_name + ":\n" + comment;
554         try {
555           content=StringRoutines.performRegularExpressionReplacement(content,"!COMMENT!",commentTextToInsert);
556         }
557         catch (Throwable e){
558           throw new ServletModuleFailure("Problem doing regular expression replacement " + e.toString(), e);
559         }
560       }
561       else{
562         try {
563           content=StringRoutines.performRegularExpressionReplacement(content,"!COMMENT!","");
564         }
565         catch (Throwable e){
566           throw new ServletModuleFailure("Problem doing regular expression replacement " + e.toString(), e);
567         }
568       }
569
570       SMTPClient client=new SMTPClient();
571       try {
572         int reply;
573         client.connect(configuration.getString("ServletModule.OpenIndy.SMTPServer"));
574
575         reply = client.getReplyCode();
576
577         if (!SMTPReply.isPositiveCompletion(reply)) {
578           client.disconnect();
579           throw new ServletModuleExc("SMTP server refused connection.");
580         }
581
582         client.sendSimpleMessage(configuration.getString("ServletModule.OpenIndy.EmailIsFrom"), to, content);
583
584         client.disconnect();
585         //mission accomplished
586         deliver(req, res, mergeData, sentMailTemplate);
587       }
588       catch(IOException e) {
589         if(client.isConnected()) {
590           try {
591             client.disconnect();
592           } catch(IOException f) {
593             // do nothing
594           }
595         }
596         throw new ServletModuleFailure(e);
597       }
598     }
599   }
600
601
602   /*
603    * Method for querying a lucene index
604    */
605   public void search(HttpServletRequest req, HttpServletResponse res)
606       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
607     try {
608       int increment=10;
609
610       HttpSession session = req.getSession(false);
611
612       String queryString="";
613
614       SimpleHash mergeData = new SimpleHash();
615
616       KeywordSearchTerm dateTerm = new KeywordSearchTerm("date_formatted","search_date","webdb_create_formatted","webdb_create_formatted","webdb_create_formatted");
617       UnIndexedSearchTerm whereTerm = new UnIndexedSearchTerm("","","","where","where");
618       TextSearchTerm creatorTerm = new TextSearchTerm("creator","search_creator","creator","creator","creator");
619       TextSearchTerm titleTerm = new TextSearchTerm("title","search_content","title","title","title");
620       TextSearchTerm descriptionTerm =  new TextSearchTerm("description","search_content","description","description","description");
621       ContentSearchTerm contentTerm = new ContentSearchTerm("content_data","search_content","content","","");
622       TopicSearchTerm topicTerm = new TopicSearchTerm();
623       ImagesSearchTerm imagesTerm = new ImagesSearchTerm();
624       AudioSearchTerm audioTerm = new AudioSearchTerm();
625       VideoSearchTerm videoTerm = new VideoSearchTerm();
626
627       //make the query available to subsequent iterations
628
629       for (Enumeration theParams = req.getParameterNames(); theParams.hasMoreElements() ;) {
630         String pName=(String)theParams.nextElement();
631         if (pName.startsWith("search_")){
632           mergeData.put(pName,new SimpleScalar(req.getParameter(pName)));
633         }
634       }
635
636       try{
637         mergeData.put("topics", themenModule.getTopicsAsSimpleList());
638       }
639       catch(ModuleException e) {
640         logger.debug("Can't get topics: " + e.toString());
641       }
642
643       String searchBackValue = req.getParameter("search_back");
644       String searchForwardValue = req.getParameter("search_forward");
645
646       if (searchBackValue != null){
647         int totalHits = ((Integer) session.getAttribute("numberOfHits")).intValue();
648         int newPosition=((Integer)session.getAttribute("positionInResults")).intValue()-increment;
649         if (newPosition<0)
650           newPosition=0;
651         if (newPosition >= totalHits)
652           newPosition=totalHits-1;
653         session.setAttribute("positionInResults",new Integer(newPosition));
654       }
655       else {
656         if (searchForwardValue != null){
657           int totalHits = ((Integer) session.getAttribute("numberOfHits")).intValue();
658           int newPosition=((Integer)session.getAttribute("positionInResults")).intValue()+increment;
659           if (newPosition<0)
660             newPosition=0;
661           if (newPosition >= totalHits)
662             newPosition=totalHits-1;
663
664           session.setAttribute("positionInResults",new Integer(newPosition));
665         }
666         else {
667           String indexPath=configuration.getString("IndexPath");
668
669
670           String creatorFragment = creatorTerm.makeTerm(req);
671           if (creatorFragment != null){
672             queryString = queryString + " +" + creatorFragment;
673           }
674
675           // search title, description, and content for something
676           // the contentTerm uses param "search_boolean" to combine its terms
677           String contentFragment = contentTerm.makeTerm(req);
678           if (contentFragment != null){
679             logger.debug("contentFragment: " + contentFragment);
680             queryString = queryString + " +" + contentFragment;
681           }
682
683           String topicFragment = topicTerm.makeTerm(req);
684           if (topicFragment != null){
685             queryString = queryString + " +" + topicFragment;
686           }
687
688           String imagesFragment = imagesTerm.makeTerm(req);
689           if (imagesFragment != null){
690             queryString = queryString + " +" + imagesFragment;
691           }
692
693           String audioFragment = audioTerm.makeTerm(req);
694           if (audioFragment != null){
695             queryString = queryString + " +" + audioFragment;
696           }
697
698           String videoFragment = videoTerm.makeTerm(req);
699           if (videoFragment != null){
700             queryString = queryString + " +" + videoFragment;
701           }
702
703           if (queryString == null || queryString == ""){
704             queryString = "";
705           }
706           else{
707             try{
708               Searcher searcher = null;
709               try {
710                 searcher = new IndexSearcher(indexPath);
711               }
712               catch(IOException e) {
713                 logger.debug("Can't open indexPath: " + indexPath);
714                 throw new ServletModuleExc("Problem with Search Index! : "+ e.toString());
715               }
716
717               Query query = null;
718               try {
719                 query = QueryParser.parse(queryString, "content", new StandardAnalyzer());
720               }
721               catch(Exception e) {
722                 searcher.close();
723                 logger.debug("Query don't parse: " + queryString);
724                 throw new ServletModuleExc("Problem with Query String! (was '"+queryString+"')");
725               }
726
727               Hits hits = null;
728               try {
729                 hits = searcher.search(query);
730               }
731               catch(IOException e) {
732                 searcher.close();
733                 logger.debug("Can't get hits: " + e.toString());
734                 throw new ServletModuleExc("Problem getting hits!");
735               }
736
737               int start = 0;
738               int end = hits.length();
739
740               String sortBy=req.getParameter("search_sort");
741               if (sortBy == null || sortBy.equals("")){
742                 throw new ServletModuleExc("Please let me sort by something!(missing search_sort)");
743               }
744
745               // here is where the documents will go for storage across sessions
746               ArrayList theDocumentsSorted = new ArrayList();
747
748               if (sortBy.equals("score")){
749                 for(int i = start; i < end; i++) {
750                   theDocumentsSorted.add(hits.doc(i));
751                 }
752               }
753               else{
754                 // then we'll sort by date!
755                 Map dateToPosition = new HashMap(end,1.0F); //we know how big it will be
756                 for(int i = start; i < end; i++) {
757                   String creationDate=(hits.doc(i)).get("creationDate");
758                   // do a little dance in case two contents created at the same second!
759                   if (dateToPosition.containsKey(creationDate)){
760                     ((ArrayList) (dateToPosition.get(creationDate))).add(new Integer(i));
761                   }
762                   else{
763                     ArrayList thePositions = new ArrayList();
764                     thePositions.add(new Integer(i));
765                     dateToPosition.put(creationDate,thePositions);
766                   }
767                 }
768                 Set keys = dateToPosition.keySet();
769                 ArrayList keyList= new ArrayList(keys);
770                 Collections.sort(keyList);
771                 if (sortBy.equals("date_desc")){
772                   Collections.reverse(keyList);
773                 }
774                 else{
775                   if (!sortBy.equals("date_asc")){
776                     throw new ServletModuleExc("don't know how to sort by: "+ sortBy);
777                   }
778                 }
779                 ListIterator keyTraverser = keyList.listIterator();
780                 while (keyTraverser.hasNext()){
781                   ArrayList positions = (ArrayList)dateToPosition.get((keyTraverser.next()));
782                   ListIterator positionsTraverser=positions.listIterator();
783                   while (positionsTraverser.hasNext()){
784                     theDocumentsSorted.add(hits.doc(((Integer)(positionsTraverser.next())).intValue()));
785                   }
786                 }
787               }
788
789               try{
790                 searcher.close();
791               }
792               catch (IOException e){
793                 logger.debug("Can't close searcher: " + e.toString());
794                 throw new ServletModuleFailure("Problem closing searcher(normal):" + e.getMessage(), e);
795               }
796
797
798               session.removeAttribute("numberOfHits");
799               session.removeAttribute("theDocumentsSorted");
800               session.removeAttribute("positionInResults");
801
802               session.setAttribute("numberOfHits",new Integer(end));
803               session.setAttribute("theDocumentsSorted",theDocumentsSorted);
804               session.setAttribute("positionInResults",new Integer(0));
805
806             }
807             catch (IOException e){
808               logger.debug("Can't close searcher: " + e.toString());
809               throw new ServletModuleFailure("Problem closing searcher: " + e.getMessage(), e);
810             }
811           }
812         }
813       }
814
815       try {
816         ArrayList theDocs = (ArrayList)session.getAttribute("theDocumentsSorted");
817         if (theDocs != null){
818
819           mergeData.put("numberOfHits", ((Integer)session.getAttribute("numberOfHits")).toString());
820           SimpleList theHits = new SimpleList();
821           int pIR=((Integer)session.getAttribute("positionInResults")).intValue();
822           int terminus;
823           int numHits=((Integer)session.getAttribute("numberOfHits")).intValue();
824
825           if (!(pIR+increment>=numHits)){
826             mergeData.put("hasNext","y");
827           }
828           if (pIR>0){
829             mergeData.put("hasPrevious","y");
830           }
831
832           if ((pIR+increment)>numHits){
833             terminus=numHits;
834           }
835           else {
836             terminus=pIR+increment;
837           }
838           for(int i = pIR; i < terminus; i++) {
839             SimpleHash h = new SimpleHash();
840             Document theHit = (Document)theDocs.get(i);
841             whereTerm.returnMeta(h,theHit);
842             creatorTerm.returnMeta(h,theHit);
843             titleTerm.returnMeta(h,theHit);
844             descriptionTerm.returnMeta(h,theHit);
845             dateTerm.returnMeta(h,theHit);
846             imagesTerm.returnMeta(h,theHit);
847             audioTerm.returnMeta(h,theHit);
848             videoTerm.returnMeta(h,theHit);
849             theHits.add(h);
850           }
851           mergeData.put("hits",theHits);
852         }
853       }
854       catch (Throwable e) {
855         logger.error("Can't iterate over hits: " + e.toString());
856
857         throw new ServletModuleFailure("Problem getting hits: " + e.getMessage(), e);
858       }
859
860       mergeData.put("queryString",queryString);
861       deliver(req,res,mergeData,searchResultsTemplate);
862     }
863     catch (NullPointerException n){
864       throw new ServletModuleFailure("Null Pointer: "+n.toString(), n);
865     }
866   }
867
868   /*
869    * Method for dynamically generating a pdf from a fo file
870    */
871   public void getpdf(HttpServletRequest req, HttpServletResponse res)
872       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
873     String ID_REQUEST_PARAM = "id";
874     String language = req.getParameter("language");
875     String generateFO=configuration.getString("GenerateFO");
876     String generatePDF=configuration.getString("GeneratePDF");
877
878
879     //don't do anything if we are not making FO files, or if we are
880     //pregenerating PDF's
881     if (generateFO.equals("yes") && generatePDF.equals("no")){
882       //fop complains unless you do the logging this way
883       org.apache.log.Logger log = null;
884       Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
885       log = hierarchy.getLoggerFor("fop");
886       log.setPriority(Priority.WARN);
887
888       String producerStorageRoot=configuration.getString("Producer.StorageRoot");
889       String producerDocRoot=configuration.getString("Producer.DocRoot");
890       //      String templateDir=MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
891       String xslSheet=configuration.getString("Producer.HTML2FOStyleSheet");
892       try {
893         String idParam = req.getParameter(ID_REQUEST_PARAM);
894         if (idParam != null) {
895           EntityContent contentEnt =
896             (EntityContent)contentModule.getById(idParam);
897           String publishPath = StringUtil.webdbDate2path(contentEnt.getValue("date"));
898           String foFile;
899
900           if (language == null){
901             foFile = producerStorageRoot + producerDocRoot + "/"
902               + publishPath  + idParam + ".fo";
903           }
904           else{
905             foFile = producerStorageRoot + producerDocRoot + "/"
906               + language + publishPath  + idParam + ".fo";
907           }
908           logger.debug("USING FILES" + foFile + " and " + xslSheet);
909           XSLTInputHandler input = new XSLTInputHandler(new File(foFile),
910                                                         new File(xslSheet));
911
912           ByteArrayOutputStream out = new ByteArrayOutputStream();
913           res.setContentType("application/pdf");
914
915           Driver driver = new Driver();
916           driver.setLogger(log);
917           driver.setRenderer(Driver.RENDER_PDF);
918           driver.setOutputStream(out);
919           driver.render(input.getParser(), input.getInputSource());
920
921           byte[] content = out.toByteArray();
922           res.setContentLength(content.length);
923           res.getOutputStream().write(content);
924           res.getOutputStream().flush();
925         }
926         else {
927           throw new ServletModuleUserExc("Missing id parameter.");
928         }
929       }
930       catch (Exception ex) {
931         logger.error(ex.toString());
932         throw new ServletModuleFailure(ex);
933       }
934     } else {
935       throw new ServletModuleExc("Can't generate a PDF because the config tells me not to.");
936     }
937   }
938
939   private void _throwBadContentType (String fileName, String contentType)
940       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
941
942     logger.error("Wrong file type uploaded!: " + fileName+" "
943                           +contentType);
944     throw new ServletModuleUserExc("The file you uploaded is of the "
945                                          +"following mime-type: "+contentType
946                                          +", we do not support this mime-type. "
947                                          +"Error One or more files of unrecognized type. Sorry");
948   }
949
950   protected String createOneTimePasswd(){
951     Random r = new Random();
952     int random = r.nextInt();
953     long l = System.currentTimeMillis();
954     l = (l*l*l*l)/random;
955     if(l<0) l = l * -1;
956     String returnString = ""+l;
957     return returnString.substring(5);
958   }
959
960
961   /* this is an overwritten method of ServletModule in order
962      to use different bundles for open and admin */
963   public void deliver(HttpServletRequest req, HttpServletResponse res,
964                       TemplateModelRoot rtm, TemplateModelRoot popups,
965                       String templateFilename) throws ServletModuleFailure
966   {
967     if (rtm == null) rtm = new SimpleHash();
968     try {
969       PrintWriter out = res.getWriter();
970       HTMLTemplateProcessor.process(res, templateFilename, rtm, popups, out,
971                                     getLocale(req), "bundles.open");
972       out.close();
973     }
974     catch (Throwable e) {
975       throw new ServletModuleFailure(e);
976     }
977   }
978 }
979
980
981