merge of localization branch into HEAD. mh and zap
[mir.git] / source / mircoders / servlet / ServletModuleOpenIndy.java
1 package mircoders.servlet;
2
3 import java.io.*;
4 import java.lang.*;
5 import java.sql.*;
6 import java.util.*;
7 import java.net.*;
8 import java.lang.reflect.*;
9 import javax.servlet.*;
10 import javax.servlet.http.*;
11
12 import freemarker.template.*;
13 import com.oreilly.servlet.multipart.*;
14 import com.oreilly.servlet.*;
15
16 import org.xml.sax.InputSource;
17 import org.xml.sax.XMLReader;
18
19 import org.apache.fop.apps.Driver;
20 import org.apache.fop.apps.Version;
21 import org.apache.fop.apps.XSLTInputHandler;
22
23 import org.apache.log.*;
24
25 import mir.servlet.*;
26 import mir.module.*;
27 import mir.misc.*;
28 import mir.entity.*;
29 import mir.storage.*;
30 import mir.media.*;
31
32 import mircoders.entity.*;
33 import mircoders.storage.*;
34 import mircoders.module.*;
35 import mircoders.producer.*;
36 import mircoders.media.MediaRequest;
37 import mircoders.global.*;
38 import mircoders.localizer.*;
39
40 /*
41  *  ServletModuleOpenIndy -
42  *   is the open-access-servlet, which is responsible for
43  *    adding comments to articles &
44  *    open-postings to the newswire
45  *
46  * @author $Author: mh $
47  * @version $Revision: 1.39 $ $Date: 2002/08/25 19:00:11 $
48  *
49  * $Log: ServletModuleOpenIndy.java,v $
50  * Revision 1.39  2002/08/25 19:00:11  mh
51  * merge of localization branch into HEAD. mh and zap
52  *
53  * Revision 1.38  2002/07/21 22:50:14  mh
54  * cleanup coding style of getpdf() method
55  *
56  * Revision 1.37  2002/07/21 22:41:45  mh
57  * make use of new MediaRequest class. A big cleanup and optimization.
58  *
59  * Revision 1.36  2002/06/29 15:45:20  mh
60  * cvs macros
61  *
62  *
63  */
64
65 public class ServletModuleOpenIndy extends ServletModule
66 {
67
68   private String        commentFormTemplate, commentFormDoneTemplate,
69                         commentFormDupeTemplate;
70   private String        postingFormTemplate, postingFormDoneTemplate,
71                         postingFormDupeTemplate;
72   private ModuleContent contentModule;
73   private ModuleComment commentModule;
74   private ModuleImages  imageModule;
75   private ModuleTopics  themenModule;
76   private String        directOp ="yes";
77   private String        passwdProtection ="yes";
78   // Singelton / Kontruktor
79   private static ServletModuleOpenIndy instance = new ServletModuleOpenIndy();
80   public static ServletModule getInstance() { return instance; }
81
82   private ServletModuleOpenIndy() {
83     try {
84       theLog = Logfile.getInstance(MirConfig.getProp("Home") + MirConfig.getProp("ServletModule.OpenIndy.Logfile"));
85       commentFormTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentTemplate");
86       commentFormDoneTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentDoneTemplate");
87       commentFormDupeTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentDupeTemplate");
88       postingFormTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingTemplate");
89       postingFormDoneTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingDoneTemplate");
90       postingFormDupeTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingDupeTemplate");
91       directOp = MirConfig.getProp("DirectOpenposting").toLowerCase();
92       passwdProtection = MirConfig.getProp("PasswdProtection").toLowerCase();
93       mainModule = new ModuleComment(DatabaseComment.getInstance());
94       contentModule = new ModuleContent(DatabaseContent.getInstance());
95       themenModule = new ModuleTopics(DatabaseTopics.getInstance());
96       imageModule = new ModuleImages(DatabaseImages.getInstance());
97       defaultAction="addposting";
98
99     }
100     catch (StorageObjectException e) {
101         theLog.printError("servletmoduleopenindy could not be initialized");
102     }
103   }
104
105
106   /**
107    *  Method for making a comment
108    */
109
110   public void addcomment(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
111   {
112     String aid = req.getParameter("aid"); // the article id the comment will belong to
113     String language = req.getParameter("language");
114
115     if (aid!=null && !aid.equals(""))
116     {
117       SimpleHash mergeData = new SimpleHash();
118
119       // onetimepasswd
120       if(passwdProtection.equals("yes")){
121         String passwd = this.createOneTimePasswd();
122         System.out.println(passwd);
123         HttpSession session = req.getSession(false);
124         session.setAttribute("passwd",passwd);
125         mergeData.put("passwd", passwd);
126       }
127
128       if (language!=null) {
129         HttpSession session = req.getSession(false);
130         session.setAttribute("Locale", new Locale(language, ""));
131         session.setAttribute("passwd",language);
132       }
133
134       mergeData.put("aid", aid);
135       deliver(req, res, mergeData, commentFormTemplate);
136     }
137     else throw new ServletModuleException("aid not set!");
138   }
139
140   /**
141    *  Method for inserting a comment into the Database and delivering
142    *  the commentDone Page
143    */
144
145   public void inscomment(HttpServletRequest req, HttpServletResponse res)
146   throws ServletModuleException,ServletModuleUserException
147   {
148     String aid = req.getParameter("to_media"); // the article id the comment will belong to
149     if (aid!=null && !aid.equals(""))
150     {
151       // ok, collecting data from form
152       try {
153         HashMap withValues = getIntersectingValues(req, DatabaseComment.getInstance());
154
155         //no html in comments(for now)
156         for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
157             String k=(String)i.next();
158             String v=(String)withValues.get(k);
159
160             withValues.put(k,StringUtil.removeHTMLTags(v));
161         }
162         withValues.put("is_published","1");
163
164         //checking the onetimepasswd
165         if(passwdProtection.equals("yes")){
166           HttpSession session = req.getSession(false);
167           String sessionPasswd = (String)session.getAttribute("passwd");
168           if ( sessionPasswd == null){
169             throw new ServletModuleUserException("Lost password");
170           }
171           String passwd = req.getParameter("passwd");
172           if ( passwd == null || (!sessionPasswd.equals(passwd))) {
173             throw new ServletModuleUserException("Missing password");
174           }
175           session.invalidate();
176         }
177
178         // inserting into database
179         String id = mainModule.add(withValues);
180         theLog.printDebugInfo("id: "+id);
181         //insert was not successfull
182         if(id==null){
183           deliver(req, res, new SimpleHash(), commentFormDupeTemplate);
184         } else {
185           DatabaseContent.getInstance().setUnproduced("id="+aid);
186
187           try {
188             EntityComment comment = (EntityComment) DatabaseComment.getInstance().selectById(id);
189             MirGlobal.localizer().openPostings().afterCommentPosting(comment);
190           }
191           catch (Throwable t) {
192             throw new ServletModuleException(t.getMessage());
193           }
194           
195           
196           
197         }
198
199         // redirecting to url
200         // should implement back to article
201         SimpleHash mergeData = new SimpleHash();
202         deliver(req, res, mergeData, commentFormDoneTemplate);
203       }
204       catch (StorageObjectException e) { throw new ServletModuleException(e.toString());}
205       catch (ModuleException e) { throw new ServletModuleException(e.toString());}
206
207     }
208     else throw new ServletModuleException("aid not set!");
209
210   }
211
212   /**
213    *  Method for delivering the form-Page for open posting
214    */
215
216   public void addposting(HttpServletRequest req, HttpServletResponse res)
217     throws ServletModuleException {
218     SimpleHash mergeData = new SimpleHash();
219
220     // onetimepasswd
221     if(passwdProtection.equals("yes")){
222       String passwd = this.createOneTimePasswd();
223       System.out.println(passwd);
224       HttpSession session = req.getSession(false);
225       session.setAttribute("passwd",passwd);
226       mergeData.put("passwd", passwd);
227     }
228
229     String maxMedia = MirConfig.getProp("ServletModule.OpenIndy.MaxMediaUploadItems");
230     String numOfMedia = req.getParameter("medianum");
231     if(numOfMedia==null||numOfMedia.equals("")){
232       numOfMedia="1";
233     } else if(Integer.parseInt(numOfMedia) > Integer.parseInt(maxMedia)) {
234       numOfMedia = maxMedia;
235     }
236
237     int mediaNum = Integer.parseInt(numOfMedia);
238     SimpleList mediaFields = new SimpleList();
239     for(int i =0; i<mediaNum;i++){
240       Integer mNum = new Integer(i+1);
241       mediaFields.add(mNum.toString());
242     }
243     mergeData.put("medianum",numOfMedia);
244     mergeData.put("mediafields",mediaFields);
245
246
247     SimpleHash extraInfo = new SimpleHash();
248     try{
249       SimpleList popUpData = DatabaseLanguage.getInstance().getPopupData();
250       extraInfo.put("languagePopUpData", popUpData );
251       extraInfo.put("themenPopupData", themenModule.getTopicsAsSimpleList());
252
253       extraInfo.put("topics", themenModule.getTopicsList());
254
255     } catch (Exception e) {
256       theLog.printError("languagePopUpData or getTopicslist failed "
257                         +e.toString());
258       throw new ServletModuleException("OpenIndy -- failed getting language or topics: "+e.toString());
259     }
260
261
262
263     deliver(req, res, mergeData, extraInfo, postingFormTemplate);
264   }
265
266   /**
267    *  Method for inserting an open posting into the Database and delivering
268    *  the postingDone Page
269    */
270
271   public void insposting(HttpServletRequest req, HttpServletResponse res)
272     throws ServletModuleException, ServletModuleUserException
273   {
274     SimpleHash mergeData = new SimpleHash();
275     boolean setMedia=false;
276     boolean setTopic = false;
277
278     try {
279       WebdbMultipartRequest mp = new WebdbMultipartRequest(req);
280       EntityList mediaList = null;
281       try {
282         // new MediaRequest, "1" is the id for the openPosting user
283         mediaList = new MediaRequest(mp, "1").getMedia(true, true);
284       } catch (MirMediaUserException e) {
285         throw new ServletModuleUserException(e.getMsg());
286       }
287           
288       HashMap withValues = mp.getParameters();
289
290       //checking the onetimepasswd
291       if(passwdProtection.equals("yes")){
292         HttpSession session = req.getSession(false);
293         String sessionPasswd = (String)session.getAttribute("passwd");
294         if ( sessionPasswd == null){
295           throw new ServletModuleUserException("Lost password");
296         }
297         String passwd = (String)withValues.get("passwd");
298         if ( passwd == null || (!sessionPasswd.equals(passwd))) {
299           throw new ServletModuleUserException("Missing password");
300         }
301         session.invalidate();
302       }
303
304       if ((((String)withValues.get("title")).length() == 0) ||
305           (((String)withValues.get("description")).length() == 0) ||
306           (((String)withValues.get("content_data")).length() == 0))
307             throw new ServletModuleUserException("Missing field");
308
309       // call the routines that escape html
310
311       for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){
312         String k=(String)i.next();
313         String v=(String)withValues.get(k);
314
315         if (k.equals("content_data")){
316           //this doesn't quite work yet, so for now, all html goes
317           //withValues.put(k,StringUtil.approveHTMLTags(v));
318           //withValues.put(k,StringUtil.removeHTMLTags(v));
319         } else {
320           withValues.put(k,StringUtil.removeHTMLTags(v));
321         }
322
323       }
324
325       withValues.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
326       withValues.put("publish_path", StringUtil.webdbDate2path((String)withValues.get("date")));
327       withValues.put("is_produced", "0");
328       // by default stuff is published, they can be un-published through the
329       // admin interface.
330       withValues.put("is_published","1");
331       // if op direct article-type == newswire
332       if (directOp.equals("yes")) withValues.put("to_article_type","1");
333
334       withValues.put("to_publisher","1");
335
336       // owner is openposting user
337 //      ML: this is not multi-language friendly and this can be done in a template
338 //      if (withValues.get("creator").toString().equals(""))
339 //        withValues.put("creator","Anonym");
340
341       // inserting  content into database
342       String cid = contentModule.add(withValues);
343       theLog.printDebugInfo("id: "+cid);
344       //insert was not successfull
345       if(cid==null){
346         //How do we know that it was not succesful cause of a
347         //dupe, what if it failed cause of "No space left on device"?
348         //Or is there something I am missing? Wouldn't it be better
349         //to have an explicit dupe check and then insert? I have no
350         //idea what I am talking about. this comment is in case
351         //I forget to explicitely ask. -mh
352         deliver(req, res, mergeData, postingFormDupeTemplate);
353       }
354
355       String[] to_topicsArr = mp.getParameterValues("to_topic");
356
357       if (to_topicsArr != null && to_topicsArr.length > 0) {
358         try{
359           DatabaseContentToTopics.getInstance().setTopics(cid,to_topicsArr);
360           setTopic = true;
361         } catch (Exception e) {
362           theLog.printError("setting content_x_topic failed");
363           contentModule.deleteById(cid);
364           throw new ServletModuleException("smod - openindy :: insposting: setting content_x_topic failed: "+e.toString());
365         } //end try
366       } //end if
367        
368       //if we're here all is ok... associate the media to the article
369       for(int i=0;i<mediaList.size();i++) {
370         Entity mediaEnt = (Entity)mediaList.elementAt(i);
371         DatabaseContentToMedia.getInstance().addMedia(cid,mediaEnt.getId());
372       }
373
374       try {
375         MirGlobal.localizer().openPostings().afterContentPosting(
376             (EntityContent)contentModule.getById(cid));
377       }
378       catch (Throwable t) {
379         throw new ServletModuleException(t.getMessage());
380       }
381     }
382     catch (MirMediaException e) { throw new ServletModuleException("MediaException: "+ e.toString());}
383     catch (IOException e) { throw new ServletModuleException("IOException: "+ e.toString());}
384     catch (StorageObjectException e) { throw new ServletModuleException("StorageObjectException" + e.toString());}
385     catch (ModuleException e) { throw new ServletModuleException("ModuleException"+e.toString());}
386
387     deliver(req, res, mergeData, postingFormDoneTemplate);
388   }
389
390   /*
391    * Method for dynamically generating a pdf from a fo file
392    */
393   public void getpdf(HttpServletRequest req, HttpServletResponse res)
394     throws ServletModuleException, ServletModuleUserException {
395     String ID_REQUEST_PARAM = "id";
396     
397     String generateFO=MirConfig.getProp("GenerateFO");
398     String generatePDF=MirConfig.getProp("GeneratePDF");
399
400     //don't do anything if we are not making FO files, or if we are
401     //pregenerating PDF's
402     if (generateFO.equals("yes") && generatePDF.equals("no")){
403       //fop complains unless you do the logging this way
404       Logger log = null;
405       Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
406       log = hierarchy.getLoggerFor("fop");
407       log.setPriority(Priority.WARN);
408     
409       String producerStorageRoot=MirConfig.getProp("Producer.StorageRoot");
410       String producerDocRoot=MirConfig.getProp("Producer.DocRoot");
411       String templateDir=MirConfig.getPropWithHome("HTMLTemplateProcessor.Dir");
412       String xslSheet=templateDir + "/" 
413         + MirConfig.getProp("Producer.PrintableContent.html2foStyleSheetName");
414       try {
415         String idParam = req.getParameter(ID_REQUEST_PARAM);
416         if (idParam != null) {
417           EntityContent contentEnt =
418             (EntityContent)contentModule.getById(idParam);
419           String publishPath = contentEnt.getValue("publish_path");
420           String foFile = producerStorageRoot + producerDocRoot + "/" 
421                           + publishPath + "/" + idParam + ".fo";
422           XSLTInputHandler input = new XSLTInputHandler(new File(foFile), 
423                                                        new File(xslSheet));
424           
425           ByteArrayOutputStream out = new ByteArrayOutputStream();
426           res.setContentType("application/pdf");
427
428           Driver driver = new Driver();
429           driver.setLogger(log);
430           driver.setRenderer(Driver.RENDER_PDF);
431           driver.setOutputStream(out);
432           driver.render(input.getParser(), input.getInputSource());
433
434           byte[] content = out.toByteArray();
435           res.setContentLength(content.length);
436           res.getOutputStream().write(content);
437           res.getOutputStream().flush();
438         } else {
439           throw new ServletModuleUserException("Missing id parameter.");
440         }
441       } catch (Exception ex) {
442         throw new ServletModuleException(ex.toString());
443       }
444     } else {
445       throw new ServletModuleUserException("Can't generate a PDF because the config tells me not to.");
446     }
447   }
448   
449   private void _throwBadContentType (String fileName, String contentType)
450     throws ServletModuleUserException {
451
452     theLog.printDebugInfo("Wrong file type uploaded!: " + fileName+" "
453                           +contentType);
454     throw new ServletModuleUserException("The file you uploaded is of the "
455         +"following mime-type: "+contentType
456         +", we do not support this mime-type. "
457         +"Error One or more files of unrecognized type. Sorry");
458   }
459
460   protected String createOneTimePasswd(){
461     Random r = new Random();
462     int random = r.nextInt();
463     long l = System.currentTimeMillis();
464     l = (l*l*l*l)/random;
465     if(l<0) l = l * -1;
466     String returnString = ""+l;
467     return returnString.substring(5);
468   }
469
470 }
471
472
473