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.Collections;
\r
43 import java.util.Date;
\r
44 import java.util.Enumeration;
\r
45 import java.util.GregorianCalendar;
\r
46 import java.util.HashMap;
\r
47 import java.util.Iterator;
\r
48 import java.util.List;
\r
49 import java.util.ListIterator;
\r
50 import java.util.Map;
\r
51 import java.util.Random;
\r
52 import java.util.Set;
\r
53 import java.util.Vector;
\r
54 import javax.servlet.http.HttpServletRequest;
\r
55 import javax.servlet.http.HttpServletResponse;
\r
56 import javax.servlet.http.HttpSession;
\r
58 import org.apache.commons.net.smtp.SMTPClient;
\r
59 import org.apache.commons.net.smtp.SMTPReply;
\r
60 import org.apache.fop.apps.Driver;
\r
61 import org.apache.fop.apps.XSLTInputHandler;
\r
62 import org.apache.log.Hierarchy;
\r
63 import org.apache.log.Priority;
\r
64 import org.apache.lucene.analysis.standard.StandardAnalyzer;
\r
65 import org.apache.lucene.document.Document;
\r
66 import org.apache.lucene.queryParser.QueryParser;
\r
67 import org.apache.lucene.search.Hits;
\r
68 import org.apache.lucene.search.IndexSearcher;
\r
69 import org.apache.lucene.search.Query;
\r
70 import org.apache.lucene.search.Searcher;
\r
71 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.StringRoutines;
\r
87 import mircoders.entity.EntityComment;
\r
88 import mircoders.entity.EntityContent;
\r
89 import mircoders.global.MirGlobal;
\r
90 import mircoders.media.MediaRequest;
\r
91 import mircoders.media.UnsupportedMediaFormatExc;
\r
92 import mircoders.module.ModuleComment;
\r
93 import mircoders.module.ModuleContent;
\r
94 import mircoders.module.ModuleImages;
\r
95 import mircoders.module.ModuleTopics;
\r
96 import mircoders.search.AudioSearchTerm;
\r
97 import mircoders.search.ContentSearchTerm;
\r
98 import mircoders.search.ImagesSearchTerm;
\r
99 import mircoders.search.KeywordSearchTerm;
\r
100 import mircoders.search.TextSearchTerm;
\r
101 import mircoders.search.TopicSearchTerm;
\r
102 import mircoders.search.UnIndexedSearchTerm;
\r
103 import mircoders.search.VideoSearchTerm;
\r
104 import mircoders.storage.DatabaseComment;
\r
105 import mircoders.storage.DatabaseContent;
\r
106 import mircoders.storage.DatabaseContentToMedia;
\r
107 import mircoders.storage.DatabaseContentToTopics;
\r
108 import mircoders.storage.DatabaseImages;
\r
109 import mircoders.storage.DatabaseLanguage;
\r
110 import mircoders.storage.DatabaseTopics;
\r
113 * ServletModuleOpenIndy -
\r
114 * is the open-access-servlet, which is responsible for
\r
115 * adding comments to articles &
\r
116 * open-postings to the newswire
\r
118 * @author mir-coders group
\r
119 * @version $Id: ServletModuleOpenIndy.java,v 1.69 2003/03/17 20:47:04 zapata Exp $
\r
123 public class ServletModuleOpenIndy extends ServletModule
\r
126 private String commentFormTemplate, commentFormDoneTemplate, commentFormDupeTemplate;
\r
127 private String postingFormTemplate, postingFormDoneTemplate, postingFormDupeTemplate;
\r
128 private String searchResultsTemplate;
\r
129 private String prepareMailTemplate,sentMailTemplate;
\r
130 private ModuleContent contentModule;
\r
131 private ModuleComment commentModule;
\r
132 private ModuleImages imageModule;
\r
133 private ModuleTopics topicsModule;
\r
134 private String directOp ="yes";
\r
135 // Singelton / Kontruktor
\r
136 private static ServletModuleOpenIndy instance = new ServletModuleOpenIndy();
\r
137 public static ServletModule getInstance() { return instance; }
\r
139 private ServletModuleOpenIndy() {
\r
142 logger = new LoggerWrapper("ServletModule.OpenIndy");
\r
144 commentFormTemplate = configuration.getString("ServletModule.OpenIndy.CommentTemplate");
\r
145 commentFormDoneTemplate = configuration.getString("ServletModule.OpenIndy.CommentDoneTemplate");
\r
146 commentFormDupeTemplate = configuration.getString("ServletModule.OpenIndy.CommentDupeTemplate");
\r
147 postingFormTemplate = configuration.getString("ServletModule.OpenIndy.PostingTemplate");
\r
148 postingFormDoneTemplate = configuration.getString("ServletModule.OpenIndy.PostingDoneTemplate");
\r
149 postingFormDupeTemplate = configuration.getString("ServletModule.OpenIndy.PostingDupeTemplate");
\r
150 searchResultsTemplate = configuration.getString("ServletModule.OpenIndy.SearchResultsTemplate");
\r
151 prepareMailTemplate = configuration.getString("ServletModule.OpenIndy.PrepareMailTemplate");
\r
152 sentMailTemplate = configuration.getString("ServletModule.OpenIndy.SentMailTemplate");
\r
153 directOp = configuration.getString("DirectOpenposting").toLowerCase();
\r
154 mainModule = new ModuleComment(DatabaseComment.getInstance());
\r
155 contentModule = new ModuleContent(DatabaseContent.getInstance());
\r
156 topicsModule = new ModuleTopics(DatabaseTopics.getInstance());
\r
157 imageModule = new ModuleImages(DatabaseImages.getInstance());
\r
158 defaultAction="addposting";
\r
160 catch (StorageObjectFailure e) {
\r
161 logger.error("servletmoduleopenindy could not be initialized: " + e.getMessage());
\r
166 * Method to return an "apology" when open postings are disabled
\r
170 * @throws ServletModuleExc
\r
171 * @throws ServletModuleUserExc
\r
172 * @throws ServletModuleFailure
\r
174 public void openPostingDisabled(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
175 deliver(aRequest, aResponse, (Map) null, null,
\r
176 configuration.getString("ServletModule.OpenIndy.PostingDisabledTemplate"));
\r
181 * Method for making a comment
\r
184 public void addcomment(HttpServletRequest req, HttpServletResponse res) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
\r
186 if (MirGlobal.abuse().getOpenPostingDisabled()) {
\r
187 openPostingDisabled(req, res);
\r
192 String aid = req.getParameter("aid"); // the article id the comment will belong to
\r
194 String language = req.getParameter("language");
\r
197 if (aid!=null && !aid.equals("")) {
\r
199 Map mergeData = new HashMap();
\r
202 if (MirGlobal.abuse().getOpenPostingPassword()) {
\r
203 String passwd = this.createOneTimePasswd();
\r
204 HttpSession session = req.getSession(false);
\r
205 session.setAttribute("passwd", passwd);
\r
206 mergeData.put("passwd", passwd);
\r
209 mergeData.put("passwd", (String) null);
\r
212 if (language != null) {
\r
213 HttpSession session = req.getSession(false);
\r
214 session.setAttribute("Locale", new Locale(language, ""));
\r
215 session.setAttribute("language", language);
\r
218 mergeData.put("aid", aid);
\r
220 Map extraInfo = new HashMap();
\r
221 extraInfo.put("languagePopUpData", DatabaseLanguage.getInstance().getPopupData());
\r
223 deliver(req, res, mergeData, extraInfo, commentFormTemplate);
\r
225 catch (Throwable t) {
\r
226 throw new ServletModuleFailure("ServletModuleOpenIndy.addcomment: " + t.getMessage(), t);
\r
229 else throw new ServletModuleExc("aid not set!");
\r
233 * Method for inserting a comment into the Database and delivering
\r
234 * the commentDone Page
\r
237 public void inscomment(HttpServletRequest req, HttpServletResponse res)
\r
238 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
\r
240 if (MirGlobal.abuse().getOpenPostingDisabled()) {
\r
241 openPostingDisabled(req, res);
\r
246 String aid = req.getParameter("to_media"); // the article id the comment will belong to
\r
247 if (aid!=null && !aid.equals(""))
\r
249 // ok, collecting data from form
\r
251 Map withValues = getIntersectingValues(req, DatabaseComment.getInstance());
\r
253 //no html in comments(for now)
\r
254 for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
\r
255 String k=(String)i.next();
\r
256 String v=(String)withValues.get(k);
\r
258 withValues.put(k,StringUtil.removeHTMLTags(v));
\r
260 withValues.put("is_published","1");
\r
261 withValues.put("to_comment_status","1");
\r
263 //checking the onetimepasswd
\r
264 HttpSession session = req.getSession(false);
\r
265 String sessionPasswd = (String) session.getAttribute("passwd");
\r
266 if ( sessionPasswd != null){
\r
267 String passwd = req.getParameter("passwd");
\r
268 if ( passwd == null || passwd.length()==0) {
\r
269 throw new ServletModuleUserExc("comment.error.missingpassword", new String[] {});
\r
271 if (!sessionPasswd.equals(passwd)) {
\r
272 throw new ServletModuleUserExc("comment.error.invalidpassword", new String[] {});
\r
274 session.invalidate();
\r
277 String id = mainModule.add(withValues);
\r
280 deliver(req, res, (Map) null, null, commentFormDupeTemplate);
\r
283 MirGlobal.abuse().logComment(req.getRemoteAddr(), id, new Date(), (String) req.getHeader("User-Agent"));
\r
285 DatabaseContent.getInstance().setUnproduced("id="+aid);
\r
288 EntityComment comment = (EntityComment) DatabaseComment.getInstance().selectById(id);
\r
289 MirGlobal.abuse().checkComment(comment, req, res);
\r
290 MirGlobal.localizer().openPostings().afterCommentPosting(comment);
\r
292 catch (Throwable t) {
\r
293 throw new ServletModuleExc(t.getMessage());
\r
297 // redirecting to url
\r
298 // should implement back to article
\r
299 Map mergeData = new HashMap();
\r
300 deliver(req, res, mergeData, null, commentFormDoneTemplate);
\r
302 catch (Throwable e) {
\r
303 throw new ServletModuleFailure(e);
\r
306 else throw new ServletModuleExc("aid not set!");
\r
311 * Method for delivering the form-Page for open posting
\r
314 public void addposting(HttpServletRequest req, HttpServletResponse res)
\r
315 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
\r
318 if (MirGlobal.abuse().getOpenPostingDisabled()) {
\r
319 openPostingDisabled(req, res);
\r
324 Map mergeData = new HashMap();
\r
327 if (MirGlobal.abuse().getOpenPostingPassword()) {
\r
328 String passwd = this.createOneTimePasswd();
\r
329 HttpSession session = req.getSession(false);
\r
330 session.setAttribute("passwd", passwd);
\r
331 mergeData.put("passwd", passwd);
\r
334 mergeData.put("passwd", (String)null);
\r
337 String maxMedia = configuration.getString("ServletModule.OpenIndy.MaxMediaUploadItems");
\r
338 String defaultMedia = configuration.getString("ServletModule.OpenIndy.DefaultMediaUploadItems");
\r
339 String numOfMedia = req.getParameter("medianum");
\r
341 if (numOfMedia == null || numOfMedia.equals("")) {
\r
342 numOfMedia = defaultMedia;
\r
344 else if (Integer.parseInt(numOfMedia) > Integer.parseInt(maxMedia)) {
\r
345 numOfMedia = maxMedia;
\r
348 int mediaNum = Integer.parseInt(numOfMedia);
\r
349 List mediaFields = new Vector();
\r
350 for (int i = 0; i < mediaNum; i++) {
\r
351 Integer mNum = new Integer(i + 1);
\r
352 mediaFields.add(mNum.toString());
\r
354 mergeData.put("medianum", numOfMedia);
\r
355 mergeData.put("mediafields", mediaFields);
\r
356 mergeData.put("to_topic", null);
\r
358 Map extraInfo = new HashMap();
\r
359 extraInfo.put("languagePopUpData", DatabaseLanguage.getInstance().getPopupData());
\r
360 extraInfo.put("themenPopupData", topicsModule.getTopicsAsSimpleList());
\r
362 extraInfo.put("topics", topicsModule.getTopicsList());
\r
363 deliver(req, res, mergeData, extraInfo, postingFormTemplate);
\r
365 catch (Throwable t) {
\r
366 throw new ServletModuleFailure(t);
\r
371 * Method for inserting an open posting into the Database and delivering
\r
372 * the postingDone Page
\r
375 public void insposting(HttpServletRequest req, HttpServletResponse res) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
\r
377 if (MirGlobal.abuse().getOpenPostingDisabled()) {
\r
378 openPostingDisabled(req, res);
\r
383 Map mergeData = new HashMap();
\r
384 boolean setMedia=false;
\r
385 boolean setTopic = false;
\r
389 WebdbMultipartRequest mp = null;
\r
390 EntityList mediaList = null;
\r
392 // new MediaRequest, "1" is the id for the openPosting user
\r
393 MediaRequest mediaReq = new MediaRequest("1", true);
\r
394 mp = new WebdbMultipartRequest(req, (FileHandler)mediaReq);
\r
395 mediaList = mediaReq.getEntityList();
\r
397 catch (Throwable e) {
\r
398 throw new ServletModuleFailure(e);
\r
401 Map withValues = mp.getParameters();
\r
403 //checking the onetimepasswd
\r
404 HttpSession session = req.getSession(false);
\r
405 String sessionPasswd = (String) session.getAttribute("passwd");
\r
406 if (sessionPasswd != null){
\r
407 String passwd = (String) withValues.get("passwd");
\r
409 logger.debug("session password = " + sessionPasswd + ", form password = " + passwd);
\r
411 if ( passwd == null || passwd.length()==0) {
\r
412 throw new ServletModuleUserExc("posting.error.missingpassword", new String[] {});
\r
414 if (!sessionPasswd.equals(passwd)) {
\r
415 throw new ServletModuleUserExc("posting.error.invalidpassword", new String[] {});
\r
417 session.invalidate();
\r
420 if ((((String)withValues.get("title")).length() == 0) ||
\r
421 (((String)withValues.get("description")).length() == 0) ||
\r
422 (((String)withValues.get("content_data")).length() == 0))
\r
423 throw new ServletModuleUserExc("posting.error.missingfield", new String[] {});
\r
425 // call the routines that escape html
\r
427 for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
\r
428 String k=(String)i.next();
\r
429 String v=(String)withValues.get(k);
\r
431 if (k.equals("content_data")){
\r
432 //this doesn't quite work yet, so for now, all html goes
\r
433 //withValues.put(k,StringUtil.approveHTMLTags(v));
\r
434 withValues.put(k,StringUtil.deleteForbiddenTags(v));
\r
436 else if (k.equals("description")) {
\r
437 String tmp = StringUtil.deleteForbiddenTags(v);
\r
438 withValues.put(k,StringUtil.deleteHTMLTableTags(tmp));
\r
441 withValues.put(k,StringUtil.removeHTMLTags(v));
\r
446 withValues.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
\r
447 withValues.put("publish_path", StringUtil.webdbDate2path((String)withValues.get("date")));
\r
448 withValues.put("is_produced", "0");
\r
449 withValues.put("is_published","1");
\r
450 if (directOp.equals("yes"))
\r
451 withValues.put("to_article_type","1");
\r
453 withValues.put("to_publisher","1");
\r
455 // inserting content into database
\r
456 String cid = contentModule.add(withValues);
\r
457 logger.debug("id: "+cid);
\r
458 //insert was not successfull
\r
461 //How do we know that it was not succesful cause of a
\r
462 //dupe, what if it failed cause of "No space left on device"?
\r
463 //Or is there something I am missing? Wouldn't it be better
\r
464 //to have an explicit dupe check and then insert? I have no
\r
465 //idea what I am talking about. this comment is in case
\r
466 //I forget to explicitely ask. -mh
\r
467 deliver(req, res, mergeData, null, postingFormDupeTemplate);
\r
471 MirGlobal.abuse().logArticle(req.getRemoteAddr(), cid, new Date(), (String) req.getHeader("User-Agent"));
\r
473 String[] to_topicsArr = mp.getParameterValues("to_topic");
\r
475 if (to_topicsArr != null && to_topicsArr.length > 0) {
\r
477 DatabaseContentToTopics.getInstance().setTopics(cid,to_topicsArr);
\r
480 catch (Throwable e) {
\r
481 logger.error("setting content_x_topic failed");
\r
482 contentModule.deleteById(cid);
\r
483 throw new ServletModuleFailure("smod - openindy :: insposting: setting content_x_topic failed: "+e.toString(), e);
\r
487 //if we're here all is ok... associate the media to the article
\r
488 for(int i=0;i<mediaList.size();i++) {
\r
489 Entity mediaEnt = (Entity)mediaList.elementAt(i);
\r
490 DatabaseContentToMedia.getInstance().addMedia(cid,mediaEnt.getId());
\r
493 EntityContent article = (EntityContent) contentModule.getById(cid);
\r
496 MirGlobal.abuse().checkArticle(article, req, res);
\r
497 MirGlobal.localizer().openPostings().afterContentPosting(article);
\r
499 catch (Throwable t) {
\r
500 logger.error("Error while post-processing article: " + t.getMessage());
\r
503 catch (Throwable e) {
\r
504 Throwable cause = ExceptionFunctions.traceCauseException(e);
\r
506 if (cause instanceof UnsupportedMediaFormatExc) {
\r
507 throw new ServletModuleUserExc("media.unsupportedformat", new String[] {} );
\r
509 throw new ServletModuleFailure(e);
\r
512 deliver(req, res, mergeData, null, postingFormDoneTemplate);
\r
516 * Method for preparing and sending a content as an email message
\r
519 public void mail(HttpServletRequest req, HttpServletResponse res)
\r
520 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
\r
522 String aid = req.getParameter("mail_aid");
\r
524 throw new ServletModuleExc("An article id must be specified in requests to email an article. Something therefore went badly wrong....");
\r
527 String to = req.getParameter("mail_to");
\r
528 String from = req.getParameter("mail_from");
\r
529 String from_name = req.getParameter("mail_from_name");
\r
530 String comment = req.getParameter("mail_comment");
\r
531 String mail_language = req.getParameter("mail_language");
\r
533 Map mergeData = new HashMap();
\r
535 if (to == null || from == null || from_name == null|| to.equals("") || from.equals("") || from_name.equals("") || mail_language == null || mail_language.equals("")){
\r
537 for (Enumeration theParams = req.getParameterNames(); theParams.hasMoreElements() ;) {
\r
538 String pName=(String)theParams.nextElement();
\r
539 if (pName.startsWith("mail_")){
\r
540 mergeData.put( pName,req.getParameter(pName) );
\r
544 deliver(req, res, mergeData, null, prepareMailTemplate);
\r
547 //run checks on to and from and mail_language to make sure no monkey business occurring
\r
548 if (mail_language.indexOf('.') != -1 || mail_language.indexOf('/') != -1 ) {
\r
549 throw new ServletModuleExc("Invalid language");
\r
551 if (to.indexOf('\n') != -1
\r
552 || to.indexOf('\r') != -1
\r
553 || to.indexOf(',') != -1) {
\r
554 throw new ServletModuleUserExc("email.error.invalidtoaddress", new String[] {to});
\r
556 if (from.indexOf('\n') != -1 || from.indexOf('\r') != -1 || from.indexOf(',') != -1 ) {
\r
557 throw new ServletModuleUserExc("email.error.invalidfromaddress", new String[] {from});
\r
561 EntityContent contentEnt;
\r
563 contentEnt = (EntityContent)contentModule.getById(aid);
\r
565 catch (Throwable e){
\r
566 throw new ServletModuleFailure("Couldn't get content for article "+aid + ": " + e.getMessage(), e);
\r
568 String producerStorageRoot=configuration.getString("Producer.StorageRoot");
\r
569 String producerDocRoot=configuration.getString("Producer.DocRoot");
\r
570 String publishPath = contentEnt.getValue("publish_path");
\r
571 String txtFilePath = producerStorageRoot + producerDocRoot + "/" + mail_language +
\r
572 publishPath + "/" + aid + ".txt";
\r
575 File inputFile = new File(txtFilePath);
\r
579 FileReader in = new FileReader(inputFile);
\r
580 StringWriter out = new StringWriter();
\r
582 while ((c = in.read()) != -1)
\r
585 content= out.toString();
\r
587 catch (FileNotFoundException e){
\r
588 throw new ServletModuleFailure("No text file found in " + txtFilePath, e);
\r
590 catch (IOException e){
\r
591 throw new ServletModuleFailure("Problem reading file in " + txtFilePath, e);
\r
593 // add some headers
\r
594 content = "To: " + to + "\nReply-To: "+ from + "\n" + content;
\r
595 // put in the comment where it should go
\r
596 if (comment != null) {
\r
597 String commentTextToInsert = "\n\nAttached comment from " + from_name + ":\n" + comment;
\r
599 content=StringRoutines.performRegularExpressionReplacement(content,"!COMMENT!",commentTextToInsert);
\r
601 catch (Throwable e){
\r
602 throw new ServletModuleFailure("Problem doing regular expression replacement " + e.toString(), e);
\r
607 content=StringRoutines.performRegularExpressionReplacement(content,"!COMMENT!","");
\r
609 catch (Throwable e){
\r
610 throw new ServletModuleFailure("Problem doing regular expression replacement " + e.toString(), e);
\r
614 SMTPClient client=new SMTPClient();
\r
617 client.connect(configuration.getString("ServletModule.OpenIndy.SMTPServer"));
\r
619 reply = client.getReplyCode();
\r
621 if (!SMTPReply.isPositiveCompletion(reply)) {
\r
622 client.disconnect();
\r
623 throw new ServletModuleExc("SMTP server refused connection.");
\r
626 client.sendSimpleMessage(configuration.getString("ServletModule.OpenIndy.EmailIsFrom"), to, content);
\r
628 client.disconnect();
\r
629 //mission accomplished
\r
630 deliver(req, res, mergeData, null, sentMailTemplate);
\r
632 catch(IOException e) {
\r
633 if(client.isConnected()) {
\r
635 client.disconnect();
\r
636 } catch(IOException f) {
\r
640 throw new ServletModuleFailure(e);
\r
646 * Method for querying a lucene index
\r
650 * @throws ServletModuleExc
\r
651 * @throws ServletModuleUserExc
\r
652 * @throws ServletModuleFailure
\r
655 public void search(HttpServletRequest req, HttpServletResponse res)
\r
656 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
660 HttpSession session = req.getSession(false);
\r
662 String queryString="";
\r
664 Map mergeData = new HashMap();
\r
666 KeywordSearchTerm dateTerm = new KeywordSearchTerm("date_formatted","search_date","webdb_create_formatted","webdb_create_formatted","webdb_create_formatted");
\r
667 UnIndexedSearchTerm whereTerm = new UnIndexedSearchTerm("","","","where","where");
\r
668 TextSearchTerm creatorTerm = new TextSearchTerm("creator","search_creator","creator","creator","creator");
\r
669 TextSearchTerm titleTerm = new TextSearchTerm("title","search_content","title","title","title");
\r
670 TextSearchTerm descriptionTerm = new TextSearchTerm("description","search_content","description","description","description");
\r
671 ContentSearchTerm contentTerm = new ContentSearchTerm("content_data","search_content","content","","");
\r
672 TopicSearchTerm topicTerm = new TopicSearchTerm();
\r
673 ImagesSearchTerm imagesTerm = new ImagesSearchTerm();
\r
674 AudioSearchTerm audioTerm = new AudioSearchTerm();
\r
675 VideoSearchTerm videoTerm = new VideoSearchTerm();
\r
677 //make the query available to subsequent iterations
\r
679 for (Enumeration theParams = req.getParameterNames(); theParams.hasMoreElements() ;) {
\r
680 String pName=(String)theParams.nextElement();
\r
681 if (pName.startsWith("search_")){
\r
682 mergeData.put(pName, req.getParameter(pName) );
\r
687 mergeData.put("topics", topicsModule.getTopicsAsSimpleList());
\r
689 catch(Throwable e) {
\r
690 logger.debug("Can't get topics: " + e.toString());
\r
693 String searchBackValue = req.getParameter("search_back");
\r
694 String searchForwardValue = req.getParameter("search_forward");
\r
696 if (searchBackValue != null){
\r
697 int totalHits = ((Integer) session.getAttribute("numberOfHits")).intValue();
\r
698 int newPosition=((Integer)session.getAttribute("positionInResults")).intValue()-increment;
\r
701 if (newPosition >= totalHits)
\r
702 newPosition=totalHits-1;
\r
703 session.setAttribute("positionInResults",new Integer(newPosition));
\r
706 if (searchForwardValue != null){
\r
707 int totalHits = ((Integer) session.getAttribute("numberOfHits")).intValue();
\r
708 int newPosition=((Integer)session.getAttribute("positionInResults")).intValue()+increment;
\r
711 if (newPosition >= totalHits)
\r
712 newPosition=totalHits-1;
\r
714 session.setAttribute("positionInResults",new Integer(newPosition));
\r
717 String indexPath=configuration.getString("IndexPath");
\r
720 String creatorFragment = creatorTerm.makeTerm(req);
\r
721 if (creatorFragment != null){
\r
722 queryString = queryString + " +" + creatorFragment;
\r
725 // search title, description, and content for something
\r
726 // the contentTerm uses param "search_boolean" to combine its terms
\r
727 String contentFragment = contentTerm.makeTerm(req);
\r
728 if (contentFragment != null){
\r
729 logger.debug("contentFragment: " + contentFragment);
\r
730 queryString = queryString + " +" + contentFragment;
\r
733 String topicFragment = topicTerm.makeTerm(req);
\r
734 if (topicFragment != null){
\r
735 queryString = queryString + " +" + topicFragment;
\r
738 String imagesFragment = imagesTerm.makeTerm(req);
\r
739 if (imagesFragment != null){
\r
740 queryString = queryString + " +" + imagesFragment;
\r
743 String audioFragment = audioTerm.makeTerm(req);
\r
744 if (audioFragment != null){
\r
745 queryString = queryString + " +" + audioFragment;
\r
748 String videoFragment = videoTerm.makeTerm(req);
\r
749 if (videoFragment != null){
\r
750 queryString = queryString + " +" + videoFragment;
\r
753 if (queryString == null || queryString == ""){
\r
758 Searcher searcher = null;
\r
760 searcher = new IndexSearcher(indexPath);
\r
762 catch(IOException e) {
\r
763 logger.debug("Can't open indexPath: " + indexPath);
\r
764 throw new ServletModuleExc("Problem with Search Index! : "+ e.toString());
\r
767 Query query = null;
\r
769 query = QueryParser.parse(queryString, "content", new StandardAnalyzer());
\r
771 catch(Exception e) {
\r
773 logger.debug("Query don't parse: " + queryString);
\r
774 throw new ServletModuleExc("Problem with Query String! (was '"+queryString+"')");
\r
779 hits = searcher.search(query);
\r
781 catch(IOException e) {
\r
783 logger.debug("Can't get hits: " + e.toString());
\r
784 throw new ServletModuleExc("Problem getting hits!");
\r
788 int end = hits.length();
\r
790 String sortBy=req.getParameter("search_sort");
\r
791 if (sortBy == null || sortBy.equals("")){
\r
792 throw new ServletModuleExc("Please let me sort by something!(missing search_sort)");
\r
795 // here is where the documents will go for storage across sessions
\r
796 ArrayList theDocumentsSorted = new ArrayList();
\r
798 if (sortBy.equals("score")){
\r
799 for(int i = start; i < end; i++) {
\r
800 theDocumentsSorted.add(hits.doc(i));
\r
804 // then we'll sort by date!
\r
805 Map dateToPosition = new HashMap(end,1.0F); //we know how big it will be
\r
806 for(int i = start; i < end; i++) {
\r
807 String creationDate=(hits.doc(i)).get("creationDate");
\r
808 // do a little dance in case two contents created at the same second!
\r
809 if (dateToPosition.containsKey(creationDate)){
\r
810 ((ArrayList) (dateToPosition.get(creationDate))).add(new Integer(i));
\r
813 ArrayList thePositions = new ArrayList();
\r
814 thePositions.add(new Integer(i));
\r
815 dateToPosition.put(creationDate,thePositions);
\r
818 Set keys = dateToPosition.keySet();
\r
819 ArrayList keyList= new ArrayList(keys);
\r
820 Collections.sort(keyList);
\r
821 if (sortBy.equals("date_desc")){
\r
822 Collections.reverse(keyList);
\r
825 if (!sortBy.equals("date_asc")){
\r
826 throw new ServletModuleExc("don't know how to sort by: "+ sortBy);
\r
829 ListIterator keyTraverser = keyList.listIterator();
\r
830 while (keyTraverser.hasNext()){
\r
831 ArrayList positions = (ArrayList)dateToPosition.get((keyTraverser.next()));
\r
832 ListIterator positionsTraverser=positions.listIterator();
\r
833 while (positionsTraverser.hasNext()){
\r
834 theDocumentsSorted.add(hits.doc(((Integer)(positionsTraverser.next())).intValue()));
\r
842 catch (IOException e){
\r
843 logger.debug("Can't close searcher: " + e.toString());
\r
844 throw new ServletModuleFailure("Problem closing searcher(normal):" + e.getMessage(), e);
\r
848 session.removeAttribute("numberOfHits");
\r
849 session.removeAttribute("theDocumentsSorted");
\r
850 session.removeAttribute("positionInResults");
\r
852 session.setAttribute("numberOfHits",new Integer(end));
\r
853 session.setAttribute("theDocumentsSorted",theDocumentsSorted);
\r
854 session.setAttribute("positionInResults",new Integer(0));
\r
857 catch (IOException e){
\r
858 logger.debug("Can't close searcher: " + e.toString());
\r
859 throw new ServletModuleFailure("Problem closing searcher: " + e.getMessage(), e);
\r
866 ArrayList theDocs = (ArrayList)session.getAttribute("theDocumentsSorted");
\r
867 if (theDocs != null){
\r
869 mergeData.put("numberOfHits", ((Integer)session.getAttribute("numberOfHits")).toString());
\r
870 List theHits = new Vector();
\r
871 int pIR=((Integer)session.getAttribute("positionInResults")).intValue();
\r
873 int numHits=((Integer)session.getAttribute("numberOfHits")).intValue();
\r
875 if (!(pIR+increment>=numHits)){
\r
876 mergeData.put("hasNext","y");
\r
879 mergeData.put("hasPrevious","y");
\r
882 if ((pIR+increment)>numHits){
\r
886 terminus=pIR+increment;
\r
888 for(int i = pIR; i < terminus; i++) {
\r
889 Map h = new HashMap();
\r
890 Document theHit = (Document)theDocs.get(i);
\r
891 whereTerm.returnMeta(h,theHit);
\r
892 creatorTerm.returnMeta(h,theHit);
\r
893 titleTerm.returnMeta(h,theHit);
\r
894 descriptionTerm.returnMeta(h,theHit);
\r
895 dateTerm.returnMeta(h,theHit);
\r
896 imagesTerm.returnMeta(h,theHit);
\r
897 audioTerm.returnMeta(h,theHit);
\r
898 videoTerm.returnMeta(h,theHit);
\r
901 mergeData.put("hits",theHits);
\r
904 catch (Throwable e) {
\r
905 logger.error("Can't iterate over hits: " + e.toString());
\r
907 throw new ServletModuleFailure("Problem getting hits: " + e.getMessage(), e);
\r
910 mergeData.put("queryString",queryString);
\r
912 deliver(req, res, mergeData, null, searchResultsTemplate);
\r
914 catch (NullPointerException n){
\r
915 throw new ServletModuleFailure("Null Pointer: "+n.toString(), n);
\r
920 * Method for dynamically generating a pdf from a fo file
\r
922 public void getpdf(HttpServletRequest req, HttpServletResponse res)
\r
923 throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure {
\r
924 String ID_REQUEST_PARAM = "id";
\r
925 String language = req.getParameter("language");
\r
926 String generateFO=configuration.getString("GenerateFO");
\r
927 String generatePDF=configuration.getString("GeneratePDF");
\r
930 //don't do anything if we are not making FO files, or if we are
\r
931 //pregenerating PDF's
\r
932 if (generateFO.equals("yes") && generatePDF.equals("no")){
\r
933 //fop complains unless you do the logging this way
\r
934 org.apache.log.Logger log = null;
\r
935 Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
\r
936 log = hierarchy.getLoggerFor("fop");
\r
937 log.setPriority(Priority.WARN);
\r
939 String producerStorageRoot=configuration.getString("Producer.StorageRoot");
\r
940 String producerDocRoot=configuration.getString("Producer.DocRoot");
\r
941 // String templateDir=MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
\r
942 String xslSheet=configuration.getString("Producer.HTML2FOStyleSheet");
\r
944 String idParam = req.getParameter(ID_REQUEST_PARAM);
\r
945 if (idParam != null) {
\r
946 EntityContent contentEnt =
\r
947 (EntityContent)contentModule.getById(idParam);
\r
948 String publishPath = StringUtil.webdbDate2path(contentEnt.getValue("date"));
\r
951 if (language == null){
\r
952 foFile = producerStorageRoot + producerDocRoot + "/"
\r
953 + publishPath + idParam + ".fo";
\r
956 foFile = producerStorageRoot + producerDocRoot + "/"
\r
957 + language + publishPath + idParam + ".fo";
\r
959 logger.debug("USING FILES" + foFile + " and " + xslSheet);
\r
960 XSLTInputHandler input = new XSLTInputHandler(new File(foFile),
\r
961 new File(xslSheet));
\r
963 ByteArrayOutputStream out = new ByteArrayOutputStream();
\r
964 res.setContentType("application/pdf");
\r
966 Driver driver = new Driver();
\r
967 driver.setLogger(log);
\r
968 driver.setRenderer(Driver.RENDER_PDF);
\r
969 driver.setOutputStream(out);
\r
970 driver.render(input.getParser(), input.getInputSource());
\r
972 byte[] content = out.toByteArray();
\r
973 res.setContentLength(content.length);
\r
974 res.getOutputStream().write(content);
\r
975 res.getOutputStream().flush();
\r
978 throw new ServletModuleExc("Missing id.");
\r
981 catch (Throwable t) {
\r
982 logger.error(t.toString());
\r
984 throw new ServletModuleFailure(t);
\r
988 throw new ServletModuleExc("Can't generate a PDF because the config tells me not to.");
\r
992 protected String createOneTimePasswd(){
\r
993 Random r = new Random();
\r
994 int random = r.nextInt();
\r
995 long l = System.currentTimeMillis();
\r
996 l = (l*l*l*l)/random;
\r
997 if(l<0) l = l * -1;
\r
998 String returnString = ""+l;
\r
1000 return returnString.substring(5);
\r
1004 /* this is an overwritten method of ServletModule in order
\r
1005 to use different bundles for open and admin */
\r
1006 /* public void deliver(HttpServletRequest req, HttpServletResponse res,
\r
1007 TemplateModelRoot rtm, TemplateModelRoot popups,
\r
1008 String templateFilename) throws ServletModuleFailure
\r
1012 public void deliver(HttpServletRequest aRequest, HttpServletResponse aResponse, Map aData, Map anExtra, String aGenerator)
\r
1013 throws ServletModuleFailure {
\r
1015 deliver(aResponse.getWriter(), aRequest, aResponse, aData, anExtra, aGenerator);
\r
1017 catch (Throwable t) {
\r
1018 throw new ServletModuleFailure(t);
\r
1022 public void deliver(PrintWriter anOutputWriter, HttpServletRequest aRequest, HttpServletResponse aResponse, Map aData, Map anExtra, String aGenerator)
\r
1023 throws ServletModuleFailure {
\r
1025 Map responseData = ServletHelper.makeGenerationData(getLocale(aRequest), "bundles.open");
\r
1026 responseData.put("data", aData);
\r
1027 responseData.put("extra", anExtra);
\r
1030 Generator generator = MirGlobal.localizer().generators().makeOpenPostingGeneratorLibrary().makeGenerator(aGenerator);
\r
1031 generator.generate(anOutputWriter, responseData, logger.asPrintWriter(logger.INFO_MESSAGE));
\r
1033 anOutputWriter.close();
\r
1035 catch (Throwable e) {
\r
1036 logger.error("Error while generating " + aGenerator + ": " + e.getMessage());
\r
1038 throw new ServletModuleFailure(e);
\r
1042 public void handleError(HttpServletRequest aRequest, HttpServletResponse aResponse,PrintWriter out, Throwable anException) {
\r
1044 logger.error("error: " + anException);
\r
1045 Map data = new HashMap();
\r
1047 data.put("errorstring", anException.getMessage());
\r
1048 data.put("date", StringUtil.date2readableDateTime(new GregorianCalendar()));
\r
1050 deliver(out, aRequest, aResponse, data, null, configuration.getString("ServletModule.OpenIndy.ErrorTemplate"));
\r
1052 catch (Throwable e) {
\r
1053 throw new ServletModuleFailure(e);
\r
1057 public void handleUserError(HttpServletRequest aRequest, HttpServletResponse aResponse,
\r
1058 PrintWriter out, ServletModuleUserExc anException) {
\r
1060 logger.warn("user error: " + anException.getMessage());
\r
1061 Map data = new HashMap();
\r
1063 MessageResources messages = MessageResources.getMessageResources("bundles.open");
\r
1064 data.put("errorstring",
\r
1065 messages.getMessage(getLocale(aRequest), anException.getMessage(), anException.getParameters())
\r
1067 data.put("date", StringUtil.date2readableDateTime(new GregorianCalendar()));
\r
1069 deliver(out, aRequest, aResponse, data, null, configuration.getString("ServletModule.OpenIndy.UserErrorTemplate"));
\r
1071 catch (Throwable e) {
\r
1072 throw new ServletModuleFailure(e);
\r