2 * Copyright (C) 2001, 2002 The Mir-coders group
4 * This file is part of Mir.
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.
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.
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
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.
32 package mircoders.servlet;
34 import java.io.ByteArrayOutputStream;
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.Arrays;
43 import java.util.Collections;
44 import java.util.Date;
45 import java.util.Enumeration;
46 import java.util.GregorianCalendar;
47 import java.util.HashMap;
48 import java.util.Iterator;
49 import java.util.List;
50 import java.util.ListIterator;
52 import java.util.Random;
54 import java.util.Vector;
55 import java.util.Locale;
56 import javax.servlet.http.HttpServletRequest;
57 import javax.servlet.http.HttpServletResponse;
58 import javax.servlet.http.HttpSession;
61 import gnu.regexp.REMatch;
62 import gnu.regexp.REMatchEnumeration;
63 import gnu.regexp.REException;
66 import org.apache.commons.net.smtp.SMTPClient;
67 import org.apache.commons.net.smtp.SMTPReply;
68 //import org.apache.fop.apps.Driver;
69 //import org.apache.fop.apps.XSLTInputHandler;
70 import org.apache.log.Hierarchy;
71 import org.apache.log.Priority;
72 import org.apache.lucene.analysis.standard.StandardAnalyzer;
73 import org.apache.lucene.document.Document;
74 import org.apache.lucene.queryParser.QueryParser;
75 import org.apache.lucene.search.Hits;
76 import org.apache.lucene.search.IndexSearcher;
77 import org.apache.lucene.search.Query;
78 import org.apache.lucene.search.Searcher;
79 import org.apache.struts.util.MessageResources;
80 import mir.entity.Entity;
81 import mir.entity.EntityList;
82 import mir.generator.Generator;
83 import mir.log.LoggerWrapper;
84 import mir.misc.FileHandler;
85 import mir.misc.StringUtil;
86 import mir.misc.WebdbMultipartRequest;
87 import mir.servlet.ServletModule;
88 import mir.servlet.ServletModuleExc;
89 import mir.servlet.ServletModuleFailure;
90 import mir.servlet.ServletModuleUserExc;
91 import mir.storage.StorageObjectFailure;
92 import mir.util.ExceptionFunctions;
93 import mir.util.HTTPRequestParser;
94 import mir.util.StringRoutines;
95 import mircoders.entity.EntityComment;
96 import mircoders.entity.EntityContent;
97 import mircoders.global.MirGlobal;
98 import mircoders.media.MediaRequest;
99 import mircoders.media.UnsupportedMediaFormatExc;
100 import mircoders.module.ModuleComment;
101 import mircoders.module.ModuleContent;
102 import mircoders.module.ModuleImages;
103 import mircoders.module.ModuleTopics;
104 import mircoders.pdf.PDFGenerator;
105 import mircoders.search.AudioSearchTerm;
106 import mircoders.search.ContentSearchTerm;
107 import mircoders.search.ImagesSearchTerm;
108 import mircoders.search.KeywordSearchTerm;
109 import mircoders.search.TextSearchTerm;
110 import mircoders.search.TopicSearchTerm;
111 import mircoders.search.UnIndexedSearchTerm;
112 import mircoders.search.VideoSearchTerm;
113 import mircoders.storage.DatabaseComment;
114 import mircoders.storage.DatabaseContent;
115 import mircoders.storage.DatabaseContentToMedia;
116 import mircoders.storage.DatabaseContentToTopics;
117 import mircoders.storage.DatabaseImages;
118 import mircoders.storage.DatabaseLanguage;
119 import mircoders.storage.DatabaseTopics;
122 * ServletModuleOpenIndy -
123 * is the open-access-servlet, which is responsible for
124 * adding comments to articles &
125 * open-postings to the newswire
127 * @author mir-coders group
128 * @version $Id: ServletModuleOpenIndy.java,v 1.73 2003/04/14 19:19:16 john Exp $
132 public class ServletModuleOpenIndy extends ServletModule
135 private String commentFormTemplate, commentFormDoneTemplate, commentFormDupeTemplate;
136 private String postingFormTemplate, postingFormDoneTemplate, postingFormDupeTemplate;
137 private String searchResultsTemplate;
138 private String prepareMailTemplate,sentMailTemplate;
139 private ModuleContent contentModule;
140 private ModuleComment commentModule;
141 private ModuleImages imageModule;
142 private ModuleTopics topicsModule;
143 private String directOp ="yes";
144 // Singelton / Kontruktor
145 private static ServletModuleOpenIndy instance = new ServletModuleOpenIndy();
146 public static ServletModule getInstance() { return instance; }
148 private ServletModuleOpenIndy() {
151 logger = new LoggerWrapper("ServletModule.OpenIndy");
153 commentFormTemplate = configuration.getString("ServletModule.OpenIndy.CommentTemplate");
154 commentFormDoneTemplate = configuration.getString("ServletModule.OpenIndy.CommentDoneTemplate");
155 commentFormDupeTemplate = configuration.getString("ServletModule.OpenIndy.CommentDupeTemplate");
156 postingFormTemplate = configuration.getString("ServletModule.OpenIndy.PostingTemplate");
157 postingFormDoneTemplate = configuration.getString("ServletModule.OpenIndy.PostingDoneTemplate");
158 postingFormDupeTemplate = configuration.getString("ServletModule.OpenIndy.PostingDupeTemplate");
159 searchResultsTemplate = configuration.getString("ServletModule.OpenIndy.SearchResultsTemplate");
160 prepareMailTemplate = configuration.getString("ServletModule.OpenIndy.PrepareMailTemplate");
161 sentMailTemplate = configuration.getString("ServletModule.OpenIndy.SentMailTemplate");
162 directOp = configuration.getString("DirectOpenposting").toLowerCase();
163 mainModule = new ModuleComment(DatabaseComment.getInstance());
164 contentModule = new ModuleContent(DatabaseContent.getInstance());
165 topicsModule = new ModuleTopics(DatabaseTopics.getInstance());
166 imageModule = new ModuleImages(DatabaseImages.getInstance());
167 defaultAction="addposting";
169 catch (StorageObjectFailure e) {
170 logger.error("servletmoduleopenindy could not be initialized: " + e.getMessage());
175 * Method to return an "apology" when open postings are disabled
179 * @throws ServletModuleExc
180 * @throws ServletModuleUserExc
181 * @throws ServletModuleFailure
183 public void openPostingDisabled(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
184 deliver(aRequest, aResponse, (Map) null, null,
185 configuration.getString("ServletModule.OpenIndy.PostingDisabledTemplate"));
190 * Method for making a comment
193 public void addcomment(HttpServletRequest req, HttpServletResponse res) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
195 if (MirGlobal.abuse().getOpenPostingDisabled()) {
196 openPostingDisabled(req, res);
201 String aid = req.getParameter("aid"); // the article id the comment will belong to
203 String language = req.getParameter("language");
206 if (aid!=null && !aid.equals("")) {
208 Map mergeData = new HashMap();
211 if (MirGlobal.abuse().getOpenPostingPassword()) {
212 String passwd = this.createOneTimePasswd();
213 HttpSession session = req.getSession(false);
214 session.setAttribute("passwd", passwd);
215 mergeData.put("passwd", passwd);
218 mergeData.put("passwd", (String) null);
221 if (language != null) {
222 HttpSession session = req.getSession(false);
223 session.setAttribute("Locale", new Locale(language, ""));
224 session.setAttribute("language", language);
227 mergeData.put("aid", aid);
229 Map extraInfo = new HashMap();
230 extraInfo.put("languagePopUpData", DatabaseLanguage.getInstance().getPopupData());
232 deliver(req, res, mergeData, extraInfo, commentFormTemplate);
234 catch (Throwable t) {
235 throw new ServletModuleFailure("ServletModuleOpenIndy.addcomment: " + t.getMessage(), t);
238 else throw new ServletModuleExc("aid not set!");
242 * Method for inserting a comment into the Database and delivering
243 * the commentDone Page
246 public void inscomment(HttpServletRequest req, HttpServletResponse res)
247 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
249 if (MirGlobal.abuse().getOpenPostingDisabled()) {
250 openPostingDisabled(req, res);
255 String aid = req.getParameter("to_media"); // the article id the comment will belong to
256 if (aid!=null && !aid.equals(""))
258 // ok, collecting data from form
260 Map withValues = getIntersectingValues(req, DatabaseComment.getInstance());
262 //no html in comments(for now)
263 for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
264 String k=(String)i.next();
265 String v=(String)withValues.get(k);
267 withValues.put(k,StringUtil.removeHTMLTags(v));
269 withValues.put("is_published","1");
270 withValues.put("to_comment_status","1");
272 //checking the onetimepasswd
273 HttpSession session = req.getSession(false);
274 String sessionPasswd = (String) session.getAttribute("passwd");
275 if ( sessionPasswd != null){
276 String passwd = req.getParameter("passwd");
277 if ( passwd == null || passwd.length()==0) {
278 throw new ServletModuleUserExc("comment.error.missingpassword", new String[] {});
280 if (!sessionPasswd.equals(passwd)) {
281 throw new ServletModuleUserExc("comment.error.invalidpassword", new String[] {});
283 session.invalidate();
286 String id = mainModule.add(withValues);
289 deliver(req, res, (Map) null, null, commentFormDupeTemplate);
292 MirGlobal.abuse().logComment(req.getRemoteAddr(), id, new Date(), (String) req.getHeader("User-Agent"));
294 DatabaseContent.getInstance().setUnproduced("id="+aid);
297 EntityComment comment = (EntityComment) DatabaseComment.getInstance().selectById(id);
298 MirGlobal.abuse().checkComment(comment, req, res);
299 MirGlobal.localizer().openPostings().afterCommentPosting(comment);
301 catch (Throwable t) {
302 throw new ServletModuleExc(t.getMessage());
306 // redirecting to url
307 // should implement back to article
308 Map mergeData = new HashMap();
309 deliver(req, res, mergeData, null, commentFormDoneTemplate);
311 catch (Throwable e) {
312 throw new ServletModuleFailure(e);
315 else throw new ServletModuleExc("aid not set!");
320 * Method for delivering the form-Page for open posting
323 public void addposting(HttpServletRequest req, HttpServletResponse res)
324 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
327 if (MirGlobal.abuse().getOpenPostingDisabled()) {
328 openPostingDisabled(req, res);
333 Map mergeData = new HashMap();
336 if (MirGlobal.abuse().getOpenPostingPassword()) {
337 String passwd = this.createOneTimePasswd();
338 HttpSession session = req.getSession(false);
339 session.setAttribute("passwd", passwd);
340 mergeData.put("passwd", passwd);
343 mergeData.put("passwd", (String)null);
346 String maxMedia = configuration.getString("ServletModule.OpenIndy.MaxMediaUploadItems");
347 String defaultMedia = configuration.getString("ServletModule.OpenIndy.DefaultMediaUploadItems");
348 String numOfMedia = req.getParameter("medianum");
350 if (numOfMedia == null || numOfMedia.equals("")) {
351 numOfMedia = defaultMedia;
353 else if (Integer.parseInt(numOfMedia) > Integer.parseInt(maxMedia)) {
354 numOfMedia = maxMedia;
357 int mediaNum = Integer.parseInt(numOfMedia);
358 List mediaFields = new Vector();
359 for (int i = 0; i < mediaNum; i++) {
360 Integer mNum = new Integer(i + 1);
361 mediaFields.add(mNum.toString());
363 mergeData.put("medianum", numOfMedia);
364 mergeData.put("mediafields", mediaFields);
365 mergeData.put("to_topic", null);
367 Map extraInfo = new HashMap();
368 extraInfo.put("languagePopUpData", DatabaseLanguage.getInstance().getPopupData());
369 extraInfo.put("themenPopupData", topicsModule.getTopicsAsSimpleList());
371 extraInfo.put("topics", topicsModule.getTopicsList());
372 deliver(req, res, mergeData, extraInfo, postingFormTemplate);
374 catch (Throwable t) {
375 throw new ServletModuleFailure(t);
380 * Method for inserting an open posting into the Database and delivering
381 * the postingDone Page
384 public void insposting(HttpServletRequest req, HttpServletResponse res) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
386 if (MirGlobal.abuse().getOpenPostingDisabled()) {
387 openPostingDisabled(req, res);
392 Map mergeData = new HashMap();
393 boolean setMedia=false;
394 boolean setTopic = false;
398 WebdbMultipartRequest mp = null;
399 EntityList mediaList = null;
401 // new MediaRequest, "1" is the id for the openPosting user
402 MediaRequest mediaReq = new MediaRequest("1", true);
403 mp = new WebdbMultipartRequest(req, (FileHandler)mediaReq);
404 mediaList = mediaReq.getEntityList();
406 catch (Throwable e) {
407 throw new ServletModuleFailure(e);
410 Map withValues = mp.getParameters();
412 //checking the onetimepasswd
413 HttpSession session = req.getSession(false);
414 String sessionPasswd = (String) session.getAttribute("passwd");
415 if (sessionPasswd != null){
416 String passwd = (String) withValues.get("passwd");
418 logger.debug("session password = " + sessionPasswd + ", form password = " + passwd);
420 if ( passwd == null || passwd.length()==0) {
421 throw new ServletModuleUserExc("posting.error.missingpassword", new String[] {});
423 if (!sessionPasswd.equals(passwd)) {
424 throw new ServletModuleUserExc("posting.error.invalidpassword", new String[] {});
426 session.invalidate();
429 if ((((String)withValues.get("title")).length() == 0) ||
430 (((String)withValues.get("description")).length() == 0) ||
431 (((String)withValues.get("content_data")).length() == 0))
432 throw new ServletModuleUserExc("posting.error.missingfield", new String[] {});
434 // call the routines that escape html
436 for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
437 String k=(String)i.next();
438 String v=(String)withValues.get(k);
440 if (k.equals("content_data")){
441 //this doesn't quite work yet, so for now, all html goes
442 //withValues.put(k,StringUtil.approveHTMLTags(v));
443 withValues.put(k,StringUtil.deleteForbiddenTags(v));
445 else if (k.equals("description")) {
446 String tmp = StringUtil.deleteForbiddenTags(v);
447 withValues.put(k,StringUtil.deleteHTMLTableTags(tmp));
450 withValues.put(k,StringUtil.removeHTMLTags(v));
455 withValues.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
456 withValues.put("publish_path", StringUtil.webdbDate2path((String)withValues.get("date")));
457 withValues.put("is_produced", "0");
458 withValues.put("is_published","1");
459 if (directOp.equals("yes"))
460 withValues.put("to_article_type","1");
462 withValues.put("to_publisher","1");
464 // inserting content into database
465 String cid = contentModule.add(withValues);
466 logger.debug("id: "+cid);
467 //insert was not successfull
470 //How do we know that it was not succesful cause of a
471 //dupe, what if it failed cause of "No space left on device"?
472 //Or is there something I am missing? Wouldn't it be better
473 //to have an explicit dupe check and then insert? I have no
474 //idea what I am talking about. this comment is in case
475 //I forget to explicitely ask. -mh
476 deliver(req, res, mergeData, null, postingFormDupeTemplate);
480 MirGlobal.abuse().logArticle(req.getRemoteAddr(), cid, new Date(), (String) req.getHeader("User-Agent"));
482 String[] to_topicsArr = mp.getParameterValues("to_topic");
484 if (to_topicsArr != null && to_topicsArr.length > 0) {
486 DatabaseContentToTopics.getInstance().setTopics(cid,to_topicsArr);
489 catch (Throwable e) {
490 logger.error("setting content_x_topic failed");
491 contentModule.deleteById(cid);
492 throw new ServletModuleFailure("smod - openindy :: insposting: setting content_x_topic failed: "+e.toString(), e);
496 //if we're here all is ok... associate the media to the article
497 for(int i=0;i<mediaList.size();i++) {
498 Entity mediaEnt = (Entity)mediaList.elementAt(i);
499 DatabaseContentToMedia.getInstance().addMedia(cid,mediaEnt.getId());
502 EntityContent article = (EntityContent) contentModule.getById(cid);
505 MirGlobal.abuse().checkArticle(article, req, res);
506 MirGlobal.localizer().openPostings().afterContentPosting(article);
508 catch (Throwable t) {
509 logger.error("Error while post-processing article: " + t.getMessage());
512 catch (Throwable e) {
513 Throwable cause = ExceptionFunctions.traceCauseException(e);
515 if (cause instanceof UnsupportedMediaFormatExc) {
516 throw new ServletModuleUserExc("media.unsupportedformat", new String[] {} );
518 throw new ServletModuleFailure(e);
521 deliver(req, res, mergeData, null, postingFormDoneTemplate);
525 * Method for preparing and sending a content as an email message
528 public void mail(HttpServletRequest req, HttpServletResponse res)
529 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
531 String aid = req.getParameter("mail_aid");
533 throw new ServletModuleExc("An article id must be specified in requests to email an article. Something therefore went badly wrong....");
536 String to = req.getParameter("mail_to");
537 String from = req.getParameter("mail_from");
538 String from_name = req.getParameter("mail_from_name");
539 String comment = req.getParameter("mail_comment");
540 String mail_language = req.getParameter("mail_language");
542 Map mergeData = new HashMap();
544 if (to == null || from == null || from_name == null|| to.equals("") || from.equals("") || from_name.equals("") || mail_language == null || mail_language.equals("")){
546 for (Enumeration theParams = req.getParameterNames(); theParams.hasMoreElements() ;) {
547 String pName=(String)theParams.nextElement();
548 if (pName.startsWith("mail_")){
549 mergeData.put( pName,req.getParameter(pName) );
553 deliver(req, res, mergeData, null, prepareMailTemplate);
556 //run checks on to and from and mail_language to make sure no monkey business occurring
557 if (mail_language.indexOf('.') != -1 || mail_language.indexOf('/') != -1 ) {
558 throw new ServletModuleExc("Invalid language");
560 if (to.indexOf('\n') != -1
561 || to.indexOf('\r') != -1
562 || to.indexOf(',') != -1) {
563 throw new ServletModuleUserExc("email.error.invalidtoaddress", new String[] {to});
565 if (from.indexOf('\n') != -1 || from.indexOf('\r') != -1 || from.indexOf(',') != -1 ) {
566 throw new ServletModuleUserExc("email.error.invalidfromaddress", new String[] {from});
570 EntityContent contentEnt;
572 contentEnt = (EntityContent)contentModule.getById(aid);
575 throw new ServletModuleFailure("Couldn't get content for article "+aid + ": " + e.getMessage(), e);
577 String producerStorageRoot=configuration.getString("Producer.StorageRoot");
578 String producerDocRoot=configuration.getString("Producer.DocRoot");
579 String publishPath = contentEnt.getValue("publish_path");
580 String txtFilePath = producerStorageRoot + producerDocRoot + "/" + mail_language +
581 publishPath + "/" + aid + ".txt";
584 File inputFile = new File(txtFilePath);
588 FileReader in = new FileReader(inputFile);
589 StringWriter out = new StringWriter();
591 while ((c = in.read()) != -1)
594 content= out.toString();
596 catch (FileNotFoundException e){
597 throw new ServletModuleFailure("No text file found in " + txtFilePath, e);
599 catch (IOException e){
600 throw new ServletModuleFailure("Problem reading file in " + txtFilePath, e);
603 content = "To: " + to + "\nReply-To: "+ from + "\n" + content;
604 // put in the comment where it should go
605 if (comment != null) {
606 String commentTextToInsert = "\n\nAttached comment from " + from_name + ":\n" + comment;
608 content=StringRoutines.performRegularExpressionReplacement(content,"!COMMENT!",commentTextToInsert);
611 throw new ServletModuleFailure("Problem doing regular expression replacement " + e.toString(), e);
616 content=StringRoutines.performRegularExpressionReplacement(content,"!COMMENT!","");
619 throw new ServletModuleFailure("Problem doing regular expression replacement " + e.toString(), e);
623 SMTPClient client=new SMTPClient();
626 client.connect(configuration.getString("ServletModule.OpenIndy.SMTPServer"));
628 reply = client.getReplyCode();
630 if (!SMTPReply.isPositiveCompletion(reply)) {
632 throw new ServletModuleExc("SMTP server refused connection.");
635 client.sendSimpleMessage(configuration.getString("ServletModule.OpenIndy.EmailIsFrom"), to, content);
638 //mission accomplished
639 deliver(req, res, mergeData, null, sentMailTemplate);
641 catch(IOException e) {
642 if(client.isConnected()) {
645 } catch(IOException f) {
649 throw new ServletModuleFailure(e);
655 * Method for querying a lucene index
659 * @throws ServletModuleExc
660 * @throws ServletModuleUserExc
661 * @throws ServletModuleFailure
664 public void search(HttpServletRequest req, HttpServletResponse res)
665 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
667 final String[] search_variables = { "search_content", "search_boolean", "search_creator",
668 "search_topic", "search_hasImages", "search_hasAudio", "search_hasVideo", "search_sort",
669 "search_submit", "search_back", "search_forward" };
670 HTTPRequestParser requestParser = new HTTPRequestParser(req);
674 HttpSession session = req.getSession(false);
676 String queryString="";
678 Map mergeData = new HashMap();
680 KeywordSearchTerm dateTerm = new KeywordSearchTerm("date_formatted","search_date","webdb_create_formatted","webdb_create_formatted","webdb_create_formatted");
681 UnIndexedSearchTerm whereTerm = new UnIndexedSearchTerm("","","","where","where");
682 TextSearchTerm creatorTerm = new TextSearchTerm("creator","search_creator","creator","creator","creator");
683 TextSearchTerm titleTerm = new TextSearchTerm("title","search_content","title","title","title");
684 TextSearchTerm descriptionTerm = new TextSearchTerm("description","search_content","description","description","description");
685 ContentSearchTerm contentTerm = new ContentSearchTerm("content_data","search_content","content","","");
686 TopicSearchTerm topicTerm = new TopicSearchTerm();
687 ImagesSearchTerm imagesTerm = new ImagesSearchTerm();
688 AudioSearchTerm audioTerm = new AudioSearchTerm();
689 VideoSearchTerm videoTerm = new VideoSearchTerm();
691 //make the query available to subsequent iterations
693 Iterator j = Arrays.asList(search_variables).iterator();
694 while (j.hasNext()) {
695 String variable = (String) j.next();
697 mergeData.put(variable, requestParser.getParameter(variable));
701 mergeData.put("topics", topicsModule.getTopicsAsSimpleList());
704 logger.debug("Can't get topics: " + e.toString());
707 String searchBackValue = req.getParameter("search_back");
708 String searchForwardValue = req.getParameter("search_forward");
710 if (searchBackValue != null){
711 int totalHits = ((Integer) session.getAttribute("numberOfHits")).intValue();
712 int newPosition=((Integer)session.getAttribute("positionInResults")).intValue()-increment;
715 if (newPosition >= totalHits)
716 newPosition=totalHits-1;
717 session.setAttribute("positionInResults",new Integer(newPosition));
720 if (searchForwardValue != null){
721 int totalHits = ((Integer) session.getAttribute("numberOfHits")).intValue();
722 int newPosition=((Integer)session.getAttribute("positionInResults")).intValue()+increment;
725 if (newPosition >= totalHits)
726 newPosition=totalHits-1;
728 session.setAttribute("positionInResults",new Integer(newPosition));
731 String indexPath=configuration.getString("IndexPath");
734 String creatorFragment = creatorTerm.makeTerm(req);
735 if (creatorFragment != null){
736 queryString = queryString + " +" + creatorFragment;
739 // search title, description, and content for something
740 // the contentTerm uses param "search_boolean" to combine its terms
741 String contentFragment = contentTerm.makeTerm(req);
742 if (contentFragment != null){
743 logger.debug("contentFragment: " + contentFragment);
744 queryString = queryString + " +" + contentFragment;
747 String topicFragment = topicTerm.makeTerm(req);
748 if (topicFragment != null){
749 queryString = queryString + " +" + topicFragment;
752 String imagesFragment = imagesTerm.makeTerm(req);
753 if (imagesFragment != null){
754 queryString = queryString + " +" + imagesFragment;
757 String audioFragment = audioTerm.makeTerm(req);
758 if (audioFragment != null){
759 queryString = queryString + " +" + audioFragment;
762 String videoFragment = videoTerm.makeTerm(req);
763 if (videoFragment != null){
764 queryString = queryString + " +" + videoFragment;
767 if (queryString == null || queryString == ""){
772 Searcher searcher = null;
774 searcher = new IndexSearcher(indexPath);
776 catch(IOException e) {
777 logger.debug("Can't open indexPath: " + indexPath);
778 throw new ServletModuleExc("Problem with Search Index! : "+ e.toString());
783 query = QueryParser.parse(queryString, "content", new StandardAnalyzer());
787 logger.debug("Query don't parse: " + queryString);
788 throw new ServletModuleExc("Problem with Query String! (was '"+queryString+"')");
793 hits = searcher.search(query);
795 catch(IOException e) {
797 logger.debug("Can't get hits: " + e.toString());
798 throw new ServletModuleExc("Problem getting hits!");
802 int end = hits.length();
804 String sortBy=req.getParameter("search_sort");
805 if (sortBy == null || sortBy.equals("")){
806 throw new ServletModuleExc("Please let me sort by something!(missing search_sort)");
809 // here is where the documents will go for storage across sessions
810 ArrayList theDocumentsSorted = new ArrayList();
812 if (sortBy.equals("score")){
813 for(int i = start; i < end; i++) {
814 theDocumentsSorted.add(hits.doc(i));
818 // then we'll sort by date!
819 Map dateToPosition = new HashMap(end,1.0F); //we know how big it will be
820 for(int i = start; i < end; i++) {
821 String creationDate=(hits.doc(i)).get("creationDate");
822 // do a little dance in case two contents created at the same second!
823 if (dateToPosition.containsKey(creationDate)){
824 ((ArrayList) (dateToPosition.get(creationDate))).add(new Integer(i));
827 ArrayList thePositions = new ArrayList();
828 thePositions.add(new Integer(i));
829 dateToPosition.put(creationDate,thePositions);
832 Set keys = dateToPosition.keySet();
833 ArrayList keyList= new ArrayList(keys);
834 Collections.sort(keyList);
835 if (sortBy.equals("date_desc")){
836 Collections.reverse(keyList);
839 if (!sortBy.equals("date_asc")){
840 throw new ServletModuleExc("don't know how to sort by: "+ sortBy);
843 ListIterator keyTraverser = keyList.listIterator();
844 while (keyTraverser.hasNext()){
845 ArrayList positions = (ArrayList)dateToPosition.get((keyTraverser.next()));
846 ListIterator positionsTraverser=positions.listIterator();
847 while (positionsTraverser.hasNext()){
848 theDocumentsSorted.add(hits.doc(((Integer)(positionsTraverser.next())).intValue()));
856 catch (IOException e){
857 logger.debug("Can't close searcher: " + e.toString());
858 throw new ServletModuleFailure("Problem closing searcher(normal):" + e.getMessage(), e);
862 session.removeAttribute("numberOfHits");
863 session.removeAttribute("theDocumentsSorted");
864 session.removeAttribute("positionInResults");
866 session.setAttribute("numberOfHits",new Integer(end));
867 session.setAttribute("theDocumentsSorted",theDocumentsSorted);
868 session.setAttribute("positionInResults",new Integer(0));
871 catch (IOException e){
872 logger.debug("Can't close searcher: " + e.toString());
873 throw new ServletModuleFailure("Problem closing searcher: " + e.getMessage(), e);
880 ArrayList theDocs = (ArrayList)session.getAttribute("theDocumentsSorted");
881 if (theDocs != null){
883 mergeData.put("numberOfHits", ((Integer)session.getAttribute("numberOfHits")).toString());
884 List theHits = new Vector();
885 int pIR=((Integer)session.getAttribute("positionInResults")).intValue();
887 int numHits=((Integer)session.getAttribute("numberOfHits")).intValue();
889 if (!(pIR+increment>=numHits)){
890 mergeData.put("hasNext","y");
893 mergeData.put("hasNext", null);
896 mergeData.put("hasPrevious","y");
899 mergeData.put("hasPrevious", null);
902 if ((pIR+increment)>numHits){
906 terminus=pIR+increment;
908 for(int i = pIR; i < terminus; i++) {
909 Map h = new HashMap();
910 Document theHit = (Document)theDocs.get(i);
911 whereTerm.returnMeta(h,theHit);
912 creatorTerm.returnMeta(h,theHit);
913 titleTerm.returnMeta(h,theHit);
914 descriptionTerm.returnMeta(h,theHit);
915 dateTerm.returnMeta(h,theHit);
916 imagesTerm.returnMeta(h,theHit);
917 audioTerm.returnMeta(h,theHit);
918 videoTerm.returnMeta(h,theHit);
921 mergeData.put("hits",theHits);
924 catch (Throwable e) {
925 logger.error("Can't iterate over hits: " + e.toString());
927 throw new ServletModuleFailure("Problem getting hits: " + e.getMessage(), e);
930 mergeData.put("queryString",queryString);
932 deliver(req, res, mergeData, null, searchResultsTemplate);
934 catch (NullPointerException n){
935 throw new ServletModuleFailure("Null Pointer: "+n.toString(), n);
940 * Method for dynamically generating a pdf using iText
944 public void getpdf(HttpServletRequest req, HttpServletResponse res)
945 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
946 String ID_REQUEST_PARAM = "id";
948 String idParam = req.getParameter(ID_REQUEST_PARAM);
949 if (idParam != null) {
950 ByteArrayOutputStream out = new ByteArrayOutputStream();
951 PDFGenerator pdfMaker = new PDFGenerator(out);
953 RE re = new RE("[0-9]+");
956 REMatch[] idMatches=re.getAllMatches(idParam);
958 if (idMatches.length > 1){
960 for (int i = 0; i < idMatches.length; i++){
961 REMatch aMatch = idMatches[i];
962 String id=aMatch.toString();
963 EntityContent contentEnt = (EntityContent)contentModule.getById(id);
964 pdfMaker.addIndexItem(contentEnt);
969 for (int i = 0; i < idMatches.length; i++){
970 REMatch aMatch = idMatches[i];
972 String id=aMatch.toString();
974 EntityContent contentEnt = (EntityContent)contentModule.getById(id);
975 pdfMaker.add(contentEnt);
980 res.setContentType("application/pdf");
981 byte[] content = out.toByteArray();
982 res.setContentLength(content.length);
983 res.getOutputStream().write(content);
984 res.getOutputStream().flush();
988 throw new ServletModuleExc("Missing id.");
991 catch (Throwable t) {
992 logger.error(t.toString());
993 throw new ServletModuleFailure(t);
1000 * Method for dynamically generating a pdf from a fo file
1001 * (deprecated until fop gets its act together regarding floats)
1005 public void getpdf(HttpServletRequest req, HttpServletResponse res)
1006 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
1007 String ID_REQUEST_PARAM = "id";
1008 String language = req.getParameter("language");
1009 String generateFO=configuration.getString("GenerateFO");
1010 String generatePDF=configuration.getString("GeneratePDF");
1013 //don't do anything if we are not making FO files, or if we are
1014 //pregenerating PDF's
1015 if (generateFO.equals("yes") && generatePDF.equals("no")){
1016 //fop complains unless you do the logging this way
1017 org.apache.log.Logger log = null;
1018 Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
1019 log = hierarchy.getLoggerFor("fop");
1020 log.setPriority(Priority.WARN);
1022 String producerStorageRoot=configuration.getString("Producer.StorageRoot");
1023 String producerDocRoot=configuration.getString("Producer.DocRoot");
1024 // String templateDir=MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
1025 String xslSheet=configuration.getString("Producer.HTML2FOStyleSheet");
1027 String idParam = req.getParameter(ID_REQUEST_PARAM);
1028 if (idParam != null) {
1029 EntityContent contentEnt =
1030 (EntityContent)contentModule.getById(idParam);
1031 String publishPath = StringUtil.webdbDate2path(contentEnt.getValue("date"));
1034 if (language == null){
1035 foFile = producerStorageRoot + producerDocRoot + "/"
1036 + publishPath + idParam + ".fo";
1039 foFile = producerStorageRoot + producerDocRoot + "/"
1040 + language + publishPath + idParam + ".fo";
1042 logger.debug("USING FILES" + foFile + " and " + xslSheet);
1043 XSLTInputHandler input = new XSLTInputHandler(new File(foFile),
1044 new File(xslSheet));
1046 ByteArrayOutputStream out = new ByteArrayOutputStream();
1047 res.setContentType("application/pdf");
1049 Driver driver = new Driver();
1050 driver.setLogger(log);
1051 driver.setRenderer(Driver.RENDER_PDF);
1052 driver.setOutputStream(out);
1053 driver.render(input.getParser(), input.getInputSource());
1055 byte[] content = out.toByteArray();
1056 res.setContentLength(content.length);
1057 res.getOutputStream().write(content);
1058 res.getOutputStream().flush();
1061 throw new ServletModuleExc("Missing id.");
1064 catch (Throwable t) {
1065 logger.error(t.toString());
1067 throw new ServletModuleFailure(t);
1071 throw new ServletModuleExc("Can't generate a PDF because the config tells me not to.");
1075 protected String createOneTimePasswd(){
1076 Random r = new Random();
1077 int random = r.nextInt();
1078 long l = System.currentTimeMillis();
1079 l = (l*l*l*l)/random;
1081 String returnString = ""+l;
1083 return returnString.substring(5);
1087 /* this is an overwritten method of ServletModule in order
1088 to use different bundles for open and admin */
1089 /* public void deliver(HttpServletRequest req, HttpServletResponse res,
1090 TemplateModelRoot rtm, TemplateModelRoot popups,
1091 String templateFilename) throws ServletModuleFailure
1095 public void deliver(HttpServletRequest aRequest, HttpServletResponse aResponse, Map aData, Map anExtra, String aGenerator)
1096 throws ServletModuleFailure {
1098 deliver(aResponse.getWriter(), aRequest, aResponse, aData, anExtra, aGenerator);
1100 catch (Throwable t) {
1101 throw new ServletModuleFailure(t);
1105 public void deliver(PrintWriter anOutputWriter, HttpServletRequest aRequest, HttpServletResponse aResponse, Map aData, Map anExtra, String aGenerator)
1106 throws ServletModuleFailure {
1108 Map responseData = ServletHelper.makeGenerationData(new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)}, "bundles.open");
1109 responseData.put("data", aData);
1110 responseData.put("extra", anExtra);
1113 Generator generator = MirGlobal.localizer().generators().makeOpenPostingGeneratorLibrary().makeGenerator(aGenerator);
1114 generator.generate(anOutputWriter, responseData, logger.asPrintWriter(logger.INFO_MESSAGE));
1116 anOutputWriter.close();
1118 catch (Throwable e) {
1119 logger.error("Error while generating " + aGenerator + ": " + e.getMessage());
1121 throw new ServletModuleFailure(e);
1125 public void handleError(HttpServletRequest aRequest, HttpServletResponse aResponse,PrintWriter out, Throwable anException) {
1127 logger.error("error: " + anException);
1128 anException.printStackTrace();
1129 Map data = new HashMap();
1131 data.put("errorstring", anException.getMessage());
1132 data.put("date", StringUtil.date2readableDateTime(new GregorianCalendar()));
1134 deliver(out, aRequest, aResponse, data, null, configuration.getString("ServletModule.OpenIndy.ErrorTemplate"));
1136 catch (Throwable e) {
1137 throw new ServletModuleFailure(e);
1141 public void handleUserError(HttpServletRequest aRequest, HttpServletResponse aResponse,
1142 PrintWriter out, ServletModuleUserExc anException) {
1144 logger.warn("user error: " + anException.getMessage());
1145 Map data = new HashMap();
1147 MessageResources messages = MessageResources.getMessageResources("bundles.open");
1148 data.put("errorstring",
1149 messages.getMessage(getLocale(aRequest), anException.getMessage(), anException.getParameters())
1151 data.put("date", StringUtil.date2readableDateTime(new GregorianCalendar()));
1153 deliver(out, aRequest, aResponse, data, null, configuration.getString("ServletModule.OpenIndy.UserErrorTemplate"));
1155 catch (Throwable e) {
1156 throw new ServletModuleFailure(e);