commented out decodeHTML, as we don't encodeHTML anymore
[mir.git] / source / mircoders / entity / EntityContent.java
1 package mircoders.entity;
2
3 import java.lang.*;
4 import java.io.*;
5 import java.util.*;
6 import java.sql.*;
7 import java.lang.reflect.*;
8
9 import freemarker.template.*;
10
11 import mir.entity.*;
12 import mir.misc.*;
13 import mir.media.*;
14 import mir.storage.*;
15
16 import mircoders.storage.*;
17
18 /**
19  * this class implements mapping of one line of the database table content
20  * to a java object
21  *
22  * @version $Revision: 1.9 $ $Date: 2002/07/19 20:55:49 $
23  * @author $Author: mh $
24  *
25  * $Log: EntityContent.java,v $
26  * Revision 1.9  2002/07/19 20:55:49  mh
27  * commented out decodeHTML, as we don't encodeHTML anymore
28  *
29  * Revision 1.8  2002/06/28 20:37:33  mh
30  * make date_formatted be webdb_create_short instead to be more consistent. also make date2webdb.. use webdb_create
31  *
32  * 
33  */
34
35
36 public class EntityContent extends Entity
37 {
38
39   String mirconf_extLinkName  = MirConfig.getProp("Producer.ExtLinkName");
40   String mirconf_intLinkName  = MirConfig.getProp("Producer.IntLinkName");
41   String mirconf_mailLinkName = MirConfig.getProp("Producer.MailLinkName");
42   String mirconf_imageRoot    = MirConfig.getProp("Producer.ImageRoot");
43
44   //this should always be transient i.e it can never be stored in the db
45   //or ObjectStore. (so the ObjectStore should only be caching what comes
46   //directly out of the DB. @todo confirm this with rk. -mh
47   HashMap _entCache = new HashMap();
48   Boolean _hasMedia = null;
49
50         // constructors
51
52         public EntityContent()
53         {
54                 super();
55     //content_data is now filed-type "text"
56                 //streamedInput = new ArrayList();
57                 //streamedInput.add("content_data");
58         }
59
60         public EntityContent(StorageObject theStorage) {
61                 this();
62                 setStorage(theStorage);
63         }
64
65         //
66         // methods
67
68  /**
69         * set is_produced flag for the article
70         */
71
72         public void setProduced(boolean yesno) throws StorageObjectException
73         {
74                 String value = (yesno) ? "1":"0";
75                 if (value.equals( getValue("is_produced") )) return;
76
77     Connection con=null;Statement stmt=null;
78     String sql = "update content set is_produced='" + value + "' where id='" + getId()+"'";
79                 try {
80                         con = theStorageObject.getPooledCon();
81                         /** @todo should be preparedStatement: faster!! */
82                         stmt = con.createStatement();
83                         theStorageObject.executeUpdate(stmt,sql);
84                 } catch (StorageObjectException e) {
85             throwStorageObjectException(e, "\n -- set produced failed");
86                 } catch (SQLException e) {
87             throwStorageObjectException(e, "\n -- set produced failed");
88                 } finally {
89                         theStorageObject.freeConnection(con,stmt);
90                 }
91         }
92
93
94  /**
95         * make openposting to newswire
96         */
97
98         public void newswire() throws StorageObjectException
99         {
100                 String sql = "update content set to_article_type='1', is_produced='0' where id='" + getId()+"'";
101                 try {
102                                 theStorageObject.executeUpdate(sql);
103                 } catch (StorageObjectException e) {
104             throwStorageObjectException(e, "\n -- newswire failed");
105                 } catch (SQLException e) {
106             throwStorageObjectException(e, "\n -- newswire failed");
107                 }
108         }
109
110
111  /**
112         * dettach from media
113         */
114         public void dettach(String cid,String mid) throws StorageObjectException
115         {
116                 if (mid!=null){
117                         try{
118                                 DatabaseContentToMedia.getInstance().delete(cid,mid);
119                         } catch (Exception e){
120                 throwStorageObjectException(e, "\n -- failed to get instance");
121                         }
122                         //set Content to unproduced
123                         setProduced(false);
124                 }
125         }
126
127  /**
128         * attach to media
129         */
130
131         public void attach(String mid) throws StorageObjectException
132         {
133                 if (mid!=null) {
134                         //write media-id mid and content-id in table content_x_media
135                         try{
136                                 DatabaseContentToMedia.getInstance().addMedia(getId(),mid);
137                         } catch(StorageObjectException e){
138                                 throwStorageObjectException(e, "attach: could not get the instance");
139                         }
140                         //set Content to unproduced
141                         setProduced(false);
142                 }       else {
143                         theLog.printError("EntityContent: attach without mid");
144                 }
145         }
146
147         /**
148          * overridden method getValue to include formatted date into every
149          * entityContent
150          */
151
152         public String getValue(String field)
153   {
154     String returnField = null;
155     if (field!=null)
156     {
157       if (field.equals("date_formatted") || field.equals("webdb_create_short") )
158       {
159                   if (hasValueForField("date"))
160         returnField = StringUtil.webdbDate2readableDate(getValue("webdb_create"));
161                 }
162       else if (field.equals("description_parsed"))
163         returnField = getDescriptionParsed();
164       else if (field.equals("description_sentence"))
165         returnField = getDescriptionSentence();
166       else if (field.equals("content_data_parsed"))
167         returnField = getContentDataParsed();
168       else
169         return super.getValue(field);
170     }
171     return returnField;
172         }
173
174   public TemplateModel get(java.lang.String key) throws TemplateModelException
175   {
176     if (key!=null) {
177       if (_entCache.containsKey(key)) {
178         return (TemplateModel)_entCache.get(key);
179       }
180       if (key.equals("to_comments")) {
181         try {
182           _entCache.put(key, getComments());
183           return (TemplateModel)_entCache.get(key);
184         } catch (Exception ex) {
185           theLog.printWarning("-- getComments: could not fetch data " + ex.toString());
186           throw new TemplateModelException(ex.toString());
187         }
188       }
189       if (key.equals("to_media_images")) {
190         try {
191           _entCache.put(key, getImagesForContent());
192           return (TemplateModel)_entCache.get(key);
193         }
194         catch (Exception ex) {
195           theLog.printWarning("-- getImagesForContent: could not fetch data " + ex.toString());
196           throw new TemplateModelException(ex.toString());
197         }
198       }
199       if (key.equals("to_media_audio")) {
200         try {
201           _entCache.put(key, getAudioForContent());
202           return (TemplateModel)_entCache.get(key);
203         }
204         catch (Exception ex) {
205           theLog.printWarning("-- getAudioForContent: could not fetch data " + ex.toString());
206           throw new TemplateModelException(ex.toString());
207         }
208       }
209       if (key.equals("to_media_video")) {
210         try {
211           _entCache.put(key, getVideoForContent());
212           return (TemplateModel)_entCache.get(key);
213         }
214         catch (Exception ex) {
215           theLog.printWarning("-- getVideoForContent: could not fetch data " + ex.toString());
216           throw new TemplateModelException(ex.toString());
217         }
218       }
219       if (key.equals("to_media_other")) {
220         try {
221           _entCache.put(key, getOtherMediaForContent());
222           return (TemplateModel)_entCache.get(key);
223         }
224         catch (Exception ex) {
225           theLog.printWarning("-- getOtherMediaForContent: could not fetch data " + ex.toString());
226           throw new TemplateModelException(ex.toString());
227         }
228       }
229       else if (key.equals("to_media_icon")) {
230         try {
231           _entCache.put(key, getUploadedMediaForNewswire());
232           return (TemplateModel)_entCache.get(key);
233         }
234         catch (Exception ex) {
235           theLog.printWarning("-- getUploadedMediaForNewswire: could not fetch data " + ex.toString());
236           throw new TemplateModelException(ex.toString());
237         }
238       }
239       else if (key.equals("to_topics")) {
240         try {
241           _entCache.put(key, 
242                         DatabaseContentToTopics.getInstance().getTopics(this));
243           return (TemplateModel)_entCache.get(key);
244         }
245         catch (Exception ex) {
246           theLog.printWarning("-- getTopics: could not fetch data " + ex.toString());
247           throw new TemplateModelException(ex.toString());
248         }
249       }
250       else {
251         return new SimpleScalar(getValue(key));
252       }
253
254     }
255     return null;
256   }
257
258
259
260
261         /**
262          * overridden method setValues to patch creator_main_url
263          */
264         public void setValues(HashMap theStringValues) {
265                 if (theStringValues != null) {
266                         if (theStringValues.containsKey("creator_main_url")){
267                                 if (((String)theStringValues.get("creator_main_url")).equalsIgnoreCase("http://")){
268                                         theStringValues.remove("creator_main_url");
269         } else if (!((String)theStringValues.get("creator_main_url")).startsWith("http://")){
270           theStringValues.put("creator_main_url","http://"+((String)theStringValues.get("creator_main_url")));
271         }
272       }
273                 }
274                 super.setValues(theStringValues);
275         }
276
277
278   private String getContentDataParsed() {
279     String returnField = getValue("content_data");
280     if ((returnField!=null) && (returnField.length()>0) ) {
281       returnField=StringUtil.deleteForbiddenTags(returnField);
282       //create http-links and email-links
283       if (getValue("is_html").equals("0")) {
284         returnField = StringUtil.createHTML(returnField,mirconf_imageRoot,
285                                             mirconf_mailLinkName,mirconf_extLinkName,
286                                             mirconf_intLinkName);
287       }
288       // commented this out as I don't think it necessary as we don't
289       // "encodeHTML" in the first place anymore.. -mh 2002.07.19
290       //returnField = StringUtil.decodeHTMLinTags(returnField);
291     }
292     return returnField;
293   }
294
295   private String getDescriptionSentence() {
296     String returnField = getValue("description");
297     if (returnField != null && returnField.length()>0) {
298        returnField = StringUtil.removeHTMLTags(returnField);
299        int endOfFirstSentence=StringUtil.findEndOfSentence(returnField,0);
300        if (endOfFirstSentence > 0){
301          returnField = returnField.substring(0,endOfFirstSentence);
302        }
303     }
304     return returnField;
305   }
306
307   private String getDescriptionParsed() {
308     String returnField = getValue("description");
309     if (returnField != null && returnField.length()>0) {
310       returnField = StringUtil.deleteForbiddenTags(returnField);
311       if (getValue("is_html").equals("0")) {
312         returnField = StringUtil.createHTML(returnField,mirconf_imageRoot,
313                                             mirconf_mailLinkName,mirconf_extLinkName,
314                                             mirconf_intLinkName);
315       }
316       returnField = StringUtil.decodeHTMLinTags(returnField);
317     }
318     return returnField;
319   }
320
321         /**
322          * fetches all the comments belonging to an article
323          *
324          * @return freemarker.template.SimpleList
325          */
326         private EntityList getComments() throws StorageObjectException {
327                 return ((DatabaseContent)theStorageObject).getComments(this);
328         }
329
330   // @todo this needs to optimized. expensive SQL
331   private SimpleHash getUploadedMediaForNewswire()
332     throws StorageObjectException, TemplateModelException
333   {
334     // fetching/setting the images
335     // return to_media_icons
336     String        tinyIcon = null, iconAlt = null;
337     MirMedia      mediaHandler = null;
338     EntityUploadedMedia uploadedMedia;
339     Entity        mediaType;
340     SimpleHash    returnHash = new SimpleHash();
341
342     EntityList upMediaEntityList =
343                     DatabaseContentToMedia.getInstance().getUploadedMedia(this);
344     if (upMediaEntityList!=null && upMediaEntityList.getCount()>=1) {
345
346       for (int n=0; n < upMediaEntityList.size();n++) {
347         uploadedMedia = (EntityUploadedMedia)upMediaEntityList.elementAt(n);
348         mediaType = uploadedMedia.getMediaType();
349         try {
350           mediaHandler = MediaHelper.getHandler( mediaType );
351         } catch (MirMediaException ex) {
352           throw new TemplateModelException(ex.toString());
353         }
354         //the "best" media type to show
355         if (mediaHandler.isVideo()) {
356           tinyIcon = MirConfig.getProp("Producer.Icon.TinyVideo");
357           iconAlt = "Video";
358           break;
359         } else if (mediaHandler.isAudio()) {
360           tinyIcon = MirConfig.getProp("Producer.Icon.TinyAudio");
361           iconAlt = "Audio";
362         } else if (tinyIcon == null && !mediaHandler.isImage()) {
363           tinyIcon = mediaHandler.getTinyIcon();
364           iconAlt = mediaHandler.getIconAlt();
365         }
366
367       }
368       //it only has image(s)
369       if (tinyIcon == null) {
370         tinyIcon = MirConfig.getProp("Producer.Icon.TinyImage");
371         iconAlt = "Image";
372       }
373     // uploadedMedia Entity list is empty.
374     // we only have text
375     } else {
376       tinyIcon = MirConfig.getProp("Producer.Icon.TinyText");
377       iconAlt = "Text";
378     }
379     returnHash.put("tiny_icon", mirconf_imageRoot+"/"+tinyIcon);
380     returnHash.put("icon_alt", iconAlt);
381     return returnHash;
382   }
383
384   private boolean hasMedia() throws StorageObjectException
385   {
386     if (_hasMedia == null) {
387       _hasMedia =
388         new Boolean(DatabaseContentToMedia.getInstance().hasMedia(this));
389     }
390     return _hasMedia.booleanValue();
391   }
392
393   //######## @todo all of the following getBlahForContent should have
394   // and optimized version where LIMIT=1 sql for list view.
395   private EntityList getImagesForContent()
396     throws StorageObjectException, TemplateModelException
397   {
398     if (hasMedia())
399       return DatabaseContentToMedia.getInstance().getImages(this);
400     else
401       return null;
402   }
403
404   private EntityList getAudioForContent()
405     throws StorageObjectException, TemplateModelException
406   {
407     if (hasMedia())
408       return DatabaseContentToMedia.getInstance().getAudio(this) ;
409     else
410       return null;
411   }
412
413   private EntityList getVideoForContent()
414     throws StorageObjectException, TemplateModelException
415   {
416     if (hasMedia())
417       return DatabaseContentToMedia.getInstance().getVideo(this) ;
418     else
419       return null;
420   }
421
422   private EntityList getOtherMediaForContent()
423     throws StorageObjectException, TemplateModelException
424   {
425     if (hasMedia())
426       return DatabaseContentToMedia.getInstance().getOther(this);
427     else
428       return null;
429   }
430
431 }