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