c044790372cdf6c3c1b13e4257a7f4ffc29ef738
[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.46 2002/11/29 13:43:42 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.Logfile");
112       commentFormTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentTemplate");
113       commentFormDoneTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentDoneTemplate");
114       commentFormDupeTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentDupeTemplate");
115       postingFormTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingTemplate");
116       postingFormDoneTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingDoneTemplate");
117       postingFormDupeTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingDupeTemplate");
118       searchResultsTemplate = MirConfig.getProp("ServletModule.OpenIndy.SearchResultsTemplate");
119       directOp = MirConfig.getProp("DirectOpenposting").toLowerCase();
120       passwdProtection = MirConfig.getProp("PasswdProtection").toLowerCase();
121       mainModule = new ModuleComment(DatabaseComment.getInstance());
122       contentModule = new ModuleContent(DatabaseContent.getInstance());
123       themenModule = new ModuleTopics(DatabaseTopics.getInstance());
124       imageModule = new ModuleImages(DatabaseImages.getInstance());
125       defaultAction="addposting";
126
127     }
128     catch (StorageObjectException e) {
129       logger.error("servletmoduleopenindy could not be initialized");
130     }
131   }
132
133
134   /**
135    *  Method for making a comment
136    */
137
138   public void addcomment(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
139   {
140     String aid = req.getParameter("aid"); // the article id the comment will belong to
141     String language = req.getParameter("language");
142
143     if (aid!=null && !aid.equals(""))
144       {
145         SimpleHash mergeData = new SimpleHash();
146
147         // onetimepasswd
148         if(passwdProtection.equals("yes")){
149           String passwd = this.createOneTimePasswd();
150           System.out.println(passwd);
151           HttpSession session = req.getSession(false);
152           session.setAttribute("passwd",passwd);
153           mergeData.put("passwd", passwd);
154         }
155
156         if (language!=null) {
157           HttpSession session = req.getSession(false);
158           session.setAttribute("Locale", new Locale(language, ""));
159           session.setAttribute("passwd",language);
160         }
161
162         mergeData.put("aid", aid);
163         deliver(req, res, mergeData, commentFormTemplate);
164       }
165     else throw new ServletModuleException("aid not set!");
166   }
167
168   /**
169    *  Method for inserting a comment into the Database and delivering
170    *  the commentDone Page
171    */
172
173   public void inscomment(HttpServletRequest req, HttpServletResponse res)
174     throws ServletModuleException,ServletModuleUserException
175   {
176     String aid = req.getParameter("to_media"); // the article id the comment will belong to
177     if (aid!=null && !aid.equals(""))
178       {
179         // ok, collecting data from form
180         try {
181           HashMap withValues = getIntersectingValues(req, DatabaseComment.getInstance());
182
183           //no html in comments(for now)
184           for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
185             String k=(String)i.next();
186             String v=(String)withValues.get(k);
187
188             withValues.put(k,StringUtil.removeHTMLTags(v));
189           }
190           withValues.put("is_published","1");
191
192           //checking the onetimepasswd
193           if(passwdProtection.equals("yes")){
194             HttpSession session = req.getSession(false);
195             String sessionPasswd = (String)session.getAttribute("passwd");
196             if ( sessionPasswd == null){
197               throw new ServletModuleUserException("Lost password");
198             }
199             String passwd = req.getParameter("passwd");
200             if ( passwd == null || (!sessionPasswd.equals(passwd))) {
201               throw new ServletModuleUserException("Missing password");
202             }
203             session.invalidate();
204           }
205
206           // inserting into database
207           String id = mainModule.add(withValues);
208           logger.debug("inscomment: id = "+id);
209           //insert was not successfull
210           if(id==null){
211             deliver(req, res, new SimpleHash(), commentFormDupeTemplate);
212           } else {
213             DatabaseContent.getInstance().setUnproduced("id="+aid);
214
215             try {
216               EntityComment comment = (EntityComment) DatabaseComment.getInstance().selectById(id);
217               MirGlobal.localizer().openPostings().afterCommentPosting(comment);
218             }
219             catch (Throwable t) {
220               throw new ServletModuleException(t.getMessage());
221             }
222
223
224
225           }
226
227           // redirecting to url
228           // should implement back to article
229           SimpleHash mergeData = new SimpleHash();
230           deliver(req, res, mergeData, commentFormDoneTemplate);
231         }
232         catch (StorageObjectException e) { throw new ServletModuleException(e.toString());}
233         catch (ModuleException e) { throw new ServletModuleException(e.toString());}
234
235       }
236     else throw new ServletModuleException("aid not set!");
237
238   }
239
240   /**
241    *  Method for delivering the form-Page for open posting
242    */
243
244   public void addposting(HttpServletRequest req, HttpServletResponse res)
245     throws ServletModuleException {
246     SimpleHash mergeData = new SimpleHash();
247
248     // onetimepasswd
249     if(passwdProtection.equals("yes")){
250       String passwd = this.createOneTimePasswd();
251       System.out.println(passwd);
252       HttpSession session = req.getSession(false);
253       session.setAttribute("passwd",passwd);
254       mergeData.put("passwd", passwd);
255     }
256
257     String maxMedia = MirConfig.getProp("ServletModule.OpenIndy.MaxMediaUploadItems");
258     String numOfMedia = req.getParameter("medianum");
259     if(numOfMedia==null||numOfMedia.equals("")){
260       numOfMedia="1";
261     } else if(Integer.parseInt(numOfMedia) > Integer.parseInt(maxMedia)) {
262       numOfMedia = maxMedia;
263     }
264
265     int mediaNum = Integer.parseInt(numOfMedia);
266     SimpleList mediaFields = new SimpleList();
267     for(int i =0; i<mediaNum;i++){
268       Integer mNum = new Integer(i+1);
269       mediaFields.add(mNum.toString());
270     }
271     mergeData.put("medianum",numOfMedia);
272     mergeData.put("mediafields",mediaFields);
273
274
275     SimpleHash extraInfo = new SimpleHash();
276     try{
277       SimpleList popUpData = DatabaseLanguage.getInstance().getPopupData();
278       extraInfo.put("languagePopUpData", popUpData );
279       extraInfo.put("themenPopupData", themenModule.getTopicsAsSimpleList());
280
281       extraInfo.put("topics", themenModule.getTopicsList());
282
283     }
284     catch (Exception e) {
285       logger.error("languagePopUpData or getTopicslist failed " + e.toString());
286       throw new ServletModuleException("OpenIndy -- failed getting language or topics: "+e.toString());
287     }
288
289
290
291     deliver(req, res, mergeData, extraInfo, postingFormTemplate);
292   }
293
294   /**
295    *  Method for inserting an open posting into the Database and delivering
296    *  the postingDone Page
297    */
298
299   public void insposting(HttpServletRequest req, HttpServletResponse res)
300     throws ServletModuleException, ServletModuleUserException
301   {
302     SimpleHash mergeData = new SimpleHash();
303     boolean setMedia=false;
304     boolean setTopic = false;
305
306     try {
307
308       WebdbMultipartRequest mp = null;
309       EntityList mediaList = null;
310       try {
311         // new MediaRequest, "1" is the id for the openPosting user
312         MediaRequest mediaReq = new MediaRequest("1", true, true);
313         mp = new WebdbMultipartRequest(req, (FileHandler)mediaReq);
314         mediaList = mediaReq.getEntityList();
315       } catch (FileHandlerUserException e) {
316         throw new ServletModuleUserException(e.getMsg());
317       }
318
319       HashMap withValues = mp.getParameters();
320
321       //checking the onetimepasswd
322       if(passwdProtection.equals("yes")){
323         HttpSession session = req.getSession(false);
324         String sessionPasswd = (String)session.getAttribute("passwd");
325         if ( sessionPasswd == null){
326           throw new ServletModuleUserException("Lost password");
327         }
328         String passwd = (String)withValues.get("passwd");
329         if ( passwd == null || (!sessionPasswd.equals(passwd))) {
330           throw new ServletModuleUserException("Missing password");
331         }
332         session.invalidate();
333       }
334
335       if ((((String)withValues.get("title")).length() == 0) ||
336           (((String)withValues.get("description")).length() == 0) ||
337           (((String)withValues.get("content_data")).length() == 0))
338         throw new ServletModuleUserException("Missing field");
339
340       // call the routines that escape html
341
342       for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
343         String k=(String)i.next();
344         String v=(String)withValues.get(k);
345
346         if (k.equals("content_data")){
347           //this doesn't quite work yet, so for now, all html goes
348           //withValues.put(k,StringUtil.approveHTMLTags(v));
349           //withValues.put(k,StringUtil.removeHTMLTags(v));
350         } else {
351           withValues.put(k,StringUtil.removeHTMLTags(v));
352         }
353
354       }
355
356       withValues.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
357       withValues.put("publish_path", StringUtil.webdbDate2path((String)withValues.get("date")));
358       withValues.put("is_produced", "0");
359       // by default stuff is published, they can be un-published through the
360       // admin interface.
361       withValues.put("is_published","1");
362       // if op direct article-type == newswire
363       if (directOp.equals("yes")) withValues.put("to_article_type","1");
364
365       withValues.put("to_publisher","1");
366
367       // owner is openposting user
368       //      ML: this is not multi-language friendly and this can be done in a template
369       //      if (withValues.get("creator").toString().equals(""))
370       //        withValues.put("creator","Anonym");
371
372       // inserting  content into database
373       String cid = contentModule.add(withValues);
374       logger.debug("insposting: id = "+cid);
375       //insert was not successfull
376       if(cid==null){
377         //How do we know that it was not succesful cause of a
378         //dupe, what if it failed cause of "No space left on device"?
379         //Or is there something I am missing? Wouldn't it be better
380         //to have an explicit dupe check and then insert? I have no
381         //idea what I am talking about. this comment is in case
382         //I forget to explicitely ask. -mh
383         deliver(req, res, mergeData, postingFormDupeTemplate);
384       }
385
386       String[] to_topicsArr = mp.getParameterValues("to_topic");
387
388       if (to_topicsArr != null && to_topicsArr.length > 0) {
389         try{
390           DatabaseContentToTopics.getInstance().setTopics(cid,to_topicsArr);
391           setTopic = true;
392         }
393         catch (Exception e) {
394           logger.error("setting content_x_topic failed");
395           contentModule.deleteById(cid);
396           throw new ServletModuleException("smod - openindy :: insposting: setting content_x_topic failed: "+e.toString());
397         } //end try
398       } //end if
399
400       //if we're here all is ok... associate the media to the article
401       for(int i=0;i<mediaList.size();i++) {
402         Entity mediaEnt = (Entity)mediaList.elementAt(i);
403         DatabaseContentToMedia.getInstance().addMedia(cid,mediaEnt.getId());
404       }
405
406       try {
407         MirGlobal.localizer().openPostings().afterContentPosting(
408                                                                  (EntityContent)contentModule.getById(cid));
409       }
410       catch (Throwable t) {
411         throw new ServletModuleException(t.getMessage());
412       }
413     }
414     catch (FileHandlerException e) { throw new ServletModuleException("MediaException: "+ e.toString());}
415     catch (IOException e) { throw new ServletModuleException("IOException: "+ e.toString());}
416     catch (StorageObjectException e) { throw new ServletModuleException("StorageObjectException" + e.toString());}
417     catch (ModuleException e) { throw new ServletModuleException("ModuleException"+e.toString());}
418
419     deliver(req, res, mergeData, postingFormDoneTemplate);
420   }
421
422   /*
423    * Method for querying a lucene index
424    */
425   public void search(HttpServletRequest req, HttpServletResponse res)
426     throws ServletModuleException, ServletModuleUserException {
427
428     String queryString="";
429
430     SimpleHash mergeData = new SimpleHash();
431
432     //make the query available to subsequent iterations
433
434     for (Enumeration theParams = req.getParameterNames(); theParams.hasMoreElements() ;) {
435       String pName=(String)theParams.nextElement();
436       if (pName.startsWith("search_")){
437         mergeData.put(pName,new SimpleScalar(req.getParameter(pName)));
438       }
439     }
440
441     try{
442       mergeData.put("topics", themenModule.getTopicsAsSimpleList());
443     }
444     catch(ModuleException e) {
445       logger.debug("search: Can't get topics: " + e.toString());
446     }
447
448     String indexPath=MirConfig.getProp("IndexPath");
449
450
451     KeywordSearchTerm dateTerm = new KeywordSearchTerm("date_formatted","search_date","webdb_create_formatted","webdbcreate_formatted","webdb_create_formatted");
452
453     UnIndexedSearchTerm whereTerm = new UnIndexedSearchTerm("","","","where","where");
454
455     TextSearchTerm creatorTerm = new TextSearchTerm("creator","search_creator","creator","creator","creator");
456     TextSearchTerm titleTerm = new TextSearchTerm("title","search_content","title","title","title");
457     TextSearchTerm descriptionTerm =  new TextSearchTerm("description","search_content","description","description","description");
458
459     ContentSearchTerm contentTerm = new ContentSearchTerm("content_data","search_content","content","","");
460
461     TopicSearchTerm topicTerm = new TopicSearchTerm();
462
463     ImagesSearchTerm imagesTerm = new ImagesSearchTerm();
464
465     AudioSearchTerm audioTerm = new AudioSearchTerm();
466
467     VideoSearchTerm videoTerm = new VideoSearchTerm();
468
469     String creatorFragment = creatorTerm.makeTerm(req);
470     if (creatorFragment != null){
471       queryString = queryString + " +" + creatorFragment;
472     }
473
474     // search title, description, and content for something
475     // the contentTerm uses "search_boolean" to combine its terms
476     String contentFragment = contentTerm.makeTerm(req);
477     if (contentFragment != null){
478       logger.debug("search: contentFragment: " + contentFragment);
479       queryString = queryString + " +" + contentFragment;
480     }
481
482     String topicFragment = topicTerm.makeTerm(req);
483     if (topicFragment != null){
484       queryString = queryString + " +" + topicFragment;
485     }
486
487     String imagesFragment = imagesTerm.makeTerm(req);
488     if (imagesFragment != null){
489       queryString = queryString + " +" + imagesFragment;
490     }
491
492     String audioFragment = audioTerm.makeTerm(req);
493     if (audioFragment != null){
494       queryString = queryString + " +" + audioFragment;
495     }
496
497     String videoFragment = videoTerm.makeTerm(req);
498     if (videoFragment != null){
499       queryString = queryString + " +" + videoFragment;
500     }
501
502     if (queryString == null || queryString == ""){
503       queryString = "";
504     }
505     else{
506
507       try{
508         Searcher searcher = null;
509         try {
510           searcher = new IndexSearcher(indexPath);
511         }
512         catch(IOException e) {
513           logger.error("search: Can't open indexPath: " + indexPath + ": " + e.getMessage());
514           throw new ServletModuleUserException("Problem with Search Index!");
515         }
516
517         // parse the query String.
518         Query query = null;
519         try {
520           query = QueryParser.parse(queryString, "content", new StandardAnalyzer());
521         }
522         catch(Exception e) {
523           searcher.close();
524           logger.error("search: Query don't parse: " + queryString + ": " + e.getMessage());
525           throw new ServletModuleUserException("Problem with Query String! (was '"+queryString+"')");
526         }
527
528         Hits hits = null;
529         try {
530           hits = searcher.search(query);
531         } catch(IOException e) {
532           searcher.close();
533           logger.error("search: Can't get hits: " + e.getMessage());
534           throw new ServletModuleUserException("Problem getting hits!");
535         }
536
537
538         // this is what needs to change in order to get sorting by date
539         // iterate over the results
540         // the results are an array of document
541         // associate this with session so we don't need to reduplicate searches
542         // make a map from date to position
543         // make an list of dates
544         // sort list by date
545         // grab low+n entries from the list of dates,
546         // iterate over these, using hash to get hit position,
547         // and hit position to get hit
548         // shove hit into SimpleList of SimpleHashes
549
550
551
552         try {
553           int start = 0;
554           int end = hits.length();
555           mergeData.put("numberOfHits", (new Integer(end)).toString());
556           SimpleList theHits = new SimpleList();
557           for(int i = start; i < end; i++) {
558             SimpleHash h = new SimpleHash();
559             Document theHit = hits.doc(i);
560             whereTerm.returnMeta(h,theHit);
561             creatorTerm.returnMeta(h,theHit);
562             titleTerm.returnMeta(h,theHit);
563             descriptionTerm.returnMeta(h,theHit);
564             dateTerm.returnMeta(h,theHit);
565             imagesTerm.returnMeta(h,theHit);
566             audioTerm.returnMeta(h,theHit);
567             videoTerm.returnMeta(h,theHit);
568             theHits.add(h);
569           }
570           mergeData.put("hits",theHits);
571         }
572         catch (Exception e) {
573           searcher.close();
574           logger.error("search: Can't iterate over hits: " + e.getMessage());
575           throw new ServletModuleUserException("Problem getting hits!");
576         }
577         searcher.close();
578       }
579       catch (IOException e){
580         logger.error("search: Can't close searcher: " + e.toString());
581         throw new ServletModuleUserException("Problem closing searcher!");
582       }
583     }
584     mergeData.put("queryString",queryString);
585     deliver(req,res,mergeData,searchResultsTemplate);
586   }
587
588   /*
589    * Method for dynamically generating a pdf from a fo file
590    */
591   public void getpdf(HttpServletRequest req, HttpServletResponse res)
592     throws ServletModuleException, ServletModuleUserException {
593     String ID_REQUEST_PARAM = "id";
594
595     String generateFO=MirConfig.getProp("GenerateFO");
596     String generatePDF=MirConfig.getProp("GeneratePDF");
597
598     //don't do anything if we are not making FO files, or if we are
599     //pregenerating PDF's
600     if (generateFO.equals("yes") && generatePDF.equals("no")){
601       //fop complains unless you do the logging this way
602       org.apache.log.Logger log = null;
603       Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
604       log = hierarchy.getLoggerFor("fop");
605       log.setPriority(Priority.WARN);
606
607       String producerStorageRoot=MirConfig.getProp("Producer.StorageRoot");
608       String producerDocRoot=MirConfig.getProp("Producer.DocRoot");
609       String templateDir=MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
610       String xslSheet=templateDir + "/"
611         + MirConfig.getProp("Producer.PrintableContent.html2foStyleSheetName");
612       try {
613         String idParam = req.getParameter(ID_REQUEST_PARAM);
614         if (idParam != null) {
615           EntityContent contentEnt =
616             (EntityContent)contentModule.getById(idParam);
617           String publishPath = contentEnt.getValue("publish_path");
618           String foFile = producerStorageRoot + producerDocRoot + "/"
619             + publishPath + "/" + idParam + ".fo";
620           XSLTInputHandler input = new XSLTInputHandler(new File(foFile),
621                                                         new File(xslSheet));
622
623           ByteArrayOutputStream out = new ByteArrayOutputStream();
624           res.setContentType("application/pdf");
625
626           Driver driver = new Driver();
627           driver.setLogger(log);
628           driver.setRenderer(Driver.RENDER_PDF);
629           driver.setOutputStream(out);
630           driver.render(input.getParser(), input.getInputSource());
631
632           byte[] content = out.toByteArray();
633           res.setContentLength(content.length);
634           res.getOutputStream().write(content);
635           res.getOutputStream().flush();
636         } else {
637           throw new ServletModuleUserException("Missing id parameter.");
638         }
639       } catch (Exception ex) {
640         throw new ServletModuleException(ex.toString());
641       }
642     } else {
643       throw new ServletModuleUserException("Can't generate a PDF because the config tells me not to.");
644     }
645   }
646
647   private void _throwBadContentType (String fileName, String contentType)
648     throws ServletModuleUserException {
649
650     logger.error("Wrong file type uploaded!: " + fileName + " (" + contentType + ")");
651     throw new ServletModuleUserException("A file you uploaded is of the "
652         +"following mime-type: " + contentType + ". Unfortunately we do not support this type. ");
653   }
654
655   protected String createOneTimePasswd(){
656     Random r = new Random();
657     int random = r.nextInt();
658     long l = System.currentTimeMillis();
659     l = (l*l*l*l)/random;
660     if(l<0) l = l * -1;
661     String returnString = ""+l;
662     return returnString.substring(5);
663   }
664
665
666   /* this is an overwritten method of ServletModule in order
667      to use different bundles for open and admin */
668   public void deliver(HttpServletRequest req, HttpServletResponse res,
669                       TemplateModelRoot rtm, TemplateModelRoot popups,
670                       String templateFilename)
671     throws ServletModuleException {
672     if (rtm == null) rtm = new SimpleHash();
673     try {
674       PrintWriter out = res.getWriter();
675       HTMLTemplateProcessor.process(res, templateFilename, rtm, popups, out,
676                                     getLocale(req), "bundles.open");
677       out.close();
678     }   catch (HTMLParseException e) {
679       throw new ServletModuleException(e.toString());
680     } catch (IOException e) {
681       throw new ServletModuleException(e.toString());
682     }
683   }
684 }
685
686
687