support for translations + lots of misc. fixes
[mir.git] / source / mircoders / storage / DatabaseContentToMedia.java
1 /*\r
2  * Copyright (C) 2001, 2002  The Mir-coders group\r
3  *\r
4  * This file is part of Mir.\r
5  *\r
6  * Mir is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 2 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Mir is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with Mir; if not, write to the Free Software\r
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19  *\r
20  * In addition, as a special exception, The Mir-coders gives permission to link\r
21  * the code of this program with the com.oreilly.servlet library, any library\r
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced\r
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of\r
24  * the above that use the same license as the above), and distribute linked\r
25  * combinations including the two.  You must obey the GNU General Public\r
26  * License in all respects for all of the code used other than the above\r
27  * mentioned libraries.  If you modify this file, you may extend this exception\r
28  * to your version of the file, but you are not obligated to do so.  If you do\r
29  * not wish to do so, delete this exception statement from your version.\r
30  */\r
31 \r
32 package mircoders.storage;\r
33 \r
34 import java.sql.Connection;\r
35 import java.sql.ResultSet;\r
36 import java.sql.Statement;\r
37 \r
38 import mir.log.LoggerWrapper;\r
39 import mir.entity.EntityList;\r
40 import mir.storage.Database;\r
41 import mir.storage.StorageObject;\r
42 import mir.storage.StorageObjectExc;\r
43 import mir.storage.StorageObjectFailure;\r
44 \r
45 import mircoders.entity.EntityContent;\r
46 import mircoders.entity.EntityUploadedMedia;\r
47 \r
48 /**\r
49  * <b>implements abstract DB connection to the content_x_media SQL table\r
50  *\r
51  * @author RK, mir-coders group\r
52  * @version $Id: DatabaseContentToMedia.java,v 1.13 2003/02/20 16:05:35 zapata Exp $\r
53  *\r
54  */\r
55 \r
56 public class DatabaseContentToMedia extends Database implements StorageObject{\r
57 \r
58   private static DatabaseContentToMedia instance;\r
59 \r
60   // the following *has* to be sychronized cause this static method\r
61   // could get preemted and we could end up with 2 instances of DatabaseFoo.\r
62   // see the "Singletons with needles and thread" article at JavaWorld -mh\r
63   public synchronized static DatabaseContentToMedia getInstance() throws\r
64       StorageObjectFailure {\r
65     if (instance == null) {\r
66       instance = new DatabaseContentToMedia();\r
67       instance.myselfDatabase = instance;\r
68     }\r
69     return instance;\r
70   }\r
71 \r
72   private DatabaseContentToMedia() throws StorageObjectFailure {\r
73     super();\r
74     logger = new LoggerWrapper("Database.ContentToMedia");\r
75 \r
76     hasTimestamp = false;\r
77     theTable = "content_x_media";\r
78 \r
79     theEntityClass = mir.entity.GenericEntity.class;\r
80   }\r
81 \r
82   /**\r
83    * get all the media-files belonging to a content entity\r
84    *\r
85    */\r
86   public EntityList getMedia(EntityContent content) throws StorageObjectFailure {\r
87     EntityList returnList = null;\r
88     if (content != null) {\r
89       // get all to_topic from media_x_topic\r
90       String id = content.getId();\r
91       String subselect = "id in (select media_id from " + theTable +\r
92           " where content_id=" + id + ")";\r
93 \r
94       try {\r
95         // media should stay in uploaded order. this is especially important\r
96         // for photo stories which require a specific chronologic order.\r
97         // this is why we have the the second parameter "id"\r
98         returnList = DatabaseMedia.getInstance().selectByWhereClause(subselect,\r
99             "id", -1);\r
100       }\r
101       catch (Throwable e) {\r
102         logger.debug("-- get media failed " + e.toString());\r
103         throw new StorageObjectFailure("-- get media failed ", e);\r
104       }\r
105     }\r
106     return returnList;\r
107   }\r
108 \r
109   public boolean hasMedia(EntityContent content) throws StorageObjectFailure,\r
110       StorageObjectExc {\r
111     if (content != null) {\r
112       try {\r
113         if (selectByWhereClause("content_id=" + content.getId(), -1).size() ==\r
114             0)\r
115           return false;\r
116         else\r
117           return true;\r
118       }\r
119       catch (Exception e) {\r
120         logger.error("DatabaseContentToMedia.hasMedia: " + e.toString());\r
121         throw new StorageObjectFailure("DatabaseContentToMedia.hasMedia: " +\r
122                                        e.toString(), e);\r
123       }\r
124     }\r
125     else {\r
126       logger.error("DatabaseContentToMedia.hasMedia: content == null");\r
127       throw new StorageObjectExc(\r
128           "DatabaseContentToMedia.hasMedia: content == null");\r
129     }\r
130   }\r
131 \r
132   /**\r
133    * get all the audio belonging to a content entity\r
134    *\r
135    */\r
136   public EntityList getAudio(EntityContent content) throws StorageObjectFailure {\r
137     EntityList returnList = null;\r
138     if (content != null) {\r
139       // get all to_topic from media_x_topic\r
140       String id = content.getId();\r
141       //this is not supported by mysql\r
142       String subselect = "id in (select media_id from " + theTable +\r
143           " where content_id=" + id + ")";\r
144 \r
145       try {\r
146         // media should stay in uploaded order. this is especially important\r
147         // for photo stories which require a specific chronologic order.\r
148         // this is why we have the the second parameter "id"\r
149         returnList = DatabaseAudio.getInstance().selectByWhereClause(subselect,\r
150             "id", -1);\r
151       }\r
152       catch (Exception e) {\r
153         logger.error("DatabaseContentToMedia.getAudio: " + e.toString());\r
154         throw new StorageObjectFailure("DatabaseContentToMedia.getAudio: " +\r
155                                        e.toString(), e);\r
156       }\r
157     }\r
158     return returnList;\r
159   }\r
160 \r
161   /**\r
162    * get all the video belonging to a content entity\r
163    *\r
164    */\r
165   public EntityList getVideo(EntityContent content) throws StorageObjectFailure {\r
166     EntityList returnList = null;\r
167     if (content != null) {\r
168       // get all to_topic from media_x_topic\r
169       String id = content.getId();\r
170       //this is not supported by mysql\r
171       String subselect = "id in (select media_id from " + theTable +\r
172           " where content_id=" + id + ")";\r
173 \r
174       try {\r
175         // media should stay in uploaded order. this is especially important\r
176         // for photo stories which require a specific chronologic order.\r
177         // this is why we have the the second parameter "id"\r
178         returnList = DatabaseVideo.getInstance().selectByWhereClause(subselect,\r
179             "id", -1);\r
180       }\r
181       catch (Exception e) {\r
182         logger.error("DatabaseContentToMedia.getVideo: " + e.toString());\r
183         throw new StorageObjectFailure("DatabaseContentToMedia.getVideo: " +\r
184                                        e.toString(), e);\r
185       }\r
186     }\r
187     return returnList;\r
188   }\r
189 \r
190   /**\r
191    * get all the images belonging to a content entity\r
192    *\r
193    */\r
194   public EntityList getImages(EntityContent content) throws\r
195       StorageObjectFailure {\r
196     EntityList returnList = null;\r
197     if (content != null) {\r
198       // get all to_topic from media_x_topic\r
199       String id = content.getId();\r
200       //this is not supported by mysql\r
201       String subselect = "id in (select media_id from " + theTable +\r
202           " where content_id=" + id + ")";\r
203 \r
204       try {\r
205         // media should stay in uploaded order. this is especially important\r
206         // for photo stories which require a specific chronologic order.\r
207         // this is why we have the the second parameter "id"\r
208         returnList = DatabaseImages.getInstance().selectByWhereClause(subselect,\r
209             "id", -1);\r
210       }\r
211       catch (Exception e) {\r
212         logger.error("DatabaseContentToMedia.getImages: " + e.toString());\r
213         throw new StorageObjectFailure("DatabaseContentToMedia.getImages: " +\r
214                                        e.toString(), e);\r
215       }\r
216     }\r
217     return returnList;\r
218   }\r
219 \r
220   /**\r
221    * get all the uploaded/other Media belonging to a content entity\r
222    *\r
223    */\r
224   public EntityList getOther(EntityContent content) throws StorageObjectFailure {\r
225     /** @todo this should only fetch published media / rk */\r
226 \r
227     EntityList returnList = null;\r
228     if (content != null) {\r
229       // get all to_topic from media_x_topic\r
230       String id = content.getId();\r
231       //this is not supported by mysql\r
232       String subselect = "id in (select media_id from " + theTable +\r
233           " where content_id=" + id + ")";\r
234 \r
235       try {\r
236         // media should stay in uploaded order. this is especially important\r
237         // for photo stories which require a specific chronologic order.\r
238         // this is why we have the the second parameter "id"\r
239         returnList = DatabaseOther.getInstance().selectByWhereClause(subselect,\r
240             "id");\r
241       }\r
242       catch (Exception e) {\r
243         e.printStackTrace();\r
244         logger.error("DatabaseContentToMedia.getOther: " + e.toString());\r
245         throw new StorageObjectFailure("DatabaseContentToMedia.getOther: " +\r
246                                        e.toString(), e);\r
247       }\r
248     }\r
249     return returnList;\r
250   }\r
251 \r
252   /**\r
253    * get all the uploaded/other Media belonging to a content entity\r
254    *\r
255    */\r
256   public EntityList getUploadedMedia(EntityContent content) throws\r
257       StorageObjectFailure {\r
258     /** @todo this should only fetch published media / rk */\r
259 \r
260     EntityList returnList = null;\r
261     if (content != null) {\r
262       // get all to_topic from media_x_topic\r
263       String id = content.getId();\r
264       //this is not supported by mysql\r
265       String subselect = "id in (select media_id from " + theTable +\r
266           " where content_id=" + id + ")";\r
267 \r
268       try {\r
269         returnList = DatabaseUploadedMedia.getInstance().selectByWhereClause(\r
270             subselect,\r
271             "id");\r
272       }\r
273       catch (Exception e) {\r
274         e.printStackTrace();\r
275         logger.error("DatabaseContentToMedia.getUploadedMedia: " + e.toString());\r
276         throw new StorageObjectFailure(\r
277             "DatabaseContentToMedia.getUploadedMedia: " + e.toString(), e);\r
278       }\r
279     }\r
280     return returnList;\r
281   }\r
282 \r
283   public void setMedia(String contentId, String[] mediaId) throws\r
284       StorageObjectFailure {\r
285     if (contentId == null) {\r
286       return;\r
287     }\r
288     if (mediaId == null || mediaId[0] == null) {\r
289       return;\r
290     }\r
291     //first delete all row with content_id=contentId\r
292     String sql = "delete from " + theTable + " where content_id=" + contentId;\r
293 \r
294     Connection con = null;\r
295     Statement stmt = null;\r
296     try {\r
297       con = getPooledCon();\r
298       // should be a preparedStatement because is faster\r
299       stmt = con.createStatement();\r
300       ResultSet rs = executeSql(stmt, sql);\r
301     }\r
302     catch (Exception e) {\r
303       logger.error("-- set media failed -- delete");\r
304       throw new StorageObjectFailure("-- set media failed -- delete", e);\r
305     }\r
306     finally {\r
307       freeConnection(con, stmt);\r
308     }\r
309 \r
310     //now insert\r
311     //first delete all row with content_id=contentId\r
312     for (int i = 0; i < mediaId.length; i++) {\r
313       sql = "insert into " + theTable + " (content_id,media_id) values ("\r
314           + contentId + "," + mediaId[i] + ")";\r
315       try {\r
316         con = getPooledCon();\r
317         // should be a preparedStatement because is faster\r
318         stmt = con.createStatement();\r
319         int rs = executeUpdate(stmt, sql);\r
320       }\r
321       catch (Exception e) {\r
322         logger.error("-- set topics failed -- insert");\r
323         throw new StorageObjectFailure("-- set topics failed -- insert ", e);\r
324       }\r
325       finally {\r
326         freeConnection(con, stmt);\r
327       }\r
328     }\r
329   }\r
330 \r
331   public void addMedia(String contentId, String mediaId) throws\r
332       StorageObjectFailure {\r
333     if (contentId == null && mediaId == null) {\r
334       return;\r
335     }\r
336 \r
337     Connection con = null;\r
338     Statement stmt = null;\r
339     //now insert\r
340 \r
341     String sql = "insert into " + theTable + " (content_id,media_id) values ("\r
342         + contentId + "," + mediaId + ")";\r
343     try {\r
344       con = getPooledCon();\r
345       // should be a preparedStatement because is faster\r
346       stmt = con.createStatement();\r
347       int rs = executeUpdate(stmt, sql);\r
348     }\r
349     catch (Exception e) {\r
350       logger.error("-- add media failed -- insert");\r
351       throw new StorageObjectFailure("-- add media failed -- insert ", e);\r
352     }\r
353     finally {\r
354       freeConnection(con, stmt);\r
355     }\r
356   }\r
357 \r
358   public void setMedia(String contentId, String mediaId) throws\r
359       StorageObjectFailure {\r
360     if (contentId == null && mediaId == null) {\r
361       return;\r
362     }\r
363     //first delete all row with content_id=contentId\r
364     String sql = "delete from " + theTable + " where content_id=" + contentId;\r
365 \r
366     Connection con = null;\r
367     Statement stmt = null;\r
368     try {\r
369       con = getPooledCon();\r
370       // should be a preparedStatement because is faster\r
371       stmt = con.createStatement();\r
372       int rs = executeUpdate(stmt, sql);\r
373     }\r
374     catch (Exception e) {\r
375       logger.error("-- set media failed -- delete");\r
376       throw new StorageObjectFailure("-- set media failed -- delete ", e);\r
377     }\r
378     finally {\r
379       freeConnection(con, stmt);\r
380     }\r
381 \r
382     //now insert\r
383     //first delete all row with content_id=contentId\r
384 \r
385     sql = "insert into " + theTable + " (content_id,media_id) values ("\r
386         + contentId + "," + mediaId + ")";\r
387     try {\r
388       con = getPooledCon();\r
389       // should be a preparedStatement because is faster\r
390       stmt = con.createStatement();\r
391       int rs = executeUpdate(stmt, sql);\r
392     }\r
393     catch (Exception e) {\r
394       logger.error("-- set media failed -- insert");\r
395       throw new StorageObjectFailure("-- set media failed -- insert ", e);\r
396     }\r
397     finally {\r
398       freeConnection(con, stmt);\r
399     }\r
400   }\r
401 \r
402   public void deleteByContentId(String contentId) throws StorageObjectFailure {\r
403     if (contentId == null) {\r
404       //theLog.printDebugInfo("-- delete topics failed -- no content id");\r
405       return;\r
406     }\r
407     //delete all row with content_id=contentId\r
408     String sql = "delete from " + theTable + " where content_id=" + contentId;\r
409 \r
410     Connection con = null;\r
411     Statement stmt = null;\r
412     try {\r
413       con = getPooledCon();\r
414       // should be a preparedStatement because is faster\r
415       stmt = con.createStatement();\r
416       int rs = executeUpdate(stmt, sql);\r
417     }\r
418     catch (Exception e) {\r
419       logger.error("-- delete by contentId failed  ");\r
420       throw new StorageObjectFailure(\r
421           "-- delete by content id failed -- delete ", e);\r
422     }\r
423     finally {\r
424       freeConnection(con, stmt);\r
425     }\r
426   }\r
427 \r
428   public void deleteByMediaId(String mediaId) throws StorageObjectFailure {\r
429     if (mediaId == null) {\r
430       //theLog.printDebugInfo("-- delete topics failed -- no topic id");\r
431       return;\r
432     }\r
433     //delete all row with content_id=contentId\r
434     String sql = "delete from " + theTable + " where media_id=" + mediaId;\r
435 \r
436     Connection con = null;\r
437     Statement stmt = null;\r
438     try {\r
439       con = getPooledCon();\r
440       // should be a preparedStatement because is faster\r
441       stmt = con.createStatement();\r
442       int rs = executeUpdate(stmt, sql);\r
443       logger.debug("-- delete media success ");\r
444     }\r
445     catch (Exception e) {\r
446       logger.error("-- delete media failed ");\r
447       throw new StorageObjectFailure("-- delete by media id failed -- ", e);\r
448     }\r
449     finally {\r
450       freeConnection(con, stmt);\r
451     }\r
452   }\r
453 \r
454   public void delete(String contentId, String mediaId) throws\r
455       StorageObjectFailure {\r
456     if (mediaId == null || contentId == null) {\r
457       logger.debug("-- delete media failed -- missing parameter");\r
458       return;\r
459     }\r
460     //delete all row with content_id=contentId and media_id=mediaId\r
461     String sql = "delete from " + theTable + " where media_id=" + mediaId +\r
462         " and content_id= " + contentId;\r
463 \r
464     Connection con = null;\r
465     Statement stmt = null;\r
466     try {\r
467       con = getPooledCon();\r
468       // should be a preparedStatement because is faster\r
469       stmt = con.createStatement();\r
470       int rs = executeUpdate(stmt, sql);\r
471       logger.debug("-- delete content_x_media success ");\r
472     }\r
473     catch (Exception e) {\r
474       logger.error("-- delete content_x_media failed ");\r
475       throw new StorageObjectFailure("-- delete content_x_media failed -- ", e);\r
476     }\r
477     finally {\r
478       freeConnection(con, stmt);\r
479     }\r
480   }\r
481 \r
482   public EntityList getContent(EntityUploadedMedia media) throws\r
483       StorageObjectFailure {\r
484     EntityList returnList = null;\r
485     if (media != null) {\r
486       String id = media.getId();\r
487       String select = "select content_id from " + theTable + " where media_id=" +\r
488           id;\r
489 \r
490       // execute select statement\r
491       Connection con = null;\r
492       Statement stmt = null;\r
493       try {\r
494         con = getPooledCon();\r
495         // should be a preparedStatement because is faster\r
496         stmt = con.createStatement();\r
497         ResultSet rs = executeSql(stmt, select);\r
498         if (rs != null) {\r
499           String mediaSelect = "id IN (";\r
500           boolean first = true;\r
501           while (rs.next()) {\r
502             if (first == false)\r
503               mediaSelect += ",";\r
504             mediaSelect += rs.getString(1);\r
505             first = false;\r
506           }\r
507           mediaSelect += ")";\r
508           if (first == false)\r
509             returnList = DatabaseContent.getInstance().selectByWhereClause(\r
510                 mediaSelect, -1);\r
511         }\r
512       }\r
513       catch (Exception e) {\r
514         logger.error("-- get content failed");\r
515         throw new StorageObjectFailure("-- get content failed -- ", e);\r
516       }\r
517       finally {\r
518         freeConnection(con, stmt);\r
519       }\r
520     }\r
521     return returnList;\r
522   }\r
523 \r
524   /**\r
525    * Returns a EntityList with all content-objects having a relation to a media\r
526    */\r
527 \r
528   public EntityList getContent() throws StorageObjectFailure {\r
529     EntityList returnList = null;\r
530 \r
531     String select = "select distinct content_id from " + theTable;\r
532     // execute select statement\r
533     Connection con = null;\r
534     Statement stmt = null;\r
535     try {\r
536       con = getPooledCon();\r
537       // should be a preparedStatement because is faster\r
538       stmt = con.createStatement();\r
539       ResultSet rs = executeSql(stmt, select);\r
540       if (rs != null) {\r
541         String mediaSelect = "id IN (";\r
542         boolean first = true;\r
543         while (rs.next()) {\r
544           if (first == false)\r
545             mediaSelect += ",";\r
546           mediaSelect += rs.getString(1);\r
547           first = false;\r
548         }\r
549         mediaSelect += ")";\r
550         if (first == false)\r
551           returnList = DatabaseContent.getInstance().selectByWhereClause(\r
552               mediaSelect, "webdb_lastchange desc");\r
553       }\r
554     }\r
555     catch (Exception e) {\r
556       logger.error("-- get content failed");\r
557       throw new StorageObjectFailure("-- get content failed -- ", e);\r
558     }\r
559     finally {\r
560       freeConnection(con, stmt);\r
561     }\r
562 \r
563     return returnList;\r
564   }\r
565 \r
566 }\r