Converted media Interface to use streams (Java IO) instead of byte buffers of
[mir.git] / source / mircoders / servlet / ServletModuleContent.java
1 /*
2  * Copyright (C) 2001, 2002  The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
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.
10  *
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.
15  *
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
19  *
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.
30  */
31
32 package mircoders.servlet;
33
34 import java.io.*;
35 import java.sql.*;
36 import java.util.*;
37 import java.net.*;
38 import javax.servlet.*;
39 import javax.servlet.http.*;
40
41
42 import freemarker.template.*;
43
44 import mir.servlet.*;
45 import mir.media.*;
46 import mir.module.*;
47 import mir.misc.*;
48 import mir.storage.*;
49 import mir.entity.*;
50
51 import mircoders.storage.*;
52 import mircoders.module.*;
53 import mircoders.entity.*;
54
55
56 /*
57  *  ServletModuleContent -
58  *  deliver html for the article admin form.
59  *
60  * @version $Revision: 1.19.2.2 $
61  * @author $Author: mh $
62  *
63  * $Log: ServletModuleContent.java,v $
64  * Revision 1.19.2.2  2002/11/01 05:38:21  mh
65  * Converted media Interface to use streams (Java IO) instead of byte buffers of
66  * the entire uplaoded files. These saves loads of unecessary memory use. JAI
67  * still consumes quite a bit though.
68  *
69  * A new temporary file (for JAI) parameter is necessary and is in the config.properties file.
70  *
71  * A nice side effect of this work is the FileHandler interface which is
72  * basically a call back mechanism for WebdbMultipartRequest which allows the
73  * uploaded file to handled by different classes. For example, for a media
74  * upload, the content-type, etc.. needs to be determined, but if say the
75  * FileEditor had a feature to upload static files... another handler wood be
76  * needed. Right now only the MediaRequest handler exists.
77  *
78  * Revision 1.19.2.1  2002/09/01 21:31:44  mh
79  * Mir goes GPL
80  *
81  * Revision 1.19  2002/07/20 22:24:25  mh
82  * made the add() method use _showObject. Fixes a bug that cause the popUps not to show up when adding an article in the admin
83  *
84  *
85  */
86
87 public class ServletModuleContent extends ServletModule
88 {
89
90   static ModuleTopics         themenModule;
91   static ModuleSchwerpunkt    schwerpunktModule;
92   static ModuleImages         imageModule;
93
94   static String templateOpString;
95
96   // Singelton / Kontruktor
97
98   private static ServletModuleContent instance = new ServletModuleContent();
99   public static ServletModule getInstance() { return instance; }
100
101   private ServletModuleContent() {
102     try {
103                 theLog = Logfile.getInstance(MirConfig.getProp("Home") + MirConfig.getProp("ServletModule.Content.Logfile"));
104       templateListString = MirConfig.getProp("ServletModule.Content.ListTemplate");
105       //templateOpString = MirConfig.getProp("ServletModule.Content.OpTemplate");
106       templateObjektString = MirConfig.getProp("ServletModule.Content.ObjektTemplate");
107       templateConfirmString = MirConfig.getProp("ServletModule.Content.ConfirmTemplate");
108       mainModule = new ModuleContent(DatabaseContent.getInstance());
109       themenModule = new ModuleTopics(DatabaseTopics.getInstance());
110       schwerpunktModule = new ModuleSchwerpunkt(DatabaseFeature.getInstance());
111       imageModule = new ModuleImages(DatabaseImages.getInstance());
112     } catch (StorageObjectException e) {
113       theLog.printDebugInfo("servletmodulecontent konnte nicht initialisiert werden");
114     }
115   }
116
117   // Methoden
118
119   public void list(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
120   {
121     try {
122       EntityUsers user = _getUser(req);
123       EntityList   theList;
124       String       offsetParam = req.getParameter("offset");
125       int          offset =0;
126
127       // hier offsetcode bearbeiteb
128       if (offsetParam != null && !offsetParam.equals(""))
129           offset = Integer.parseInt(offsetParam);
130
131       if (req.getParameter("next") != null)
132           offset=Integer.parseInt(req.getParameter("nextoffset"));
133       else
134           if (req.getParameter("prev") != null)
135             offset = Integer.parseInt(req.getParameter("prevoffset"));
136
137       String        whereParam = req.getParameter("where");
138       String        orderParam = req.getParameter("order");
139
140       theList = ((ModuleContent)mainModule).getContent(whereParam, orderParam, offset, user);
141       _list(theList, req, res);
142     } catch (ModuleException e) {
143       throw new ServletModuleException(e.toString());
144     }
145   }
146
147   public void listop(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
148   {
149     try {
150       EntityUsers user = _getUser(req);
151       EntityList   theList;
152       String       offsetParam = req.getParameter("offset");
153       int          offset =0;
154
155       String whereParam = req.getParameter("where");
156
157       if (whereParam==null) whereParam = "to_article_type='0'";
158
159       // hier offsetcode bearbeiteb
160       if (offsetParam != null && !offsetParam.equals(""))
161           offset = Integer.parseInt(offsetParam);
162
163       if (req.getParameter("next") != null)
164           offset=Integer.parseInt(req.getParameter("nextoffset"));
165       else
166           if (req.getParameter("prev") != null)
167             offset = Integer.parseInt(req.getParameter("prevoffset"));
168
169       String orderParam = req.getParameter("order");
170
171       theList = ((ModuleContent)mainModule).getContent(whereParam, orderParam, offset, user);
172       _list(theList, req, res);
173     } catch (ModuleException e) {
174       throw new ServletModuleException(e.toString());
175     }
176   }
177
178
179   public void search(HttpServletRequest req, HttpServletResponse res)
180     throws ServletModuleException {
181     try {
182       EntityUsers   user = _getUser(req);
183       EntityList    theList;
184       String        fieldParam = req.getParameter("field");
185       String        fieldValueParam = req.getParameter("fieldvalue");
186       String        orderParam = req.getParameter("order");
187
188       theList = ((ModuleContent)mainModule).getContentByField(fieldParam, fieldValueParam, orderParam, 0, user);
189       _list(theList, req, res);
190     } catch (ModuleException e) {
191       throw new ServletModuleException(e.toString());
192     }
193   }
194
195   public void add(HttpServletRequest req, HttpServletResponse res)
196     throws ServletModuleException {
197     _showObject(null, req, res);
198   }
199
200
201   public void insert(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
202   {
203     //theLog.printDebugInfo(":: content :: trying to insert");
204     try {
205       EntityUsers   user = _getUser(req);
206       HashMap withValues = getIntersectingValues(req, DatabaseContent.getInstance());
207       //theLog.printDebugInfo(":: content :: got intersecting values");
208       String now = StringUtil.date2webdbDate(new GregorianCalendar());
209       withValues.put("date", now);
210       withValues.put("publish_path", StringUtil.webdbDate2path(now));
211       withValues.put("to_publisher", user.getId());
212       withValues.put("is_produced", "0");
213       if (!withValues.containsKey("is_published"))
214         withValues.put("is_published","0");
215       if (!withValues.containsKey("is_html"))
216         withValues.put("is_html","0");
217       if (withValues.get("creator").toString().equals(""))
218         withValues.put("creator","Anonym");
219       String id = mainModule.add(withValues);
220       DatabaseContentToTopics.getInstance().setTopics(id,req.getParameterValues("to_topic"));
221       //theLog.printDebugInfo(":: content :: inserted");
222       _showObject(id, req, res);
223     }
224     catch (StorageObjectException e) {
225       throw new ServletModuleException(e.toString());
226     }
227     catch (ModuleException e) {
228       throw new ServletModuleException(e.toString());
229     }
230   }
231
232   public void delete(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
233   {
234
235     EntityUsers   user = _getUser(req);
236     // hier pruefen ob dem akt. user loeschen erlaubt ist...
237     String idParam = req.getParameter("id");
238     if (idParam == null) throw new ServletModuleException("Falscher Aufruf: (id) nicht angegeben");
239
240     String confirmParam = req.getParameter("confirm");
241     String cancelParam = req.getParameter("cancel");
242
243     if (confirmParam == null && cancelParam == null) {
244       // HTML Ausgabe zum Confirmen!
245       SimpleHash mergeData = new SimpleHash();
246       mergeData.put("module", "Content");
247       mergeData.put("infoString", "Content: " + idParam);
248       mergeData.put("id", idParam);
249       mergeData.put("where", req.getParameter("where"));
250       mergeData.put("order", req.getParameter("order"));
251       mergeData.put("offset", req.getParameter("offset"));
252       deliver(req, res, mergeData, templateConfirmString);
253     }
254     else {
255       if (confirmParam!= null && !confirmParam.equals("")) {
256         try {
257           mainModule.deleteById(idParam);
258
259           /** @todo the following two should be imlied in
260            *  DatabaseContent */
261
262           //delete rows in the content_x_topic-table
263           DatabaseContentToTopics.getInstance().deleteByContentId(idParam);
264           //delete rows in the comment-table
265           DatabaseComment.getInstance().deleteByContentId(idParam);
266         } catch (ModuleException e) {
267           throw new ServletModuleException(e.toString());
268         } catch (StorageObjectException e) {
269           throw new ServletModuleException(e.toString());
270         }
271         list(req,res);
272       }
273       else {
274         // Datensatz anzeigen
275         _showObject(idParam, req, res);
276       }
277     }
278   }
279
280   public void edit(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
281   {
282     String        idParam = req.getParameter("id");
283     if (idParam == null) throw new ServletModuleException("Falscher Aufruf: (id) nicht angegeben");
284     _showObject(idParam, req, res);
285   }
286
287   // methods for attaching media file
288   public void attach(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
289   {
290     String  mediaIdParam = req.getParameter("mid");
291     String  idParam = req.getParameter("cid");
292     if (idParam == null||mediaIdParam==null) throw new ServletModuleException("smod content :: attach :: cid/mid missing");
293
294     try {
295       EntityContent entContent = (EntityContent)mainModule.getById(idParam);
296       entContent.attach(mediaIdParam);
297     }
298     catch(ModuleException e) {
299       theLog.printError("smod content :: attach :: could not get entityContent");
300     }
301     catch(StorageObjectException e) {
302       theLog.printError("smod content :: attach :: could not get entityContent");
303     }
304
305     _showObject(idParam, req, res);
306   }
307
308   public void dettach(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
309   {
310     String  cidParam = req.getParameter("cid");
311                 String  midParam = req.getParameter("mid");
312     if (cidParam == null) throw new ServletModuleException("smod content :: dettach :: cid missing");
313     if (midParam == null) throw new ServletModuleException("smod content :: dettach :: mid missing");
314
315     try {
316       EntityContent entContent = (EntityContent)mainModule.getById(cidParam);
317       entContent.dettach(cidParam,midParam);
318     }
319     catch(ModuleException e) {
320       theLog.printError("smod content :: dettach :: could not get entityContent");
321     }
322     catch(StorageObjectException e) {
323       theLog.printError("smod content :: dettach :: could not get entityContent");
324     }
325
326     _showObject(cidParam, req, res);
327   }
328
329   public void newswire(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
330   {
331     String  idParam = req.getParameter("id");
332     if (idParam == null) throw new ServletModuleException("smod content :: newswire :: id missing");
333     try {
334       EntityContent entContent = (EntityContent)mainModule.getById(idParam);
335       entContent.newswire();
336     }
337     catch(ModuleException e) {
338       theLog.printError("smod content :: newswire :: could not get entityContent");
339     }
340     catch(StorageObjectException e) {
341       theLog.printError("smod content :: dettach :: could not get entityContent");
342     }
343
344     list(req, res);
345   }
346
347
348   public void update(HttpServletRequest req, HttpServletResponse res)
349     throws ServletModuleException
350   {
351     try {
352
353       EntityUsers   user = _getUser(req);
354       if (user==null) theLog.printDebugInfo("user null!");
355       String idParam = req.getParameter("id");
356       if (idParam == null) throw new ServletModuleException("Wrong call: (id) is missing");
357
358       HashMap withValues = getIntersectingValues(req, DatabaseContent.getInstance());
359       String[] topic_id = req.getParameterValues("to_topic");
360       String content_id = req.getParameter("id");
361       // withValues.put("publish_path", StringUtil.webdbDate2path((String)withValues.get("date")));
362       if(user != null) withValues.put("user_id", user.getId());
363       withValues.put("is_produced", "0");
364       if (!withValues.containsKey("is_published"))
365         withValues.put("is_published","0");
366       if (!withValues.containsKey("is_html"))
367         withValues.put("is_html","0");
368       if (withValues.get("creator").toString().equals(""))
369         withValues.put("creator","Anonym");
370       //theLog.printDebugInfo("updating. ");
371       String id = mainModule.set(withValues);
372       DatabaseContentToTopics.getInstance().setTopics(req.getParameter("id"),topic_id);
373       //theLog.printDebugInfo("update done. ");
374       String whereParam = req.getParameter("where");
375       String orderParam = req.getParameter("order");
376       if ((whereParam!=null && !whereParam.equals("")) || (orderParam!=null && !orderParam.equals(""))){
377         //theLog.printDebugInfo("update to list");
378         list(req,res);
379       }
380       else
381         _showObject(idParam, req, res);
382     }
383     catch (StorageObjectException e) {
384       throw new ServletModuleException(e.toString());
385     }
386     catch (ModuleException e) {
387       throw new ServletModuleException(e.toString());
388     }
389   }
390
391   /* 
392    * HelperMethod shows the basic article editing form.
393    *
394    * if the "id" parameter is null, it means show an empty form to add a new
395    * article.
396    */ 
397   private void _showObject(String id, HttpServletRequest req, HttpServletResponse res)
398     throws ServletModuleException {
399
400     SimpleHash extraInfo = new SimpleHash();
401     try {
402       TemplateModelRoot entContent;
403       if (id != null) {
404         entContent = (TemplateModelRoot)mainModule.getById(id);
405       } else {
406         SimpleHash withValues = new SimpleHash();
407         withValues.put("new", "1");
408         withValues.put("is_published", "0");
409         String now = StringUtil.date2webdbDate(new GregorianCalendar());
410         withValues.put("date", new SimpleScalar(now));
411         EntityUsers   user = _getUser(req);
412         withValues.put("login_user", user);
413         entContent = withValues;
414       }
415         
416
417       extraInfo.put("themenPopupData", themenModule.getTopicsAsSimpleList());
418       try {
419         extraInfo.put("articletypePopupData",
420                         DatabaseArticleType.getInstance().getPopupData());
421       } catch (Exception e) {
422         theLog.printError("articletype could not be fetched.");
423       }
424       try {
425         extraInfo.put("languagePopupData", DatabaseLanguage.getInstance().getPopupData());
426       } catch (Exception e) {
427         theLog.printError("language-popup could not be fetched.");
428       }
429
430       extraInfo.put("schwerpunktPopupData", schwerpunktModule.getSchwerpunktAsSimpleList());
431       // hier code um zur liste zurueckzukommen
432       String offsetParam, whereParam, orderParam;
433       if ((offsetParam = req.getParameter("offset"))!=null) extraInfo.put("offset", offsetParam);
434       if ((whereParam = req.getParameter("where"))!=null) extraInfo.put("where", whereParam);
435       if ((orderParam = req.getParameter("order"))!=null) extraInfo.put("order", orderParam);
436       extraInfo.put("login_user", _getUser(req));
437       deliver(req, res, entContent, extraInfo, templateObjektString);
438     } catch (Exception e) {
439       throw new ServletModuleException(e.toString());
440     }
441   }
442
443
444   public void _list(EntityList theList, HttpServletRequest req, HttpServletResponse res)
445     throws ServletModuleException {
446
447     try {
448       // hier dann htmlcode rausschreiben
449       if (theList == null || theList.getCount() == 0 || theList.getCount()>1) {
450         SimpleHash modelRoot = HTMLTemplateProcessor.makeSimpleHashWithEntitylistInfos(theList);
451         modelRoot.put("themenHashData", themenModule.getHashData());
452         modelRoot.put("schwerpunktHashData", schwerpunktModule.getHashData());
453         modelRoot.put("articletypeHash", DatabaseArticleType.getInstance().getHashData());
454         deliver(req, res, modelRoot, templateListString);
455       } else  { // count = 1
456         _showObject(theList.elementAt(0).getId(),req,res);
457       }
458     } catch (StorageObjectException e) {
459       throw new ServletModuleException(e.toString());
460     }
461   }
462
463   public void _listop(EntityList theList, HttpServletRequest req, HttpServletResponse res)
464     throws ServletModuleException {
465
466     try {
467       // delivering html
468       if (theList == null || theList.getCount() == 0 || theList.getCount()>1) {
469         SimpleHash modelRoot = HTMLTemplateProcessor.makeSimpleHashWithEntitylistInfos(theList);
470         modelRoot.put("articletypeHash", DatabaseArticleType.getInstance().getHashData());
471
472     EntityContent       currentContent;
473     EntityList          upMediaEntityList;
474     EntityList          imageEntityList;
475     EntityList          currentMediaList;
476     Entity              mediaType;
477     EntityMedia         uploadedMedia;
478     SimpleList          opList;
479       String imageRoot = MirConfig.getProp("Producer.ImageRoot");
480
481     SimpleHash          contentHash;
482     Class               mediaHandlerClass=null;
483     MirMedia            mediaHandler=null;
484     String              mediaHandlerName=null;
485     Database            mediaStorage=null;
486     String              tinyIcon;
487     String              iconAlt;
488
489       for (int i=0; i < theList.size();i++) {
490         currentContent = (EntityContent)theList.elementAt(i);
491         //fetching/setting the images
492         upMediaEntityList = DatabaseContentToMedia.getInstance().getUploadedMedia(currentContent);
493         if (upMediaEntityList!=null && upMediaEntityList.getCount()>=1) {
494           tinyIcon = null;
495           iconAlt = null;
496           mediaHandler = null;
497           mediaHandlerName = null;
498           for (int n=0; n < upMediaEntityList.size();n++) {
499             uploadedMedia = (EntityMedia)upMediaEntityList.elementAt(n);
500             mediaType = uploadedMedia.getMediaType();
501
502             //must of had a non-existant to_media_type entry..
503             //let's save our ass.
504             if (mediaType != null) {
505                 try {
506                   mediaHandlerName = mediaType.getValue("classname");
507                   mediaHandlerClass = Class.forName("mir.media.MediaHandler"+mediaHandlerName);
508                   mediaHandler = (MirMedia)mediaHandlerClass.newInstance();
509                 } catch (Exception e) {
510                   theLog.printError("ProducerStartpage:problem in reflection: "+mediaHandlerName);
511                 }
512
513                 //the "best" media type to show
514                 if (mediaHandler.isVideo()) {
515                   tinyIcon = MirConfig.getProp("Producer.Icon.TinyVideo");
516                   iconAlt = "Video";
517                   break;
518                 } else if (mediaHandler.isAudio()) {
519                   tinyIcon = MirConfig.getProp("Producer.Icon.TinyAudio");
520                   iconAlt = "Audio";
521                 } else if (tinyIcon == null && !mediaHandler.isImage()) {
522                   tinyIcon = mediaHandler.getTinyIconName();
523                   iconAlt = mediaHandler.getIconAltName();
524                 }
525             }
526           }
527           //it only has image(s)
528           if (tinyIcon == null) {
529             tinyIcon = MirConfig.getProp("Producer.Icon.TinyImage");
530             iconAlt = "Image";
531           }
532
533         // uploadedMedia Entity list is empty.
534         // we only have text
535         } else {
536           tinyIcon = MirConfig.getProp("Producer.Icon.TinyText");
537           iconAlt = "Text";
538         }
539
540         try{
541           //mediaList = HTMLTemplateProcessor.makeSimpleList(upMediaEntityList);
542           contentHash = (SimpleHash)theList.get(i);
543           contentHash.put("tiny_icon", imageRoot+"/"+tinyIcon);
544           contentHash.put("icon_alt", iconAlt);
545         } catch (Exception e){}
546       }
547
548
549         deliver(req, res, modelRoot, templateListString);
550       } else  { // count = 1
551         _showObject(theList.elementAt(0).getId(), req, res);
552       }
553     } catch (StorageObjectException e) {
554       throw new ServletModuleException(e.toString());
555     }
556   }
557
558   private EntityUsers _getUser(HttpServletRequest req)
559   {
560     HttpSession session=req.getSession(false);
561     return (EntityUsers)session.getAttribute("login.uid");
562   }
563 }
564