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;
39 import java.lang.reflect.*;
40 import javax.servlet.*;
41 import javax.servlet.http.*;
43 import freemarker.template.*;
44 import com.oreilly.servlet.multipart.*;
45 import com.oreilly.servlet.*;
47 import org.xml.sax.InputSource;
48 import org.xml.sax.XMLReader;
50 import org.apache.fop.apps.Driver;
51 import org.apache.fop.apps.Version;
52 import org.apache.fop.apps.XSLTInputHandler;
54 import org.apache.log.*;
63 import mircoders.entity.*;
64 import mircoders.storage.*;
65 import mircoders.module.*;
66 import mircoders.producer.*;
67 import mircoders.media.MediaRequest;
68 import mircoders.global.*;
69 import mircoders.localizer.*;
72 * ServletModuleOpenIndy -
73 * is the open-access-servlet, which is responsible for
74 * adding comments to articles &
75 * open-postings to the newswire
77 * @author $Author: bruno $
78 * @version $Revision: 1.41 $ $Date: 2002/09/03 14:30:37 $
80 * $Log: ServletModuleOpenIndy.java,v $
81 * Revision 1.41 2002/09/03 14:30:37 bruno
82 * seperation of admin and open posting bundles
84 * Revision 1.40 2002/09/01 22:05:57 mh
87 * Revision 1.39 2002/08/25 19:00:11 mh
88 * merge of localization branch into HEAD. mh and zap
90 * Revision 1.38 2002/07/21 22:50:14 mh
91 * cleanup coding style of getpdf() method
93 * Revision 1.37 2002/07/21 22:41:45 mh
94 * make use of new MediaRequest class. A big cleanup and optimization.
96 * Revision 1.36 2002/06/29 15:45:20 mh
102 public class ServletModuleOpenIndy extends ServletModule
105 private String commentFormTemplate, commentFormDoneTemplate,
106 commentFormDupeTemplate;
107 private String postingFormTemplate, postingFormDoneTemplate,
108 postingFormDupeTemplate;
109 private ModuleContent contentModule;
110 private ModuleComment commentModule;
111 private ModuleImages imageModule;
112 private ModuleTopics themenModule;
113 private String directOp ="yes";
114 private String passwdProtection ="yes";
115 // Singelton / Kontruktor
116 private static ServletModuleOpenIndy instance = new ServletModuleOpenIndy();
117 public static ServletModule getInstance() { return instance; }
119 private ServletModuleOpenIndy() {
121 theLog = Logfile.getInstance(MirConfig.getProp("Home") + MirConfig.getProp("ServletModule.OpenIndy.Logfile"));
122 commentFormTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentTemplate");
123 commentFormDoneTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentDoneTemplate");
124 commentFormDupeTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentDupeTemplate");
125 postingFormTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingTemplate");
126 postingFormDoneTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingDoneTemplate");
127 postingFormDupeTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingDupeTemplate");
128 directOp = MirConfig.getProp("DirectOpenposting").toLowerCase();
129 passwdProtection = MirConfig.getProp("PasswdProtection").toLowerCase();
130 mainModule = new ModuleComment(DatabaseComment.getInstance());
131 contentModule = new ModuleContent(DatabaseContent.getInstance());
132 themenModule = new ModuleTopics(DatabaseTopics.getInstance());
133 imageModule = new ModuleImages(DatabaseImages.getInstance());
134 defaultAction="addposting";
137 catch (StorageObjectException e) {
138 theLog.printError("servletmoduleopenindy could not be initialized");
144 * Method for making a comment
147 public void addcomment(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
149 String aid = req.getParameter("aid"); // the article id the comment will belong to
150 String language = req.getParameter("language");
152 if (aid!=null && !aid.equals(""))
154 SimpleHash mergeData = new SimpleHash();
157 if(passwdProtection.equals("yes")){
158 String passwd = this.createOneTimePasswd();
159 System.out.println(passwd);
160 HttpSession session = req.getSession(false);
161 session.setAttribute("passwd",passwd);
162 mergeData.put("passwd", passwd);
165 if (language!=null) {
166 HttpSession session = req.getSession(false);
167 session.setAttribute("Locale", new Locale(language, ""));
168 session.setAttribute("passwd",language);
171 mergeData.put("aid", aid);
172 deliver(req, res, mergeData, commentFormTemplate);
174 else throw new ServletModuleException("aid not set!");
178 * Method for inserting a comment into the Database and delivering
179 * the commentDone Page
182 public void inscomment(HttpServletRequest req, HttpServletResponse res)
183 throws ServletModuleException,ServletModuleUserException
185 String aid = req.getParameter("to_media"); // the article id the comment will belong to
186 if (aid!=null && !aid.equals(""))
188 // ok, collecting data from form
190 HashMap withValues = getIntersectingValues(req, DatabaseComment.getInstance());
192 //no html in comments(for now)
193 for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
194 String k=(String)i.next();
195 String v=(String)withValues.get(k);
197 withValues.put(k,StringUtil.removeHTMLTags(v));
199 withValues.put("is_published","1");
201 //checking the onetimepasswd
202 if(passwdProtection.equals("yes")){
203 HttpSession session = req.getSession(false);
204 String sessionPasswd = (String)session.getAttribute("passwd");
205 if ( sessionPasswd == null){
206 throw new ServletModuleUserException("Lost password");
208 String passwd = req.getParameter("passwd");
209 if ( passwd == null || (!sessionPasswd.equals(passwd))) {
210 throw new ServletModuleUserException("Missing password");
212 session.invalidate();
215 // inserting into database
216 String id = mainModule.add(withValues);
217 theLog.printDebugInfo("id: "+id);
218 //insert was not successfull
220 deliver(req, res, new SimpleHash(), commentFormDupeTemplate);
222 DatabaseContent.getInstance().setUnproduced("id="+aid);
225 EntityComment comment = (EntityComment) DatabaseComment.getInstance().selectById(id);
226 MirGlobal.localizer().openPostings().afterCommentPosting(comment);
228 catch (Throwable t) {
229 throw new ServletModuleException(t.getMessage());
236 // redirecting to url
237 // should implement back to article
238 SimpleHash mergeData = new SimpleHash();
239 deliver(req, res, mergeData, commentFormDoneTemplate);
241 catch (StorageObjectException e) { throw new ServletModuleException(e.toString());}
242 catch (ModuleException e) { throw new ServletModuleException(e.toString());}
245 else throw new ServletModuleException("aid not set!");
250 * Method for delivering the form-Page for open posting
253 public void addposting(HttpServletRequest req, HttpServletResponse res)
254 throws ServletModuleException {
255 SimpleHash mergeData = new SimpleHash();
258 if(passwdProtection.equals("yes")){
259 String passwd = this.createOneTimePasswd();
260 System.out.println(passwd);
261 HttpSession session = req.getSession(false);
262 session.setAttribute("passwd",passwd);
263 mergeData.put("passwd", passwd);
266 String maxMedia = MirConfig.getProp("ServletModule.OpenIndy.MaxMediaUploadItems");
267 String numOfMedia = req.getParameter("medianum");
268 if(numOfMedia==null||numOfMedia.equals("")){
270 } else if(Integer.parseInt(numOfMedia) > Integer.parseInt(maxMedia)) {
271 numOfMedia = maxMedia;
274 int mediaNum = Integer.parseInt(numOfMedia);
275 SimpleList mediaFields = new SimpleList();
276 for(int i =0; i<mediaNum;i++){
277 Integer mNum = new Integer(i+1);
278 mediaFields.add(mNum.toString());
280 mergeData.put("medianum",numOfMedia);
281 mergeData.put("mediafields",mediaFields);
284 SimpleHash extraInfo = new SimpleHash();
286 SimpleList popUpData = DatabaseLanguage.getInstance().getPopupData();
287 extraInfo.put("languagePopUpData", popUpData );
288 extraInfo.put("themenPopupData", themenModule.getTopicsAsSimpleList());
290 extraInfo.put("topics", themenModule.getTopicsList());
292 } catch (Exception e) {
293 theLog.printError("languagePopUpData or getTopicslist failed "
295 throw new ServletModuleException("OpenIndy -- failed getting language or topics: "+e.toString());
300 deliver(req, res, mergeData, extraInfo, postingFormTemplate);
304 * Method for inserting an open posting into the Database and delivering
305 * the postingDone Page
308 public void insposting(HttpServletRequest req, HttpServletResponse res)
309 throws ServletModuleException, ServletModuleUserException
311 SimpleHash mergeData = new SimpleHash();
312 boolean setMedia=false;
313 boolean setTopic = false;
316 WebdbMultipartRequest mp = new WebdbMultipartRequest(req);
317 EntityList mediaList = null;
319 // new MediaRequest, "1" is the id for the openPosting user
320 mediaList = new MediaRequest(mp, "1").getMedia(true, true);
321 } catch (MirMediaUserException e) {
322 throw new ServletModuleUserException(e.getMsg());
325 HashMap withValues = mp.getParameters();
327 //checking the onetimepasswd
328 if(passwdProtection.equals("yes")){
329 HttpSession session = req.getSession(false);
330 String sessionPasswd = (String)session.getAttribute("passwd");
331 if ( sessionPasswd == null){
332 throw new ServletModuleUserException("Lost password");
334 String passwd = (String)withValues.get("passwd");
335 if ( passwd == null || (!sessionPasswd.equals(passwd))) {
336 throw new ServletModuleUserException("Missing password");
338 session.invalidate();
341 if ((((String)withValues.get("title")).length() == 0) ||
342 (((String)withValues.get("description")).length() == 0) ||
343 (((String)withValues.get("content_data")).length() == 0))
344 throw new ServletModuleUserException("Missing field");
346 // call the routines that escape html
348 for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
349 String k=(String)i.next();
350 String v=(String)withValues.get(k);
352 if (k.equals("content_data")){
353 //this doesn't quite work yet, so for now, all html goes
354 //withValues.put(k,StringUtil.approveHTMLTags(v));
355 //withValues.put(k,StringUtil.removeHTMLTags(v));
357 withValues.put(k,StringUtil.removeHTMLTags(v));
362 withValues.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
363 withValues.put("publish_path", StringUtil.webdbDate2path((String)withValues.get("date")));
364 withValues.put("is_produced", "0");
365 // by default stuff is published, they can be un-published through the
367 withValues.put("is_published","1");
368 // if op direct article-type == newswire
369 if (directOp.equals("yes")) withValues.put("to_article_type","1");
371 withValues.put("to_publisher","1");
373 // owner is openposting user
374 // ML: this is not multi-language friendly and this can be done in a template
375 // if (withValues.get("creator").toString().equals(""))
376 // withValues.put("creator","Anonym");
378 // inserting content into database
379 String cid = contentModule.add(withValues);
380 theLog.printDebugInfo("id: "+cid);
381 //insert was not successfull
383 //How do we know that it was not succesful cause of a
384 //dupe, what if it failed cause of "No space left on device"?
385 //Or is there something I am missing? Wouldn't it be better
386 //to have an explicit dupe check and then insert? I have no
387 //idea what I am talking about. this comment is in case
388 //I forget to explicitely ask. -mh
389 deliver(req, res, mergeData, postingFormDupeTemplate);
392 String[] to_topicsArr = mp.getParameterValues("to_topic");
394 if (to_topicsArr != null && to_topicsArr.length > 0) {
396 DatabaseContentToTopics.getInstance().setTopics(cid,to_topicsArr);
398 } catch (Exception e) {
399 theLog.printError("setting content_x_topic failed");
400 contentModule.deleteById(cid);
401 throw new ServletModuleException("smod - openindy :: insposting: setting content_x_topic failed: "+e.toString());
405 //if we're here all is ok... associate the media to the article
406 for(int i=0;i<mediaList.size();i++) {
407 Entity mediaEnt = (Entity)mediaList.elementAt(i);
408 DatabaseContentToMedia.getInstance().addMedia(cid,mediaEnt.getId());
412 MirGlobal.localizer().openPostings().afterContentPosting(
413 (EntityContent)contentModule.getById(cid));
415 catch (Throwable t) {
416 throw new ServletModuleException(t.getMessage());
419 catch (MirMediaException e) { throw new ServletModuleException("MediaException: "+ e.toString());}
420 catch (IOException e) { throw new ServletModuleException("IOException: "+ e.toString());}
421 catch (StorageObjectException e) { throw new ServletModuleException("StorageObjectException" + e.toString());}
422 catch (ModuleException e) { throw new ServletModuleException("ModuleException"+e.toString());}
424 deliver(req, res, mergeData, postingFormDoneTemplate);
428 * Method for dynamically generating a pdf from a fo file
430 public void getpdf(HttpServletRequest req, HttpServletResponse res)
431 throws ServletModuleException, ServletModuleUserException {
432 String ID_REQUEST_PARAM = "id";
434 String generateFO=MirConfig.getProp("GenerateFO");
435 String generatePDF=MirConfig.getProp("GeneratePDF");
437 //don't do anything if we are not making FO files, or if we are
438 //pregenerating PDF's
439 if (generateFO.equals("yes") && generatePDF.equals("no")){
440 //fop complains unless you do the logging this way
442 Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
443 log = hierarchy.getLoggerFor("fop");
444 log.setPriority(Priority.WARN);
446 String producerStorageRoot=MirConfig.getProp("Producer.StorageRoot");
447 String producerDocRoot=MirConfig.getProp("Producer.DocRoot");
448 String templateDir=MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
449 String xslSheet=templateDir + "/"
450 + MirConfig.getProp("Producer.PrintableContent.html2foStyleSheetName");
452 String idParam = req.getParameter(ID_REQUEST_PARAM);
453 if (idParam != null) {
454 EntityContent contentEnt =
455 (EntityContent)contentModule.getById(idParam);
456 String publishPath = contentEnt.getValue("publish_path");
457 String foFile = producerStorageRoot + producerDocRoot + "/"
458 + publishPath + "/" + idParam + ".fo";
459 XSLTInputHandler input = new XSLTInputHandler(new File(foFile),
462 ByteArrayOutputStream out = new ByteArrayOutputStream();
463 res.setContentType("application/pdf");
465 Driver driver = new Driver();
466 driver.setLogger(log);
467 driver.setRenderer(Driver.RENDER_PDF);
468 driver.setOutputStream(out);
469 driver.render(input.getParser(), input.getInputSource());
471 byte[] content = out.toByteArray();
472 res.setContentLength(content.length);
473 res.getOutputStream().write(content);
474 res.getOutputStream().flush();
476 throw new ServletModuleUserException("Missing id parameter.");
478 } catch (Exception ex) {
479 throw new ServletModuleException(ex.toString());
482 throw new ServletModuleUserException("Can't generate a PDF because the config tells me not to.");
486 private void _throwBadContentType (String fileName, String contentType)
487 throws ServletModuleUserException {
489 theLog.printDebugInfo("Wrong file type uploaded!: " + fileName+" "
491 throw new ServletModuleUserException("The file you uploaded is of the "
492 +"following mime-type: "+contentType
493 +", we do not support this mime-type. "
494 +"Error One or more files of unrecognized type. Sorry");
497 protected String createOneTimePasswd(){
498 Random r = new Random();
499 int random = r.nextInt();
500 long l = System.currentTimeMillis();
501 l = (l*l*l*l)/random;
503 String returnString = ""+l;
504 return returnString.substring(5);
508 /* this is an overwritten method of ServletModule in order
509 to use different bundles for open and admin */
510 public void deliver(HttpServletRequest req, HttpServletResponse res,
511 TemplateModelRoot rtm, TemplateModelRoot popups,
512 String templateFilename)
513 throws ServletModuleException {
514 if (rtm == null) rtm = new SimpleHash();
516 PrintWriter out = res.getWriter();
517 HTMLTemplateProcessor.process(res, templateFilename, rtm, popups, out,
518 getLocale(req), "bundles.open");
520 } catch (HTMLParseException e) {
521 throw new ServletModuleException(e.toString());
522 } catch (IOException e) {
523 throw new ServletModuleException(e.toString());