2 * Copyright (C) 2001, 2002 The Mir-coders group
\r
4 * This file is part of Mir.
\r
6 * Mir is free software; you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation; either version 2 of the License, or
\r
9 * (at your option) any later version.
\r
11 * Mir is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with Mir; if not, write to the Free Software
\r
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 * In addition, as a special exception, The Mir-coders gives permission to link
\r
21 * the code of this program with the com.oreilly.servlet library, any library
\r
22 * licensed under the Apache Software License, The Sun (tm) Java Advanced
\r
23 * Imaging library (JAI), The Sun JIMI library (or with modified versions of
\r
24 * the above that use the same license as the above), and distribute linked
\r
25 * combinations including the two. You must obey the GNU General Public
\r
26 * License in all respects for all of the code used other than the above
\r
27 * mentioned libraries. If you modify this file, you may extend this exception
\r
28 * to your version of the file, but you are not obligated to do so. If you do
\r
29 * not wish to do so, delete this exception statement from your version.
\r
32 package mircoders.servlet;
\r
34 import java.io.ByteArrayOutputStream;
\r
35 import java.io.File;
\r
36 import java.io.FileNotFoundException;
\r
37 import java.io.FileReader;
\r
38 import java.io.IOException;
\r
39 import java.io.PrintWriter;
\r
40 import java.io.StringWriter;
\r
41 import java.util.ArrayList;
\r
42 import java.util.Arrays;
\r
43 import java.util.Collections;
\r
44 import java.util.Date;
\r
45 import java.util.Enumeration;
\r
46 import java.util.GregorianCalendar;
\r
47 import java.util.HashMap;
\r
48 import java.util.Iterator;
\r
49 import java.util.List;
\r
50 import java.util.ListIterator;
\r
51 import java.util.Map;
\r
52 import java.util.Random;
\r
53 import java.util.Set;
\r
54 import java.util.Vector;
\r
55 import javax.servlet.http.HttpServletRequest;
\r
56 import javax.servlet.http.HttpServletResponse;
\r
57 import javax.servlet.http.HttpSession;
\r
59 import org.apache.commons.net.smtp.SMTPClient;
\r
60 import org.apache.commons.net.smtp.SMTPReply;
\r
61 import org.apache.fop.apps.Driver;
\r
62 import org.apache.fop.apps.XSLTInputHandler;
\r
63 import org.apache.log.Hierarchy;
\r
64 import org.apache.log.Priority;
\r
65 import org.apache.lucene.analysis.standard.StandardAnalyzer;
\r
66 import org.apache.lucene.document.Document;
\r
67 import org.apache.lucene.queryParser.QueryParser;
\r
68 import org.apache.lucene.search.Hits;
\r
69 import org.apache.lucene.search.IndexSearcher;
\r
70 import org.apache.lucene.search.Query;
\r
71 import org.apache.lucene.search.Searcher;
\r
72 import org.apache.struts.util.MessageResources;
\r
73 import mir.entity.Entity;
\r
74 import mir.entity.EntityList;
\r
75 import mir.generator.Generator;
\r
76 import mir.log.LoggerWrapper;
\r
77 import mir.misc.FileHandler;
\r
78 import mir.misc.StringUtil;
\r
79 import mir.misc.WebdbMultipartRequest;
\r
80 import mir.servlet.ServletModule;
\r
81 import mir.servlet.ServletModuleExc;
\r
82 import mir.servlet.ServletModuleFailure;
\r
83 import mir.servlet.ServletModuleUserExc;
\r
84 import mir.storage.StorageObjectFailure;
\r
85 import mir.util.ExceptionFunctions;
\r
86 import mir.util.HTTPRequestParser;
\r
87 import mir.util.StringRoutines;
\r
88 import mircoders.entity.EntityComment;
\r
89 import mircoders.entity.EntityContent;
\r
90 import mircoders.global.MirGlobal;
\r
91 import mircoders.media.MediaRequest;
\r
92 import mircoders.media.UnsupportedMediaFormatExc;
\r
93 import mircoders.module.ModuleComment;
\r
94 import mircoders.module.ModuleContent;
\r
95 import mircoders.module.ModuleImages;
\r
96 import mircoders.module.ModuleTopics;
\r
97 import mircoders.search.AudioSearchTerm;
\r
98 import mircoders.search.ContentSearchTerm;
\r
99 import mircoders.search.ImagesSearchTerm;
\r
100 import mircoders.search.KeywordSearchTerm;
\r
101 import mircoders.search.TextSearchTerm;
\r
102 import mircoders.search.TopicSearchTerm;
\r
103 import mircoders.search.UnIndexedSearchTerm;
\r
104 import mircoders.search.VideoSearchTerm;
\r
105 import mircoders.storage.DatabaseComment;
\r
106 import mircoders.storage.DatabaseContent;
\r
107 import mircoders.storage.DatabaseContentToMedia;
\r
108 import mircoders.storage.DatabaseContentToTopics;
\r
109 import mircoders.storage.DatabaseImages;
\r
110 import mircoders.storage.DatabaseLanguage;
\r
111 import mircoders.storage.DatabaseTopics;
\r
114 * ServletModuleOpenIndy -
\r
115 * is the open-access-servlet, which is responsible for
\r
116 * adding comments to articles &
\r
117 * open-postings to the newswire
\r
119 * @author mir-coders group
\r
120 * @version $Id: ServletModuleOpenIndy.java,v 1.70 2003/04/02 22:15:03 zapata Exp $
\r
124 public class ServletModuleOpenIndy extends ServletModule
\r
127 private String commentFormTemplate, commentFormDoneTemplate, commentFormDupeTemplate;
\r
128 private String postingFormTemplate, postingFormDoneTemplate, postingFormDupeTemplate;
\r
129 private String searchResultsTemplate;
\r
130 private String prepareMailTemplate,sentMailTemplate;
\r
131 private ModuleContent contentModule;
\r
132 private ModuleComment commentModule;
\r
133 private ModuleImages imageModule;
\r
134 private ModuleTopics topicsModule;
\r
135 private String directOp ="yes";
\r
136 // Singelton / Kontruktor
\r
137 private static ServletModuleOpenIndy instance = new ServletModuleOpenIndy();
\r
138 public static ServletModule getInstance() { return instance; }
\r
140 private ServletModuleOpenIndy() {
\r
143 logger = new LoggerWrapper("ServletModule.OpenIndy");
\r
145 commentFormTemplate = configuration.getString("ServletModule.OpenIndy.CommentTemplate");
\r
146 commentFormDoneTemplate = configuration.getString("ServletModule.OpenIndy.CommentDoneTemplate");
\r
147 commentFormDupeTemplate = configuration.getString("ServletModule.OpenIndy.CommentDupeTemplate");
\r
148 postingFormTemplate = configuration.getString("ServletModule.OpenIndy.PostingTemplate");
\r
149 postingFormDoneTemplate = configuration.getString("ServletModule.OpenIndy.PostingDoneTemplate");
\r
150 postingFormDupeTemplate = configuration.getString("ServletModule.OpenIndy.PostingDupeTemplate");
\r
151 searchResultsTemplate = configuration.getString("ServletModule.OpenIndy.SearchResultsTemplate");
\r
152 prepareMailTemplate = configuration.getString("ServletModule.OpenIndy.PrepareMailTemplate");
\r
153 sentMailTemplate = configuration.getString("ServletModule.OpenIndy.SentMailTemplate");
\r
154 directOp = configuration.getString("DirectOpenposting").toLowerCase();
\r
155 mainModule = new ModuleComment(DatabaseComment.getInstance());
\r
156 contentModule = new ModuleContent(DatabaseContent.getInstance());
\r
157 topicsModule = new ModuleTopics(DatabaseTopics.getInstance());
\r
158 imageModule = new ModuleImages(DatabaseImages.getInstance());
\r
159 defaultAction="addposting";
\r
161 catch (StorageObjectFailure e) {
\r
162 logger.error("servletmoduleopenindy could not be initialized: " + e.getMessage());
\r
167 * Method to return an "apology" when open postings are disabled
\r
171 * @throws ServletModuleExc
\r
172 * @throws ServletModuleUserExc
\r
173 * @throws ServletModuleFailure
\r
175 public void openPostingDisabled(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
176 deliver(aRequest, aResponse, (Map) null, null,
\r
177 configuration.getString("ServletModule.OpenIndy.PostingDisabledTemplate"));
\r
182 * Method for making a comment
\r
185 public void addcomment(HttpServletRequest req, HttpServletResponse res) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
\r
187 if (MirGlobal.abuse().getOpenPostingDisabled()) {
\r
188 openPostingDisabled(req, res);
\r
193 String aid = req.getParameter("aid"); // the article id the comment will belong to
\r
195 String language = req.getParameter("language");
\r
198 if (aid!=null && !aid.equals("")) {
\r
200 Map mergeData = new HashMap();
\r
203 if (MirGlobal.abuse().getOpenPostingPassword()) {
\r
204 String passwd = this.createOneTimePasswd();
\r
205 HttpSession session = req.getSession(false);
\r
206 session.setAttribute("passwd", passwd);
\r
207 mergeData.put("passwd", passwd);
\r
210 mergeData.put("passwd", (String) null);
\r
213 if (language != null) {
\r
214 HttpSession session = req.getSession(false);
\r
215 session.setAttribute("Locale", new Locale(language, ""));
\r
216 session.setAttribute("language", language);
\r
219 mergeData.put("aid", aid);
\r
221 Map extraInfo = new HashMap();
\r
222 extraInfo.put("languagePopUpData", DatabaseLanguage.getInstance().getPopupData());
\r
224 deliver(req, res, mergeData, extraInfo, commentFormTemplate);
\r
226 catch (Throwable t) {
\r
227 throw new ServletModuleFailure("ServletModuleOpenIndy.addcomment: " + t.getMessage(), t);
\r
230 else throw new ServletModuleExc("aid not set!");
\r
234 * Method for inserting a comment into the Database and delivering
\r
235 * the commentDone Page
\r
238 public void inscomment(HttpServletRequest req, HttpServletResponse res)
\r
239 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
\r
241 if (MirGlobal.abuse().getOpenPostingDisabled()) {
\r
242 openPostingDisabled(req, res);
\r
247 String aid = req.getParameter("to_media"); // the article id the comment will belong to
\r
248 if (aid!=null && !aid.equals(""))
\r
250 // ok, collecting data from form
\r
252 Map withValues = getIntersectingValues(req, DatabaseComment.getInstance());
\r
254 //no html in comments(for now)
\r
255 for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
\r
256 String k=(String)i.next();
\r
257 String v=(String)withValues.get(k);
\r
259 withValues.put(k,StringUtil.removeHTMLTags(v));
\r
261 withValues.put("is_published","1");
\r
262 withValues.put("to_comment_status","1");
\r
264 //checking the onetimepasswd
\r
265 HttpSession session = req.getSession(false);
\r
266 String sessionPasswd = (String) session.getAttribute("passwd");
\r
267 if ( sessionPasswd != null){
\r
268 String passwd = req.getParameter("passwd");
\r
269 if ( passwd == null || passwd.length()==0) {
\r
270 throw new ServletModuleUserExc("comment.error.missingpassword", new String[] {});
\r
272 if (!sessionPasswd.equals(passwd)) {
\r
273 throw new ServletModuleUserExc("comment.error.invalidpassword", new String[] {});
\r
275 session.invalidate();
\r
278 String id = mainModule.add(withValues);
\r
281 deliver(req, res, (Map) null, null, commentFormDupeTemplate);
\r
284 MirGlobal.abuse().logComment(req.getRemoteAddr(), id, new Date(), (String) req.getHeader("User-Agent"));
\r
286 DatabaseContent.getInstance().setUnproduced("id="+aid);
\r
289 EntityComment comment = (EntityComment) DatabaseComment.getInstance().selectById(id);
\r
290 MirGlobal.abuse().checkComment(comment, req, res);
\r
291 MirGlobal.localizer().openPostings().afterCommentPosting(comment);
\r
293 catch (Throwable t) {
\r
294 throw new ServletModuleExc(t.getMessage());
\r
298 // redirecting to url
\r
299 // should implement back to article
\r
300 Map mergeData = new HashMap();
\r
301 deliver(req, res, mergeData, null, commentFormDoneTemplate);
\r
303 catch (Throwable e) {
\r
304 throw new ServletModuleFailure(e);
\r
307 else throw new ServletModuleExc("aid not set!");
\r
312 * Method for delivering the form-Page for open posting
\r
315 public void addposting(HttpServletRequest req, HttpServletResponse res)
\r
316 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
\r
319 if (MirGlobal.abuse().getOpenPostingDisabled()) {
\r
320 openPostingDisabled(req, res);
\r
325 Map mergeData = new HashMap();
\r
328 if (MirGlobal.abuse().getOpenPostingPassword()) {
\r
329 String passwd = this.createOneTimePasswd();
\r
330 HttpSession session = req.getSession(false);
\r
331 session.setAttribute("passwd", passwd);
\r
332 mergeData.put("passwd", passwd);
\r
335 mergeData.put("passwd", (String)null);
\r
338 String maxMedia = configuration.getString("ServletModule.OpenIndy.MaxMediaUploadItems");
\r
339 String defaultMedia = configuration.getString("ServletModule.OpenIndy.DefaultMediaUploadItems");
\r
340 String numOfMedia = req.getParameter("medianum");
\r
342 if (numOfMedia == null || numOfMedia.equals("")) {
\r
343 numOfMedia = defaultMedia;
\r
345 else if (Integer.parseInt(numOfMedia) > Integer.parseInt(maxMedia)) {
\r
346 numOfMedia = maxMedia;
\r
349 int mediaNum = Integer.parseInt(numOfMedia);
\r
350 List mediaFields = new Vector();
\r
351 for (int i = 0; i < mediaNum; i++) {
\r
352 Integer mNum = new Integer(i + 1);
\r
353 mediaFields.add(mNum.toString());
\r
355 mergeData.put("medianum", numOfMedia);
\r
356 mergeData.put("mediafields", mediaFields);
\r
357 mergeData.put("to_topic", null);
\r
359 Map extraInfo = new HashMap();
\r
360 extraInfo.put("languagePopUpData", DatabaseLanguage.getInstance().getPopupData());
\r
361 extraInfo.put("themenPopupData", topicsModule.getTopicsAsSimpleList());
\r
363 extraInfo.put("topics", topicsModule.getTopicsList());
\r
364 deliver(req, res, mergeData, extraInfo, postingFormTemplate);
\r
366 catch (Throwable t) {
\r
367 throw new ServletModuleFailure(t);
\r
372 * Method for inserting an open posting into the Database and delivering
\r
373 * the postingDone Page
\r
376 public void insposting(HttpServletRequest req, HttpServletResponse res) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
\r
378 if (MirGlobal.abuse().getOpenPostingDisabled()) {
\r
379 openPostingDisabled(req, res);
\r
384 Map mergeData = new HashMap();
\r
385 boolean setMedia=false;
\r
386 boolean setTopic = false;
\r
390 WebdbMultipartRequest mp = null;
\r
391 EntityList mediaList = null;
\r
393 // new MediaRequest, "1" is the id for the openPosting user
\r
394 MediaRequest mediaReq = new MediaRequest("1", true);
\r
395 mp = new WebdbMultipartRequest(req, (FileHandler)mediaReq);
\r
396 mediaList = mediaReq.getEntityList();
\r
398 catch (Throwable e) {
\r
399 throw new ServletModuleFailure(e);
\r
402 Map withValues = mp.getParameters();
\r
404 //checking the onetimepasswd
\r
405 HttpSession session = req.getSession(false);
\r
406 String sessionPasswd = (String) session.getAttribute("passwd");
\r
407 if (sessionPasswd != null){
\r
408 String passwd = (String) withValues.get("passwd");
\r
410 logger.debug("session password = " + sessionPasswd + ", form password = " + passwd);
\r
412 if ( passwd == null || passwd.length()==0) {
\r
413 throw new ServletModuleUserExc("posting.error.missingpassword", new String[] {});
\r
415 if (!sessionPasswd.equals(passwd)) {
\r
416 throw new ServletModuleUserExc("posting.error.invalidpassword", new String[] {});
\r
418 session.invalidate();
\r
421 if ((((String)withValues.get("title")).length() == 0) ||
\r
422 (((String)withValues.get("description")).length() == 0) ||
\r
423 (((String)withValues.get("content_data")).length() == 0))
\r
424 throw new ServletModuleUserExc("posting.error.missingfield", new String[] {});
\r
426 // call the routines that escape html
\r
428 for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
\r
429 String k=(String)i.next();
\r
430 String v=(String)withValues.get(k);
\r
432 if (k.equals("content_data")){
\r
433 //this doesn't quite work yet, so for now, all html goes
\r
434 //withValues.put(k,StringUtil.approveHTMLTags(v));
\r
435 withValues.put(k,StringUtil.deleteForbiddenTags(v));
\r
437 else if (k.equals("description")) {
\r
438 String tmp = StringUtil.deleteForbiddenTags(v);
\r
439 withValues.put(k,StringUtil.deleteHTMLTableTags(tmp));
\r
442 withValues.put(k,StringUtil.removeHTMLTags(v));
\r
447 withValues.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
\r
448 withValues.put("publish_path", StringUtil.webdbDate2path((String)withValues.get("date")));
\r
449 withValues.put("is_produced", "0");
\r
450 withValues.put("is_published","1");
\r
451 if (directOp.equals("yes"))
\r
452 withValues.put("to_article_type","1");
\r
454 withValues.put("to_publisher","1");
\r
456 // inserting content into database
\r
457 String cid = contentModule.add(withValues);
\r
458 logger.debug("id: "+cid);
\r
459 //insert was not successfull
\r
462 //How do we know that it was not succesful cause of a
\r
463 //dupe, what if it failed cause of "No space left on device"?
\r
464 //Or is there something I am missing? Wouldn't it be better
\r
465 //to have an explicit dupe check and then insert? I have no
\r
466 //idea what I am talking about. this comment is in case
\r
467 //I forget to explicitely ask. -mh
\r
468 deliver(req, res, mergeData, null, postingFormDupeTemplate);
\r
472 MirGlobal.abuse().logArticle(req.getRemoteAddr(), cid, new Date(), (String) req.getHeader("User-Agent"));
\r
474 String[] to_topicsArr = mp.getParameterValues("to_topic");
\r
476 if (to_topicsArr != null && to_topicsArr.length > 0) {
\r
478 DatabaseContentToTopics.getInstance().setTopics(cid,to_topicsArr);
\r
481 catch (Throwable e) {
\r
482 logger.error("setting content_x_topic failed");
\r
483 contentModule.deleteById(cid);
\r
484 throw new ServletModuleFailure("smod - openindy :: insposting: setting content_x_topic failed: "+e.toString(), e);
\r
488 //if we're here all is ok... associate the media to the article
\r
489 for(int i=0;i<mediaList.size();i++) {
\r
490 Entity mediaEnt = (Entity)mediaList.elementAt(i);
\r
491 DatabaseContentToMedia.getInstance().addMedia(cid,mediaEnt.getId());
\r
494 EntityContent article = (EntityContent) contentModule.getById(cid);
\r
497 MirGlobal.abuse().checkArticle(article, req, res);
\r
498 MirGlobal.localizer().openPostings().afterContentPosting(article);
\r
500 catch (Throwable t) {
\r
501 logger.error("Error while post-processing article: " + t.getMessage());
\r
504 catch (Throwable e) {
\r
505 Throwable cause = ExceptionFunctions.traceCauseException(e);
\r
507 if (cause instanceof UnsupportedMediaFormatExc) {
\r
508 throw new ServletModuleUserExc("media.unsupportedformat", new String[] {} );
\r
510 throw new ServletModuleFailure(e);
\r
513 deliver(req, res, mergeData, null, postingFormDoneTemplate);
\r
517 * Method for preparing and sending a content as an email message
\r
520 public void mail(HttpServletRequest req, HttpServletResponse res)
\r
521 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
\r
523 String aid = req.getParameter("mail_aid");
\r
525 throw new ServletModuleExc("An article id must be specified in requests to email an article. Something therefore went badly wrong....");
\r
528 String to = req.getParameter("mail_to");
\r
529 String from = req.getParameter("mail_from");
\r
530 String from_name = req.getParameter("mail_from_name");
\r
531 String comment = req.getParameter("mail_comment");
\r
532 String mail_language = req.getParameter("mail_language");
\r
534 Map mergeData = new HashMap();
\r
536 if (to == null || from == null || from_name == null|| to.equals("") || from.equals("") || from_name.equals("") || mail_language == null || mail_language.equals("")){
\r
538 for (Enumeration theParams = req.getParameterNames(); theParams.hasMoreElements() ;) {
\r
539 String pName=(String)theParams.nextElement();
\r
540 if (pName.startsWith("mail_")){
\r
541 mergeData.put( pName,req.getParameter(pName) );
\r
545 deliver(req, res, mergeData, null, prepareMailTemplate);
\r
548 //run checks on to and from and mail_language to make sure no monkey business occurring
\r
549 if (mail_language.indexOf('.') != -1 || mail_language.indexOf('/') != -1 ) {
\r
550 throw new ServletModuleExc("Invalid language");
\r
552 if (to.indexOf('\n') != -1
\r
553 || to.indexOf('\r') != -1
\r
554 || to.indexOf(',') != -1) {
\r
555 throw new ServletModuleUserExc("email.error.invalidtoaddress", new String[] {to});
\r
557 if (from.indexOf('\n') != -1 || from.indexOf('\r') != -1 || from.indexOf(',') != -1 ) {
\r
558 throw new ServletModuleUserExc("email.error.invalidfromaddress", new String[] {from});
\r
562 EntityContent contentEnt;
\r
564 contentEnt = (EntityContent)contentModule.getById(aid);
\r
566 catch (Throwable e){
\r
567 throw new ServletModuleFailure("Couldn't get content for article "+aid + ": " + e.getMessage(), e);
\r
569 String producerStorageRoot=configuration.getString("Producer.StorageRoot");
\r
570 String producerDocRoot=configuration.getString("Producer.DocRoot");
\r
571 String publishPath = contentEnt.getValue("publish_path");
\r
572 String txtFilePath = producerStorageRoot + producerDocRoot + "/" + mail_language +
\r
573 publishPath + "/" + aid + ".txt";
\r
576 File inputFile = new File(txtFilePath);
\r
580 FileReader in = new FileReader(inputFile);
\r
581 StringWriter out = new StringWriter();
\r
583 while ((c = in.read()) != -1)
\r
586 content= out.toString();
\r
588 catch (FileNotFoundException e){
\r
589 throw new ServletModuleFailure("No text file found in " + txtFilePath, e);
\r
591 catch (IOException e){
\r
592 throw new ServletModuleFailure("Problem reading file in " + txtFilePath, e);
\r
594 // add some headers
\r
595 content = "To: " + to + "\nReply-To: "+ from + "\n" + content;
\r
596 // put in the comment where it should go
\r
597 if (comment != null) {
\r
598 String commentTextToInsert = "\n\nAttached comment from " + from_name + ":\n" + comment;
\r
600 content=StringRoutines.performRegularExpressionReplacement(content,"!COMMENT!",commentTextToInsert);
\r
602 catch (Throwable e){
\r
603 throw new ServletModuleFailure("Problem doing regular expression replacement " + e.toString(), e);
\r
608 content=StringRoutines.performRegularExpressionReplacement(content,"!COMMENT!","");
\r
610 catch (Throwable e){
\r
611 throw new ServletModuleFailure("Problem doing regular expression replacement " + e.toString(), e);
\r
615 SMTPClient client=new SMTPClient();
\r
618 client.connect(configuration.getString("ServletModule.OpenIndy.SMTPServer"));
\r
620 reply = client.getReplyCode();
\r
622 if (!SMTPReply.isPositiveCompletion(reply)) {
\r
623 client.disconnect();
\r
624 throw new ServletModuleExc("SMTP server refused connection.");
\r
627 client.sendSimpleMessage(configuration.getString("ServletModule.OpenIndy.EmailIsFrom"), to, content);
\r
629 client.disconnect();
\r
630 //mission accomplished
\r
631 deliver(req, res, mergeData, null, sentMailTemplate);
\r
633 catch(IOException e) {
\r
634 if(client.isConnected()) {
\r
636 client.disconnect();
\r
637 } catch(IOException f) {
\r
641 throw new ServletModuleFailure(e);
\r
647 * Method for querying a lucene index
\r
651 * @throws ServletModuleExc
\r
652 * @throws ServletModuleUserExc
\r
653 * @throws ServletModuleFailure
\r
656 public void search(HttpServletRequest req, HttpServletResponse res)
\r
657 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
659 final String[] search_variables = { "search_content", "search_boolean", "search_creator",
\r
660 "search_topic", "search_hasImages", "search_hasAudio", "search_hasVideo", "search_sort",
\r
661 "search_submit", "search_back", "search_forward" };
\r
662 HTTPRequestParser requestParser = new HTTPRequestParser(req);
\r
666 HttpSession session = req.getSession(false);
\r
668 String queryString="";
\r
670 Map mergeData = new HashMap();
\r
672 KeywordSearchTerm dateTerm = new KeywordSearchTerm("date_formatted","search_date","webdb_create_formatted","webdb_create_formatted","webdb_create_formatted");
\r
673 UnIndexedSearchTerm whereTerm = new UnIndexedSearchTerm("","","","where","where");
\r
674 TextSearchTerm creatorTerm = new TextSearchTerm("creator","search_creator","creator","creator","creator");
\r
675 TextSearchTerm titleTerm = new TextSearchTerm("title","search_content","title","title","title");
\r
676 TextSearchTerm descriptionTerm = new TextSearchTerm("description","search_content","description","description","description");
\r
677 ContentSearchTerm contentTerm = new ContentSearchTerm("content_data","search_content","content","","");
\r
678 TopicSearchTerm topicTerm = new TopicSearchTerm();
\r
679 ImagesSearchTerm imagesTerm = new ImagesSearchTerm();
\r
680 AudioSearchTerm audioTerm = new AudioSearchTerm();
\r
681 VideoSearchTerm videoTerm = new VideoSearchTerm();
\r
683 //make the query available to subsequent iterations
\r
685 Iterator j = Arrays.asList(search_variables).iterator();
\r
686 while (j.hasNext()) {
\r
687 String variable = (String) j.next();
\r
689 mergeData.put(variable, requestParser.getParameter(variable));
\r
693 mergeData.put("topics", topicsModule.getTopicsAsSimpleList());
\r
695 catch(Throwable e) {
\r
696 logger.debug("Can't get topics: " + e.toString());
\r
699 String searchBackValue = req.getParameter("search_back");
\r
700 String searchForwardValue = req.getParameter("search_forward");
\r
702 if (searchBackValue != null){
\r
703 int totalHits = ((Integer) session.getAttribute("numberOfHits")).intValue();
\r
704 int newPosition=((Integer)session.getAttribute("positionInResults")).intValue()-increment;
\r
707 if (newPosition >= totalHits)
\r
708 newPosition=totalHits-1;
\r
709 session.setAttribute("positionInResults",new Integer(newPosition));
\r
712 if (searchForwardValue != null){
\r
713 int totalHits = ((Integer) session.getAttribute("numberOfHits")).intValue();
\r
714 int newPosition=((Integer)session.getAttribute("positionInResults")).intValue()+increment;
\r
717 if (newPosition >= totalHits)
\r
718 newPosition=totalHits-1;
\r
720 session.setAttribute("positionInResults",new Integer(newPosition));
\r
723 String indexPath=configuration.getString("IndexPath");
\r
726 String creatorFragment = creatorTerm.makeTerm(req);
\r
727 if (creatorFragment != null){
\r
728 queryString = queryString + " +" + creatorFragment;
\r
731 // search title, description, and content for something
\r
732 // the contentTerm uses param "search_boolean" to combine its terms
\r
733 String contentFragment = contentTerm.makeTerm(req);
\r
734 if (contentFragment != null){
\r
735 logger.debug("contentFragment: " + contentFragment);
\r
736 queryString = queryString + " +" + contentFragment;
\r
739 String topicFragment = topicTerm.makeTerm(req);
\r
740 if (topicFragment != null){
\r
741 queryString = queryString + " +" + topicFragment;
\r
744 String imagesFragment = imagesTerm.makeTerm(req);
\r
745 if (imagesFragment != null){
\r
746 queryString = queryString + " +" + imagesFragment;
\r
749 String audioFragment = audioTerm.makeTerm(req);
\r
750 if (audioFragment != null){
\r
751 queryString = queryString + " +" + audioFragment;
\r
754 String videoFragment = videoTerm.makeTerm(req);
\r
755 if (videoFragment != null){
\r
756 queryString = queryString + " +" + videoFragment;
\r
759 if (queryString == null || queryString == ""){
\r
764 Searcher searcher = null;
\r
766 searcher = new IndexSearcher(indexPath);
\r
768 catch(IOException e) {
\r
769 logger.debug("Can't open indexPath: " + indexPath);
\r
770 throw new ServletModuleExc("Problem with Search Index! : "+ e.toString());
\r
773 Query query = null;
\r
775 query = QueryParser.parse(queryString, "content", new StandardAnalyzer());
\r
777 catch(Exception e) {
\r
779 logger.debug("Query don't parse: " + queryString);
\r
780 throw new ServletModuleExc("Problem with Query String! (was '"+queryString+"')");
\r
785 hits = searcher.search(query);
\r
787 catch(IOException e) {
\r
789 logger.debug("Can't get hits: " + e.toString());
\r
790 throw new ServletModuleExc("Problem getting hits!");
\r
794 int end = hits.length();
\r
796 String sortBy=req.getParameter("search_sort");
\r
797 if (sortBy == null || sortBy.equals("")){
\r
798 throw new ServletModuleExc("Please let me sort by something!(missing search_sort)");
\r
801 // here is where the documents will go for storage across sessions
\r
802 ArrayList theDocumentsSorted = new ArrayList();
\r
804 if (sortBy.equals("score")){
\r
805 for(int i = start; i < end; i++) {
\r
806 theDocumentsSorted.add(hits.doc(i));
\r
810 // then we'll sort by date!
\r
811 Map dateToPosition = new HashMap(end,1.0F); //we know how big it will be
\r
812 for(int i = start; i < end; i++) {
\r
813 String creationDate=(hits.doc(i)).get("creationDate");
\r
814 // do a little dance in case two contents created at the same second!
\r
815 if (dateToPosition.containsKey(creationDate)){
\r
816 ((ArrayList) (dateToPosition.get(creationDate))).add(new Integer(i));
\r
819 ArrayList thePositions = new ArrayList();
\r
820 thePositions.add(new Integer(i));
\r
821 dateToPosition.put(creationDate,thePositions);
\r
824 Set keys = dateToPosition.keySet();
\r
825 ArrayList keyList= new ArrayList(keys);
\r
826 Collections.sort(keyList);
\r
827 if (sortBy.equals("date_desc")){
\r
828 Collections.reverse(keyList);
\r
831 if (!sortBy.equals("date_asc")){
\r
832 throw new ServletModuleExc("don't know how to sort by: "+ sortBy);
\r
835 ListIterator keyTraverser = keyList.listIterator();
\r
836 while (keyTraverser.hasNext()){
\r
837 ArrayList positions = (ArrayList)dateToPosition.get((keyTraverser.next()));
\r
838 ListIterator positionsTraverser=positions.listIterator();
\r
839 while (positionsTraverser.hasNext()){
\r
840 theDocumentsSorted.add(hits.doc(((Integer)(positionsTraverser.next())).intValue()));
\r
848 catch (IOException e){
\r
849 logger.debug("Can't close searcher: " + e.toString());
\r
850 throw new ServletModuleFailure("Problem closing searcher(normal):" + e.getMessage(), e);
\r
854 session.removeAttribute("numberOfHits");
\r
855 session.removeAttribute("theDocumentsSorted");
\r
856 session.removeAttribute("positionInResults");
\r
858 session.setAttribute("numberOfHits",new Integer(end));
\r
859 session.setAttribute("theDocumentsSorted",theDocumentsSorted);
\r
860 session.setAttribute("positionInResults",new Integer(0));
\r
863 catch (IOException e){
\r
864 logger.debug("Can't close searcher: " + e.toString());
\r
865 throw new ServletModuleFailure("Problem closing searcher: " + e.getMessage(), e);
\r
872 ArrayList theDocs = (ArrayList)session.getAttribute("theDocumentsSorted");
\r
873 if (theDocs != null){
\r
875 mergeData.put("numberOfHits", ((Integer)session.getAttribute("numberOfHits")).toString());
\r
876 List theHits = new Vector();
\r
877 int pIR=((Integer)session.getAttribute("positionInResults")).intValue();
\r
879 int numHits=((Integer)session.getAttribute("numberOfHits")).intValue();
\r
881 if (!(pIR+increment>=numHits)){
\r
882 mergeData.put("hasNext","y");
\r
885 mergeData.put("hasNext", null);
\r
888 mergeData.put("hasPrevious","y");
\r
891 mergeData.put("hasPrevious", null);
\r
894 if ((pIR+increment)>numHits){
\r
898 terminus=pIR+increment;
\r
900 for(int i = pIR; i < terminus; i++) {
\r
901 Map h = new HashMap();
\r
902 Document theHit = (Document)theDocs.get(i);
\r
903 whereTerm.returnMeta(h,theHit);
\r
904 creatorTerm.returnMeta(h,theHit);
\r
905 titleTerm.returnMeta(h,theHit);
\r
906 descriptionTerm.returnMeta(h,theHit);
\r
907 dateTerm.returnMeta(h,theHit);
\r
908 imagesTerm.returnMeta(h,theHit);
\r
909 audioTerm.returnMeta(h,theHit);
\r
910 videoTerm.returnMeta(h,theHit);
\r
913 mergeData.put("hits",theHits);
\r
916 catch (Throwable e) {
\r
917 logger.error("Can't iterate over hits: " + e.toString());
\r
919 throw new ServletModuleFailure("Problem getting hits: " + e.getMessage(), e);
\r
922 mergeData.put("queryString",queryString);
\r
924 deliver(req, res, mergeData, null, searchResultsTemplate);
\r
926 catch (NullPointerException n){
\r
927 throw new ServletModuleFailure("Null Pointer: "+n.toString(), n);
\r
932 * Method for dynamically generating a pdf from a fo file
\r
934 public void getpdf(HttpServletRequest req, HttpServletResponse res)
\r
935 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
936 String ID_REQUEST_PARAM = "id";
\r
937 String language = req.getParameter("language");
\r
938 String generateFO=configuration.getString("GenerateFO");
\r
939 String generatePDF=configuration.getString("GeneratePDF");
\r
942 //don't do anything if we are not making FO files, or if we are
\r
943 //pregenerating PDF's
\r
944 if (generateFO.equals("yes") && generatePDF.equals("no")){
\r
945 //fop complains unless you do the logging this way
\r
946 org.apache.log.Logger log = null;
\r
947 Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
\r
948 log = hierarchy.getLoggerFor("fop");
\r
949 log.setPriority(Priority.WARN);
\r
951 String producerStorageRoot=configuration.getString("Producer.StorageRoot");
\r
952 String producerDocRoot=configuration.getString("Producer.DocRoot");
\r
953 // String templateDir=MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
\r
954 String xslSheet=configuration.getString("Producer.HTML2FOStyleSheet");
\r
956 String idParam = req.getParameter(ID_REQUEST_PARAM);
\r
957 if (idParam != null) {
\r
958 EntityContent contentEnt =
\r
959 (EntityContent)contentModule.getById(idParam);
\r
960 String publishPath = StringUtil.webdbDate2path(contentEnt.getValue("date"));
\r
963 if (language == null){
\r
964 foFile = producerStorageRoot + producerDocRoot + "/"
\r
965 + publishPath + idParam + ".fo";
\r
968 foFile = producerStorageRoot + producerDocRoot + "/"
\r
969 + language + publishPath + idParam + ".fo";
\r
971 logger.debug("USING FILES" + foFile + " and " + xslSheet);
\r
972 XSLTInputHandler input = new XSLTInputHandler(new File(foFile),
\r
973 new File(xslSheet));
\r
975 ByteArrayOutputStream out = new ByteArrayOutputStream();
\r
976 res.setContentType("application/pdf");
\r
978 Driver driver = new Driver();
\r
979 driver.setLogger(log);
\r
980 driver.setRenderer(Driver.RENDER_PDF);
\r
981 driver.setOutputStream(out);
\r
982 driver.render(input.getParser(), input.getInputSource());
\r
984 byte[] content = out.toByteArray();
\r
985 res.setContentLength(content.length);
\r
986 res.getOutputStream().write(content);
\r
987 res.getOutputStream().flush();
\r
990 throw new ServletModuleExc("Missing id.");
\r
993 catch (Throwable t) {
\r
994 logger.error(t.toString());
\r
996 throw new ServletModuleFailure(t);
\r
1000 throw new ServletModuleExc("Can't generate a PDF because the config tells me not to.");
\r
1004 protected String createOneTimePasswd(){
\r
1005 Random r = new Random();
\r
1006 int random = r.nextInt();
\r
1007 long l = System.currentTimeMillis();
\r
1008 l = (l*l*l*l)/random;
\r
1009 if(l<0) l = l * -1;
\r
1010 String returnString = ""+l;
\r
1012 return returnString.substring(5);
\r
1016 /* this is an overwritten method of ServletModule in order
\r
1017 to use different bundles for open and admin */
\r
1018 /* public void deliver(HttpServletRequest req, HttpServletResponse res,
\r
1019 TemplateModelRoot rtm, TemplateModelRoot popups,
\r
1020 String templateFilename) throws ServletModuleFailure
\r
1024 public void deliver(HttpServletRequest aRequest, HttpServletResponse aResponse, Map aData, Map anExtra, String aGenerator)
\r
1025 throws ServletModuleFailure {
\r
1027 deliver(aResponse.getWriter(), aRequest, aResponse, aData, anExtra, aGenerator);
\r
1029 catch (Throwable t) {
\r
1030 throw new ServletModuleFailure(t);
\r
1034 public void deliver(PrintWriter anOutputWriter, HttpServletRequest aRequest, HttpServletResponse aResponse, Map aData, Map anExtra, String aGenerator)
\r
1035 throws ServletModuleFailure {
\r
1037 Map responseData = ServletHelper.makeGenerationData(getLocale(aRequest), "bundles.open");
\r
1038 responseData.put("data", aData);
\r
1039 responseData.put("extra", anExtra);
\r
1042 Generator generator = MirGlobal.localizer().generators().makeOpenPostingGeneratorLibrary().makeGenerator(aGenerator);
\r
1043 generator.generate(anOutputWriter, responseData, logger.asPrintWriter(logger.INFO_MESSAGE));
\r
1045 anOutputWriter.close();
\r
1047 catch (Throwable e) {
\r
1048 logger.error("Error while generating " + aGenerator + ": " + e.getMessage());
\r
1050 throw new ServletModuleFailure(e);
\r
1054 public void handleError(HttpServletRequest aRequest, HttpServletResponse aResponse,PrintWriter out, Throwable anException) {
\r
1056 logger.error("error: " + anException);
\r
1057 Map data = new HashMap();
\r
1059 data.put("errorstring", anException.getMessage());
\r
1060 data.put("date", StringUtil.date2readableDateTime(new GregorianCalendar()));
\r
1062 deliver(out, aRequest, aResponse, data, null, configuration.getString("ServletModule.OpenIndy.ErrorTemplate"));
\r
1064 catch (Throwable e) {
\r
1065 throw new ServletModuleFailure(e);
\r
1069 public void handleUserError(HttpServletRequest aRequest, HttpServletResponse aResponse,
\r
1070 PrintWriter out, ServletModuleUserExc anException) {
\r
1072 logger.warn("user error: " + anException.getMessage());
\r
1073 Map data = new HashMap();
\r
1075 MessageResources messages = MessageResources.getMessageResources("bundles.open");
\r
1076 data.put("errorstring",
\r
1077 messages.getMessage(getLocale(aRequest), anException.getMessage(), anException.getParameters())
\r
1079 data.put("date", StringUtil.date2readableDateTime(new GregorianCalendar()));
\r
1081 deliver(out, aRequest, aResponse, data, null, configuration.getString("ServletModule.OpenIndy.UserErrorTemplate"));
\r
1083 catch (Throwable e) {
\r
1084 throw new ServletModuleFailure(e);
\r