introduced some customization for the content list in admin
[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.*;
35 import java.lang.*;
36 import java.sql.*;
37 import java.util.*;
38 import java.net.*;
39 import java.lang.reflect.*;
40 import javax.servlet.*;
41 import javax.servlet.http.*;
42
43 import freemarker.template.*;
44 import com.oreilly.servlet.multipart.*;
45 import com.oreilly.servlet.*;
46
47 import org.xml.sax.InputSource;
48 import org.xml.sax.XMLReader;
49
50 import org.apache.fop.apps.Driver;
51 import org.apache.fop.apps.Version;
52 import org.apache.fop.apps.XSLTInputHandler;
53
54 import org.apache.lucene.analysis.standard.StandardAnalyzer;
55 import org.apache.lucene.search.*;
56 import org.apache.lucene.document.Document;
57 import org.apache.lucene.document.Field;
58 import org.apache.lucene.analysis.standard.*;
59 import org.apache.lucene.queryParser.*;
60
61 import org.apache.log.*;
62
63 import mir.servlet.*;
64 import mir.module.*;
65 import mir.misc.*;
66 import mir.entity.*;
67 import mir.storage.*;
68 import mir.media.*;
69 import mir.log.*;
70
71 import mircoders.entity.*;
72 import mircoders.storage.*;
73 import mircoders.module.*;
74 import mircoders.producer.*;
75 import mircoders.media.MediaRequest;
76 import mircoders.global.*;
77 import mircoders.localizer.*;
78 import mircoders.search.*;
79
80 /*
81  *  ServletModuleOpenIndy -
82  *   is the open-access-servlet, which is responsible for
83  *    adding comments to articles &
84  *    open-postings to the newswire
85  *
86  * @author mir-coders group
87  * @version $Id: ServletModuleOpenIndy.java,v 1.48 2002/11/30 19:45:57 zapata Exp $
88  *
89  */
90
91 public class ServletModuleOpenIndy extends ServletModule
92 {
93
94   private String        commentFormTemplate, commentFormDoneTemplate,
95     commentFormDupeTemplate;
96   private String        postingFormTemplate, postingFormDoneTemplate,
97     postingFormDupeTemplate;
98   private String        searchResultsTemplate;
99   private ModuleContent contentModule;
100   private ModuleComment commentModule;
101   private ModuleImages  imageModule;
102   private ModuleTopics  themenModule;
103   private String        directOp ="yes";
104   private String        passwdProtection ="yes";
105   // Singelton / Kontruktor
106   private static ServletModuleOpenIndy instance = new ServletModuleOpenIndy();
107   public static ServletModule getInstance() { return instance; }
108
109   private ServletModuleOpenIndy() {
110     try {
111       logger = new LoggerWrapper("ServletModule.OpenIndy");
112
113       commentFormTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentTemplate");
114       commentFormDoneTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentDoneTemplate");
115       commentFormDupeTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentDupeTemplate");
116       postingFormTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingTemplate");
117       postingFormDoneTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingDoneTemplate");
118       postingFormDupeTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingDupeTemplate");
119       searchResultsTemplate = MirConfig.getProp("ServletModule.OpenIndy.SearchResultsTemplate");
120       directOp = MirConfig.getProp("DirectOpenposting").toLowerCase();
121       passwdProtection = MirConfig.getProp("PasswdProtection").toLowerCase();
122       mainModule = new ModuleComment(DatabaseComment.getInstance());
123       contentModule = new ModuleContent(DatabaseContent.getInstance());
124       themenModule = new ModuleTopics(DatabaseTopics.getInstance());
125       imageModule = new ModuleImages(DatabaseImages.getInstance());
126       defaultAction="addposting";
127
128     }
129     catch (StorageObjectException e) {
130       logger.error("servletmoduleopenindy could not be initialized: " + e.getMessage());
131     }
132   }
133
134
135   /**
136    *  Method for making a comment
137    */
138
139   public void addcomment(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
140   {
141     String aid = req.getParameter("aid"); // the article id the comment will belong to
142     String language = req.getParameter("language");
143
144     if (aid!=null && !aid.equals(""))
145       {
146         SimpleHash mergeData = new SimpleHash();
147
148         // onetimepasswd
149         if(passwdProtection.equals("yes")){
150           String passwd = this.createOneTimePasswd();
151           System.out.println(passwd);
152           HttpSession session = req.getSession(false);
153           session.setAttribute("passwd",passwd);
154           mergeData.put("passwd", passwd);
155         }
156
157         if (language!=null) {
158           HttpSession session = req.getSession(false);
159           session.setAttribute("Locale", new Locale(language, ""));
160           session.setAttribute("passwd",language);
161         }
162
163         mergeData.put("aid", aid);
164         deliver(req, res, mergeData, commentFormTemplate);
165       }
166     else throw new ServletModuleException("aid not set!");
167   }
168
169   /**
170    *  Method for inserting a comment into the Database and delivering
171    *  the commentDone Page
172    */
173
174   public void inscomment(HttpServletRequest req, HttpServletResponse res)
175     throws ServletModuleException,ServletModuleUserException
176   {
177     String aid = req.getParameter("to_media"); // the article id the comment will belong to
178     if (aid!=null && !aid.equals(""))
179       {
180         // ok, collecting data from form
181         try {
182           HashMap withValues = getIntersectingValues(req, DatabaseComment.getInstance());
183
184           //no html in comments(for now)
185           for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
186             String k=(String)i.next();
187             String v=(String)withValues.get(k);
188
189             withValues.put(k,StringUtil.removeHTMLTags(v));
190           }
191           withValues.put("is_published","1");
192
193           //checking the onetimepasswd
194           if(passwdProtection.equals("yes")){
195             HttpSession session = req.getSession(false);
196             String sessionPasswd = (String)session.getAttribute("passwd");
197             if ( sessionPasswd == null){
198               throw new ServletModuleUserException("Lost password");
199             }
200             String passwd = req.getParameter("passwd");
201             if ( passwd == null || (!sessionPasswd.equals(passwd))) {
202               throw new ServletModuleUserException("Missing password");
203             }
204             session.invalidate();
205           }
206
207           // inserting into database
208           String id = mainModule.add(withValues);
209           logger.debug("id: "+id);
210           //insert was not successfull
211           if(id==null){
212             deliver(req, res, new SimpleHash(), commentFormDupeTemplate);
213           } else {
214             DatabaseContent.getInstance().setUnproduced("id="+aid);
215
216             try {
217               EntityComment comment = (EntityComment) DatabaseComment.getInstance().selectById(id);
218               MirGlobal.localizer().openPostings().afterCommentPosting(comment);
219             }
220             catch (Throwable t) {
221               throw new ServletModuleException(t.getMessage());
222             }
223           
224           
225           
226           }
227
228           // redirecting to url
229           // should implement back to article
230           SimpleHash mergeData = new SimpleHash();
231           deliver(req, res, mergeData, commentFormDoneTemplate);
232         }
233         catch (StorageObjectException e) { throw new ServletModuleException(e.toString());}
234         catch (ModuleException e) { throw new ServletModuleException(e.toString());}
235
236       }
237     else throw new ServletModuleException("aid not set!");
238
239   }
240
241   /**
242    *  Method for delivering the form-Page for open posting
243    */
244
245   public void addposting(HttpServletRequest req, HttpServletResponse res)
246     throws ServletModuleException {
247     SimpleHash mergeData = new SimpleHash();
248
249     // onetimepasswd
250     if(passwdProtection.equals("yes")){
251       String passwd = this.createOneTimePasswd();
252       System.out.println(passwd);
253       HttpSession session = req.getSession(false);
254       session.setAttribute("passwd",passwd);
255       mergeData.put("passwd", passwd);
256     }
257
258     String maxMedia = MirConfig.getProp("ServletModule.OpenIndy.MaxMediaUploadItems");
259     String numOfMedia = req.getParameter("medianum");
260     if(numOfMedia==null||numOfMedia.equals("")){
261       numOfMedia="1";
262     } else if(Integer.parseInt(numOfMedia) > Integer.parseInt(maxMedia)) {
263       numOfMedia = maxMedia;
264     }
265
266     int mediaNum = Integer.parseInt(numOfMedia);
267     SimpleList mediaFields = new SimpleList();
268     for(int i =0; i<mediaNum;i++){
269       Integer mNum = new Integer(i+1);
270       mediaFields.add(mNum.toString());
271     }
272     mergeData.put("medianum",numOfMedia);
273     mergeData.put("mediafields",mediaFields);
274
275
276     SimpleHash extraInfo = new SimpleHash();
277     try{
278       SimpleList popUpData = DatabaseLanguage.getInstance().getPopupData();
279       extraInfo.put("languagePopUpData", popUpData );
280       extraInfo.put("themenPopupData", themenModule.getTopicsAsSimpleList());
281
282       extraInfo.put("topics", themenModule.getTopicsList());
283
284     } 
285     catch (Exception e) {
286       logger.error("languagePopUpData or getTopicslist failed "+e.toString());
287       throw new ServletModuleException("OpenIndy -- failed getting language or topics: "+e.toString());
288     }
289
290
291
292     deliver(req, res, mergeData, extraInfo, postingFormTemplate);
293   }
294
295   /**
296    *  Method for inserting an open posting into the Database and delivering
297    *  the postingDone Page
298    */
299
300   public void insposting(HttpServletRequest req, HttpServletResponse res)
301     throws ServletModuleException, ServletModuleUserException
302   {
303     SimpleHash mergeData = new SimpleHash();
304     boolean setMedia=false;
305     boolean setTopic = false;
306
307     try {
308
309       WebdbMultipartRequest mp = null;
310       EntityList mediaList = null;
311       try {
312         // new MediaRequest, "1" is the id for the openPosting user
313         MediaRequest mediaReq = new MediaRequest("1", true, true);
314         mp = new WebdbMultipartRequest(req, (FileHandler)mediaReq);
315         mediaList = mediaReq.getEntityList();
316       } catch (FileHandlerUserException e) {
317         throw new ServletModuleUserException(e.getMsg());
318       }
319           
320       HashMap withValues = mp.getParameters();
321
322       //checking the onetimepasswd
323       if(passwdProtection.equals("yes")){
324         HttpSession session = req.getSession(false);
325         String sessionPasswd = (String)session.getAttribute("passwd");
326         if ( sessionPasswd == null){
327           throw new ServletModuleUserException("Lost password");
328         }
329         String passwd = (String)withValues.get("passwd");
330         if ( passwd == null || (!sessionPasswd.equals(passwd))) {
331           throw new ServletModuleUserException("Missing password");
332         }
333         session.invalidate();
334       }
335
336       if ((((String)withValues.get("title")).length() == 0) ||
337           (((String)withValues.get("description")).length() == 0) ||
338           (((String)withValues.get("content_data")).length() == 0))
339         throw new ServletModuleUserException("Missing field");
340
341       // call the routines that escape html
342
343       for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
344         String k=(String)i.next();
345         String v=(String)withValues.get(k);
346
347         if (k.equals("content_data")){
348           //this doesn't quite work yet, so for now, all html goes
349           //withValues.put(k,StringUtil.approveHTMLTags(v));
350           //withValues.put(k,StringUtil.removeHTMLTags(v));
351         } else {
352           withValues.put(k,StringUtil.removeHTMLTags(v));
353         }
354
355       }
356
357       withValues.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
358       withValues.put("publish_path", StringUtil.webdbDate2path((String)withValues.get("date")));
359       withValues.put("is_produced", "0");
360       // by default stuff is published, they can be un-published through the
361       // admin interface.
362       withValues.put("is_published","1");
363       // if op direct article-type == newswire
364       if (directOp.equals("yes")) withValues.put("to_article_type","1");
365
366       withValues.put("to_publisher","1");
367
368       // owner is openposting user
369       //      ML: this is not multi-language friendly and this can be done in a template
370       //      if (withValues.get("creator").toString().equals(""))
371       //        withValues.put("creator","Anonym");
372
373       // inserting  content into database
374       String cid = contentModule.add(withValues);
375       logger.debug("id: "+cid);
376       //insert was not successfull
377       if(cid==null){
378         //How do we know that it was not succesful cause of a
379         //dupe, what if it failed cause of "No space left on device"?
380         //Or is there something I am missing? Wouldn't it be better
381         //to have an explicit dupe check and then insert? I have no
382         //idea what I am talking about. this comment is in case
383         //I forget to explicitely ask. -mh
384         deliver(req, res, mergeData, postingFormDupeTemplate);
385       }
386
387       String[] to_topicsArr = mp.getParameterValues("to_topic");
388
389       if (to_topicsArr != null && to_topicsArr.length > 0) {
390         try{
391           DatabaseContentToTopics.getInstance().setTopics(cid,to_topicsArr);
392           setTopic = true;
393         } 
394         catch (Exception e) {
395           logger.error("setting content_x_topic failed");
396           contentModule.deleteById(cid);
397           throw new ServletModuleException("smod - openindy :: insposting: setting content_x_topic failed: "+e.toString());
398         } //end try
399       } //end if
400        
401       //if we're here all is ok... associate the media to the article
402       for(int i=0;i<mediaList.size();i++) {
403         Entity mediaEnt = (Entity)mediaList.elementAt(i);
404         DatabaseContentToMedia.getInstance().addMedia(cid,mediaEnt.getId());
405       }
406
407       try {
408         MirGlobal.localizer().openPostings().afterContentPosting(
409                                                                  (EntityContent)contentModule.getById(cid));
410       }
411       catch (Throwable t) {
412         throw new ServletModuleException(t.getMessage());
413       }
414     }
415     catch (FileHandlerException e) { throw new ServletModuleException("MediaException: "+ e.toString());}
416     catch (IOException e) { throw new ServletModuleException("IOException: "+ e.toString());}
417     catch (StorageObjectException e) { throw new ServletModuleException("StorageObjectException" + e.toString());}
418     catch (ModuleException e) { throw new ServletModuleException("ModuleException"+e.toString());}
419
420     deliver(req, res, mergeData, postingFormDoneTemplate);
421   }
422
423   /*
424    * Method for querying a lucene index
425    */
426   public void search(HttpServletRequest req, HttpServletResponse res)
427     throws ServletModuleException, ServletModuleUserException {
428     try {
429       int increment=10;
430
431       HttpSession session = req.getSession(false);
432
433       String queryString="";
434     
435       SimpleHash mergeData = new SimpleHash();
436     
437       KeywordSearchTerm dateTerm = new KeywordSearchTerm("date_formatted","search_date","webdb_create_formatted","webdb_create_formatted","webdb_create_formatted");
438       UnIndexedSearchTerm whereTerm = new UnIndexedSearchTerm("","","","where","where");
439       TextSearchTerm creatorTerm = new TextSearchTerm("creator","search_creator","creator","creator","creator");
440       TextSearchTerm titleTerm = new TextSearchTerm("title","search_content","title","title","title");
441       TextSearchTerm descriptionTerm =  new TextSearchTerm("description","search_content","description","description","description");
442       ContentSearchTerm contentTerm = new ContentSearchTerm("content_data","search_content","content","","");
443       TopicSearchTerm topicTerm = new TopicSearchTerm();
444       ImagesSearchTerm imagesTerm = new ImagesSearchTerm();
445       AudioSearchTerm audioTerm = new AudioSearchTerm();
446       VideoSearchTerm videoTerm = new VideoSearchTerm();
447     
448       //make the query available to subsequent iterations
449
450       for (Enumeration theParams = req.getParameterNames(); theParams.hasMoreElements() ;) {
451         String pName=(String)theParams.nextElement();
452         if (pName.startsWith("search_")){
453           mergeData.put(pName,new SimpleScalar(req.getParameter(pName)));
454         }
455       }
456     
457       try{
458         mergeData.put("topics", themenModule.getTopicsAsSimpleList());
459       }
460       catch(ModuleException e) {
461         logger.debug("Can't get topics: " + e.toString());
462       }
463     
464       String searchSubmitValue = req.getParameter("search_submit");
465     
466       if (searchSubmitValue != null && searchSubmitValue.equals("Back")){
467         int totalHits = ((Integer) session.getAttribute("numberOfHits")).intValue();
468         int newPosition=((Integer)session.getAttribute("positionInResults")).intValue()-increment;
469         if (newPosition < 0 || newPosition >= totalHits){
470           throw new ServletModuleUserException("newPosition: index out bounds, value was:"+(new Integer(newPosition)).toString());
471         }
472         session.setAttribute("positionInResults",new Integer(newPosition));
473       
474       }
475       else {
476         if (searchSubmitValue != null && searchSubmitValue.equals("Forward")){
477           int totalHits = ((Integer) session.getAttribute("numberOfHits")).intValue();
478           int newPosition=((Integer)session.getAttribute("positionInResults")).intValue()+increment;
479           if (newPosition < 0 || newPosition >= totalHits){
480             throw new ServletModuleUserException("newPosition: index out bounds, value was:"+(new Integer(newPosition)).toString());
481           }
482           session.setAttribute("positionInResults",new Integer(newPosition));
483         
484         }
485         else {
486           String indexPath=MirConfig.getProp("IndexPath");
487                 
488         
489           String creatorFragment = creatorTerm.makeTerm(req);
490           if (creatorFragment != null){
491             queryString = queryString + " +" + creatorFragment;
492           }
493         
494           // search title, description, and content for something
495           // the contentTerm uses param "search_boolean" to combine its terms
496           String contentFragment = contentTerm.makeTerm(req);
497           if (contentFragment != null){
498             logger.debug("contentFragment: " + contentFragment);
499             queryString = queryString + " +" + contentFragment;
500           }
501         
502           String topicFragment = topicTerm.makeTerm(req);
503           if (topicFragment != null){
504             queryString = queryString + " +" + topicFragment;
505           }
506         
507           String imagesFragment = imagesTerm.makeTerm(req);
508           if (imagesFragment != null){
509             queryString = queryString + " +" + imagesFragment;
510           }
511         
512           String audioFragment = audioTerm.makeTerm(req);
513           if (audioFragment != null){
514             queryString = queryString + " +" + audioFragment;
515           }
516         
517           String videoFragment = videoTerm.makeTerm(req);
518           if (videoFragment != null){
519             queryString = queryString + " +" + videoFragment;
520           }
521         
522           if (queryString == null || queryString == ""){
523             queryString = "";
524           }
525           else{
526             try{
527               Searcher searcher = null;
528               try {
529                 searcher = new IndexSearcher(indexPath);
530               } 
531               catch(IOException e) {
532                 logger.debug("Can't open indexPath: " + indexPath);
533                 throw new ServletModuleUserException("Problem with Search Index! : "+ e.toString());
534               }
535             
536               Query query = null;
537               try {
538                 query = QueryParser.parse(queryString, "content", new StandardAnalyzer());
539               } 
540               catch(Exception e) {
541                 searcher.close();
542                 logger.debug("Query don't parse: " + queryString);
543                 throw new ServletModuleUserException("Problem with Query String! (was '"+queryString+"')");
544               }
545             
546               Hits hits = null;
547               try {
548                 hits = searcher.search(query);
549               } 
550               catch(IOException e) {
551                 searcher.close();
552                 logger.debug("Can't get hits: " + e.toString());
553                 throw new ServletModuleUserException("Problem getting hits!");
554               }
555           
556               int start = 0;
557               int end = hits.length();
558           
559               String sortBy=req.getParameter("search_sort");
560               if (sortBy == null || sortBy.equals("")){
561                 throw new ServletModuleUserException("Please let me sort by something!(missing search_sort)");
562               }
563           
564               // here is where the documents will go for storage across sessions
565               ArrayList theDocumentsSorted = new ArrayList();
566           
567               if (sortBy.equals("score")){
568                 for(int i = start; i < end; i++) {
569                   theDocumentsSorted.add(hits.doc(i));
570                 }
571               }
572               else{
573                 // then we'll sort by date!
574                 HashMap dateToPosition = new HashMap(end,1.0F); //we know how big it will be
575                 for(int i = start; i < end; i++) {
576                   String creationDate=(hits.doc(i)).get("creationDate");
577                   // do a little dance in case two contents created at the same second!
578                   if (dateToPosition.containsKey(creationDate)){
579                     ((ArrayList) (dateToPosition.get(creationDate))).add(new Integer(i));
580                   }
581                   else{ 
582                     ArrayList thePositions = new ArrayList();
583                     thePositions.add(new Integer(i));
584                     dateToPosition.put(creationDate,thePositions);
585                   }
586                 }
587                 Set keys = dateToPosition.keySet();
588                 ArrayList keyList= new ArrayList(keys);
589                 Collections.sort(keyList);
590                 if (sortBy.equals("date_desc")){
591                   Collections.reverse(keyList);     
592                 }
593                 else{
594                   if (!sortBy.equals("date_asc")){
595                     throw new ServletModuleUserException("don't know how to sort by: "+ sortBy);
596                   }
597                 }
598                 ListIterator keyTraverser = keyList.listIterator();
599                 while (keyTraverser.hasNext()){
600                   ArrayList positions = (ArrayList)dateToPosition.get((keyTraverser.next()));
601                   ListIterator positionsTraverser=positions.listIterator();
602                   while (positionsTraverser.hasNext()){
603                     theDocumentsSorted.add(hits.doc(((Integer)(positionsTraverser.next())).intValue()));
604                   }
605                 }
606               }
607               
608               try{
609                 searcher.close();
610               }
611               catch (IOException e){
612                 logger.debug("Can't close searcher: " + e.toString());
613                 throw new ServletModuleUserException("Problem closing searcher(normal)!");
614               }
615                       
616               
617               session.removeAttribute("numberOfHits");
618               session.removeAttribute("theDocumentsSorted");
619               session.removeAttribute("positionInResults");
620           
621               session.setAttribute("numberOfHits",new Integer(end));
622               session.setAttribute("theDocumentsSorted",theDocumentsSorted);
623               session.setAttribute("positionInResults",new Integer(0));
624           
625             }
626             catch (IOException e){
627               logger.debug("Can't close searcher: " + e.toString());
628               throw new ServletModuleUserException("Problem closing searcher!");
629             }
630           }
631         }
632       }
633     
634       try {
635         ArrayList theDocs = (ArrayList)session.getAttribute("theDocumentsSorted"); 
636         if (theDocs != null){
637         
638           mergeData.put("numberOfHits", ((Integer)session.getAttribute("numberOfHits")).toString());
639           SimpleList theHits = new SimpleList();
640           int pIR=((Integer)session.getAttribute("positionInResults")).intValue();
641           int terminus;
642           int numHits=((Integer)session.getAttribute("numberOfHits")).intValue();
643         
644           if (!(pIR+increment>=numHits)){
645             mergeData.put("hasNext","y");
646           }
647           if (pIR-increment>=0){
648             mergeData.put("hasPrevious","y");
649           }
650         
651           if ((pIR+increment)>numHits){
652             terminus=numHits;
653           }
654           else {
655             terminus=pIR+increment;
656           }
657           for(int i = pIR; i < terminus; i++) {
658             SimpleHash h = new SimpleHash();
659             Document theHit = (Document)theDocs.get(i);
660             whereTerm.returnMeta(h,theHit);
661             creatorTerm.returnMeta(h,theHit);
662             titleTerm.returnMeta(h,theHit);
663             descriptionTerm.returnMeta(h,theHit);
664             dateTerm.returnMeta(h,theHit);
665             imagesTerm.returnMeta(h,theHit);
666             audioTerm.returnMeta(h,theHit);
667             videoTerm.returnMeta(h,theHit);  
668             theHits.add(h);
669           }
670           mergeData.put("hits",theHits);
671         }
672       }
673       catch (Exception e) {
674         logger.debug("Can't iterate over hits: " + e.toString());
675         throw new ServletModuleUserException("Problem getting hits!");
676       }
677     
678       mergeData.put("queryString",queryString);
679       deliver(req,res,mergeData,searchResultsTemplate);
680     }
681     catch (NullPointerException n){
682       n.printStackTrace();
683       throw new ServletModuleUserException("Null Pointer"+n.toString());
684     }
685   }
686
687   /*
688    * Method for dynamically generating a pdf from a fo file
689    */
690   public void getpdf(HttpServletRequest req, HttpServletResponse res)
691     throws ServletModuleException, ServletModuleUserException {
692     String ID_REQUEST_PARAM = "id";
693     
694     String generateFO=MirConfig.getProp("GenerateFO");
695     String generatePDF=MirConfig.getProp("GeneratePDF");
696
697     //don't do anything if we are not making FO files, or if we are
698     //pregenerating PDF's
699     if (generateFO.equals("yes") && generatePDF.equals("no")){
700       //fop complains unless you do the logging this way
701       org.apache.log.Logger log = null;
702       Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
703       log = hierarchy.getLoggerFor("fop");
704       log.setPriority(Priority.WARN);
705     
706       String producerStorageRoot=MirConfig.getProp("Producer.StorageRoot");
707       String producerDocRoot=MirConfig.getProp("Producer.DocRoot");
708       String templateDir=MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
709       String xslSheet=templateDir + "/" 
710         + MirConfig.getProp("Producer.PrintableContent.html2foStyleSheetName");
711       try {
712         String idParam = req.getParameter(ID_REQUEST_PARAM);
713         if (idParam != null) {
714           EntityContent contentEnt =
715             (EntityContent)contentModule.getById(idParam);
716           String publishPath = contentEnt.getValue("publish_path");
717           String foFile = producerStorageRoot + producerDocRoot + "/" 
718             + publishPath + "/" + idParam + ".fo";
719           XSLTInputHandler input = new XSLTInputHandler(new File(foFile), 
720                                                         new File(xslSheet));
721           
722           ByteArrayOutputStream out = new ByteArrayOutputStream();
723           res.setContentType("application/pdf");
724
725           Driver driver = new Driver();
726           driver.setLogger(log);
727           driver.setRenderer(Driver.RENDER_PDF);
728           driver.setOutputStream(out);
729           driver.render(input.getParser(), input.getInputSource());
730
731           byte[] content = out.toByteArray();
732           res.setContentLength(content.length);
733           res.getOutputStream().write(content);
734           res.getOutputStream().flush();
735         } else {
736           throw new ServletModuleUserException("Missing id parameter.");
737         }
738       } catch (Exception ex) {
739         throw new ServletModuleException(ex.toString());
740       }
741     } else {
742       throw new ServletModuleUserException("Can't generate a PDF because the config tells me not to.");
743     }
744   }
745   
746   private void _throwBadContentType (String fileName, String contentType)
747     throws ServletModuleUserException {
748
749     logger.error("Wrong file type uploaded!: " + fileName+" "
750                           +contentType);
751     throw new ServletModuleUserException("The file you uploaded is of the "
752                                          +"following mime-type: "+contentType
753                                          +", we do not support this mime-type. "
754                                          +"Error One or more files of unrecognized type. Sorry");
755   }
756
757   protected String createOneTimePasswd(){
758     Random r = new Random();
759     int random = r.nextInt();
760     long l = System.currentTimeMillis();
761     l = (l*l*l*l)/random;
762     if(l<0) l = l * -1;
763     String returnString = ""+l;
764     return returnString.substring(5);
765   }
766
767
768   /* this is an overwritten method of ServletModule in order
769      to use different bundles for open and admin */
770   public void deliver(HttpServletRequest req, HttpServletResponse res,
771                       TemplateModelRoot rtm, TemplateModelRoot popups,
772                       String templateFilename)
773     throws ServletModuleException {
774     if (rtm == null) rtm = new SimpleHash();
775     try {
776       PrintWriter out = res.getWriter();
777       HTMLTemplateProcessor.process(res, templateFilename, rtm, popups, out,
778                                     getLocale(req), "bundles.open");
779       out.close();
780     }   catch (HTMLParseException e) {
781       throw new ServletModuleException(e.toString());
782     } catch (IOException e) {
783       throw new ServletModuleException(e.toString());
784     }
785   }
786 }
787
788
789