* anti-abuse upgrade: filters now stored in the database (experimental)
[mir.git] / source / mircoders / localizer / basic / MirBasicDataModelLocalizer.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  any library licensed under the Apache Software License,\r
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
23  * (or with modified versions of the above that use the same license as the above),\r
24  * and distribute linked combinations including the two.  You must obey the\r
25  * GNU General Public License in all respects for all of the code used other than\r
26  * the above mentioned libraries.  If you modify this file, you may extend this\r
27  * exception to your version of the file, but you are not obligated to do so.\r
28  * If you do not wish to do so, delete this exception statement from your version.\r
29  */\r
30 package mircoders.localizer.basic;\r
31 \r
32 import mir.config.MirPropertiesConfiguration;\r
33 import mir.entity.Entity;\r
34 import mir.entity.adapter.*;\r
35 import mir.generator.Generator;\r
36 import mir.generator.GeneratorExc;\r
37 import mir.generator.GeneratorFailure;\r
38 import mir.log.LoggerWrapper;\r
39 import mir.media.MediaHandler;\r
40 import mir.misc.NumberUtils;\r
41 import mir.util.JDBCStringRoutines;\r
42 import mir.util.ParameterExpander;\r
43 import mir.util.RewindableIterator;\r
44 import mir.util.StructuredContentParser;\r
45 import mircoders.entity.EntityUploadedMedia;\r
46 import mircoders.global.MirGlobal;\r
47 import mircoders.localizer.MirAdminInterfaceLocalizer;\r
48 import mircoders.localizer.MirDataModelLocalizer;\r
49 import mircoders.localizer.MirLocalizerExc;\r
50 import mircoders.localizer.MirLocalizerFailure;\r
51 import mircoders.media.MediaHelper;\r
52 import mircoders.module.ModuleContent;\r
53 import mircoders.module.ModuleLanguage;\r
54 import mircoders.storage.*;\r
55 import multex.Failure;\r
56 \r
57 import java.util.*;\r
58 \r
59 public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {\r
60   protected LoggerWrapper logger = new LoggerWrapper("Localizer.DataModel");\r
61   protected MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();\r
62   protected ModuleLanguage languageModule = new ModuleLanguage();\r
63 \r
64   protected void constructContentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure, MirLocalizerExc {\r
65     try {\r
66       anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
67       anEntityAdapterDefinition.addDBDateField("changedate", "webdb_lastchange", configuration.getString("Mir.DefaultTimezone"));\r
68       anEntityAdapterDefinition.addMirDateField("date", "date", configuration.getString("Mir.DefaultTimezone"));\r
69 \r
70       anEntityAdapterDefinition.addCalculatedField("lockinguser", new ToOneRelationField("to_locking_user", "id", "user"));\r
71       anEntityAdapterDefinition.addCalculatedField("is_locked", new ContentToIsLockedField());\r
72 \r
73       anEntityAdapterDefinition.addCalculatedField("to_topics", new ContentToTopicsField());\r
74       anEntityAdapterDefinition.addCalculatedField("to_comments", new ContentToCommentsField());\r
75       anEntityAdapterDefinition.addCalculatedField("language", new ToOneRelationField("to_language", "language", "id"));\r
76       anEntityAdapterDefinition.addCalculatedField("commentcount", new ContentCommentCountField(" and is_published='1'"));\r
77       anEntityAdapterDefinition.addCalculatedField("fullcommentcount", new ContentCommentCountField(""));\r
78 \r
79 \r
80       anEntityAdapterDefinition.addCalculatedField("mediacount", new ContentMediaCountField("uploaded_media", true));\r
81       anEntityAdapterDefinition.addCalculatedField("fullmediacount", new ContentMediaCountField("uploaded_media", false));\r
82 \r
83       anEntityAdapterDefinition.addCalculatedField("to_uploaded_media", new ContentToMediaField( "uploadedMedia" ));\r
84       anEntityAdapterDefinition.addCalculatedField("to_media_images",  new ContentToMediaField( "image" ));\r
85       anEntityAdapterDefinition.addCalculatedField("to_media_audio", new ContentToMediaField( "audio" ));\r
86       anEntityAdapterDefinition.addCalculatedField("to_media_video", new ContentToMediaField( "video" ));\r
87       anEntityAdapterDefinition.addCalculatedField("to_media_other", new ContentToMediaField( "otherMedia" ));\r
88 \r
89       anEntityAdapterDefinition.addCalculatedField("firstImage",  new ContentToFirstMediaField( "image" ));\r
90       anEntityAdapterDefinition.addCalculatedField("firstAudio", new ContentToFirstMediaField( "audio" ));\r
91       anEntityAdapterDefinition.addCalculatedField("firstVideo", new ContentToFirstMediaField( "video" ));\r
92       anEntityAdapterDefinition.addCalculatedField("firstOther", new ContentToFirstMediaField( "otherMedia" ));\r
93 \r
94       anEntityAdapterDefinition.addCalculatedField("to_all_uploaded_media", new ContentToMediaField( "uploadedMedia", false));\r
95       anEntityAdapterDefinition.addCalculatedField("to_all_media_images",  new ContentToMediaField( "image", false));\r
96       anEntityAdapterDefinition.addCalculatedField("to_all_media_audio", new ContentToMediaField( "audio", false));\r
97       anEntityAdapterDefinition.addCalculatedField("to_all_media_video", new ContentToMediaField( "video", false));\r
98       anEntityAdapterDefinition.addCalculatedField("to_all_media_other", new ContentToMediaField( "otherMedia", false));\r
99       anEntityAdapterDefinition.addCalculatedField("to_media_icon", new ContentToIconField());\r
100 \r
101       anEntityAdapterDefinition.addCalculatedField("article_type", new ToOneRelationField("to_article_type", "articleType", "id"));\r
102 \r
103       anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));\r
104       anEntityAdapterDefinition.addCalculatedField("content_data_parsed", new FilteredField("content_data"));\r
105 \r
106       anEntityAdapterDefinition.addCalculatedField("children", new ContentToChildrenField());\r
107       anEntityAdapterDefinition.addCalculatedField("parent", new ToOneRelationField("to_content", "content", "id"));\r
108 \r
109       anEntityAdapterDefinition.addCalculatedField("publicurl", new ExpandedField(configuration.getString("Article.PublicUrl")));\r
110 \r
111       anEntityAdapterDefinition.addCalculatedField("operations",\r
112           new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleArticleOperations()));\r
113       \r
114       anEntityAdapterDefinition.addCalculatedField("languagename", new ContentToLanguageNameField());\r
115 \r
116       anEntityAdapterDefinition.addCalculatedField("is_original", new ContentIsOriginalField());\r
117       anEntityAdapterDefinition.addCalculatedField("to_original", new ContentToOriginalField());\r
118       anEntityAdapterDefinition.addCalculatedField("to_translations", new ContentToTranslationsField());\r
119       anEntityAdapterDefinition.addCalculatedField("to_translation", new ContentToTranslationField());\r
120 \r
121       anEntityAdapterDefinition.addCalculatedField("previews", new EntityAdapterDefinition.CalculatedField() {\r
122         public Object getValue(EntityAdapter anEntityAdapter) {\r
123           try {\r
124             return MirGlobal.localizer().adminInterface().getPreviewPages(anEntityAdapter);\r
125           }\r
126           catch (MirLocalizerExc e) {\r
127             throw new Failure("Cannot get previews for article", e);\r
128           }\r
129         }\r
130       });\r
131     }\r
132     catch (Throwable t) {\r
133       throw new MirLocalizerFailure(t.getMessage(), t);\r
134     }\r
135   }\r
136 \r
137 \r
138 \r
139   protected void constructCommentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure {\r
140     try {\r
141       anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
142       anEntityAdapterDefinition.addCalculatedField("to_content", new ToOneRelationField("to_media", "content", "id"));\r
143       anEntityAdapterDefinition.addCalculatedField("status", new CommentToStatusField());\r
144 \r
145       anEntityAdapterDefinition.addCalculatedField("to_uploaded_media", new CommentToMediaField( "uploadedMedia" ));\r
146       anEntityAdapterDefinition.addCalculatedField("to_media_images",  new CommentToMediaField( "image" ));\r
147       anEntityAdapterDefinition.addCalculatedField("to_media_audio", new CommentToMediaField( "audio" ));\r
148       anEntityAdapterDefinition.addCalculatedField("to_media_video", new CommentToMediaField( "video" ));\r
149       anEntityAdapterDefinition.addCalculatedField("to_media_other", new CommentToMediaField( "otherMedia" ));\r
150       anEntityAdapterDefinition.addCalculatedField("to_all_uploaded_media", new CommentToMediaField( "uploadedMedia", false));\r
151       anEntityAdapterDefinition.addCalculatedField("to_all_media_images",  new CommentToMediaField( "image", false));\r
152       anEntityAdapterDefinition.addCalculatedField("to_all_media_audio", new CommentToMediaField( "audio", false));\r
153       anEntityAdapterDefinition.addCalculatedField("to_all_media_video", new CommentToMediaField( "video", false));\r
154       anEntityAdapterDefinition.addCalculatedField("to_all_media_other", new CommentToMediaField( "otherMedia", false));\r
155 \r
156       anEntityAdapterDefinition.addCalculatedField("publicurl", new ExpandedField(configuration.getString("Comment.PublicUrl")));\r
157 \r
158       anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));\r
159       anEntityAdapterDefinition.addCalculatedField("operations",\r
160           new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleCommentOperations()));\r
161     }\r
162     catch (Throwable t) {\r
163       throw new MirLocalizerFailure(t.getMessage(), t);\r
164     }\r
165   }\r
166 \r
167   public EntityAdapterModel adapterModel() throws MirLocalizerFailure, MirLocalizerExc {\r
168     EntityAdapterModel result = new EntityAdapterModel();\r
169 \r
170     try {\r
171       EntityAdapterDefinition definition;\r
172 \r
173       definition = new EntityAdapterDefinition();\r
174       constructContentAdapterDefinition( definition );\r
175       result.addMapping( "content", DatabaseContent.getInstance(), definition);\r
176 \r
177       definition = new EntityAdapterDefinition();\r
178       constructCommentAdapterDefinition( definition );\r
179       result.addMapping( "comment", DatabaseComment.getInstance(), definition);\r
180       result.addMapping( "commentStatus", DatabaseCommentStatus.getInstance(), new EntityAdapterDefinition());\r
181 \r
182       result.addMapping( "articleType", DatabaseArticleType.getInstance(), new EntityAdapterDefinition());\r
183 \r
184       result.addMapping( "mediaType", DatabaseMediaType.getInstance(), new EntityAdapterDefinition());\r
185 \r
186 \r
187       definition = new EntityAdapterDefinition();\r
188       definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
189       result.addMapping( "breakingNews", DatabaseBreaking.getInstance(), definition);\r
190 \r
191       definition = new EntityAdapterDefinition();\r
192       definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
193       result.addMapping( "internalMessage", DatabaseMessages.getInstance(), definition);\r
194 \r
195       definition = new EntityAdapterDefinition();\r
196       definition.addCalculatedField("mediafolder", new ToOneRelationField("to_media_folder", "mediaFolder", "id"));\r
197       definition.addCalculatedField("human_readable_size", new HumanReadableSizeField("value"));\r
198       definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
199       definition.addCalculatedField("info", new MediaToMediaInfoField());\r
200       result.addMapping( "uploadedMedia", DatabaseUploadedMedia.getInstance(), definition);\r
201       definition = new EntityAdapterDefinition();\r
202       definition.addCalculatedField("mediafolder", new ToOneRelationField("to_media_folder", "mediaFolder", "id"));\r
203       definition.addCalculatedField("human_readable_size", new HumanReadableSizeField("value"));\r
204       definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
205       definition.addCalculatedField("info", new MediaToMediaInfoField());\r
206       definition.addCalculatedField("big_icon", new MediaToBigIconField());\r
207       result.addMapping( "image", DatabaseImages.getInstance(), definition);\r
208       definition = new EntityAdapterDefinition();\r
209       definition.addCalculatedField("mediafolder", new ToOneRelationField("to_media_folder", "mediaFolder", "id"));\r
210       definition.addCalculatedField("human_readable_size", new HumanReadableSizeField("value"));\r
211       definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
212       definition.addCalculatedField("info", new MediaToMediaInfoField());\r
213       definition.addCalculatedField("big_icon", new MediaToBigIconField());\r
214       result.addMapping( "audio", DatabaseAudio.getInstance(), definition);\r
215       definition = new EntityAdapterDefinition();\r
216       definition.addCalculatedField("mediafolder", new ToOneRelationField("to_media_folder", "mediaFolder", "id"));\r
217       definition.addCalculatedField("human_readable_size", new HumanReadableSizeField("value"));\r
218       definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
219       definition.addCalculatedField("info", new MediaToMediaInfoField());\r
220       definition.addCalculatedField("big_icon", new MediaToBigIconField());\r
221       result.addMapping( "video", DatabaseVideo.getInstance(), definition);\r
222 \r
223       definition = new EntityAdapterDefinition();\r
224       definition.addCalculatedField("mediafolder", new ToOneRelationField("to_media_folder", "mediaFolder", "id"));\r
225       definition.addCalculatedField("human_readable_size", new HumanReadableSizeField("value"));\r
226       definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
227       definition.addCalculatedField("info", new MediaToMediaInfoField());\r
228       definition.addCalculatedField("big_icon", new MediaToBigIconField());\r
229       result.addMapping( "otherMedia", DatabaseOther.getInstance(), definition);\r
230 \r
231 \r
232       result.addMapping( "mediaFolder", DatabaseMediafolder.getInstance(), new EntityAdapterDefinition());\r
233       result.addMapping( "imageType", DatabaseImageType.getInstance(), new EntityAdapterDefinition());\r
234       result.addMapping( "language", DatabaseLanguage.getInstance(), new EntityAdapterDefinition());\r
235       result.addMapping( "mediaType", DatabaseMediaType.getInstance(), new EntityAdapterDefinition());\r
236       result.addMapping( "topic", DatabaseTopics.getInstance(), new EntityAdapterDefinition());\r
237 \r
238       definition = new EntityAdapterDefinition();\r
239       definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
240       definition.addDBDateField("lastlogindate", "lastlogin", configuration.getString("Mir.DefaultTimezone"));\r
241       definition.addCalculatedField("structuredProfile", new StructuredContentField("profile"));\r
242       result.addMapping( "user", DatabaseUsers.getInstance(), definition);\r
243 \r
244       result.addMapping( "content_x_topic", DatabaseContentToTopics.getInstance(), new EntityAdapterDefinition());\r
245 \r
246       definition = new EntityAdapterDefinition();\r
247       definition.addCalculatedField("to_filters",\r
248           new ToManyRelationField("id", "filter", "filter_group_id", "priority asc"));\r
249       result.addMapping("filterGroup", DatabaseFilterGroup.getInstance(), definition);\r
250       definition = new EntityAdapterDefinition();\r
251       definition.addDBDateField("lasthit", "last_hit", configuration.getString("Mir.DefaultTimezone"));\r
252       definition.addCalculatedField("to_filter_group",\r
253           new ToOneRelationField("filter_group_id", "filter_group", "id"));\r
254       result.addMapping("filter", DatabaseFilter.getInstance(), definition);\r
255     }\r
256     catch (Throwable t) {\r
257       throw new MirLocalizerFailure(t.getMessage(), t);\r
258     }\r
259 \r
260     return result;\r
261   }\r
262 \r
263   protected class CommentToStatusField implements EntityAdapterDefinition.CalculatedField {\r
264     public Object getValue(EntityAdapter anEntityAdapter) {\r
265       try {\r
266         return anEntityAdapter.getToOneRelation(\r
267                     "id="+anEntityAdapter.get("to_comment_status"),\r
268                     "id",\r
269                     "commentStatus" );\r
270       }\r
271       catch (Throwable t) {\r
272         throw new RuntimeException(t.getMessage());\r
273       }\r
274     }\r
275   }\r
276 \r
277   protected class EntityToSimpleOperationsField implements EntityAdapterDefinition.CalculatedField {\r
278     private List operations;\r
279 \r
280     public EntityToSimpleOperationsField(List anOperations) {\r
281       operations = anOperations;\r
282     }\r
283 \r
284     public Object getValue(EntityAdapter anEntityAdapter) {\r
285       try {\r
286         Iterator i = operations.iterator();\r
287         List availableOperations = new ArrayList();\r
288 \r
289         while (i.hasNext()) {\r
290           MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =\r
291             (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();\r
292 \r
293           if (operation.isAvailable(anEntityAdapter)) {\r
294             availableOperations.add(operation.getName());\r
295           }\r
296         };\r
297 \r
298         return availableOperations;\r
299       }\r
300       catch (Throwable t) {\r
301         throw new RuntimeException(t.getMessage());\r
302       }\r
303     }\r
304   }\r
305 \r
306   protected class FilteredField implements EntityAdapterDefinition.CalculatedField {\r
307     private String fieldName;\r
308 \r
309     public FilteredField(String aFieldName) {\r
310       fieldName = aFieldName;\r
311     }\r
312 \r
313     public Object getValue(EntityAdapter anEntityAdapter) {\r
314       try {\r
315         if (anEntityAdapter.get("is_html")!=null && anEntityAdapter.get("is_html").equals("1")) {\r
316           return MirGlobal.localizer().producerAssistant().filterHTMLText((String) anEntityAdapter.get(fieldName));\r
317         }\r
318         else {\r
319           return MirGlobal.localizer().producerAssistant().filterNonHTMLText((String) anEntityAdapter.get(fieldName));\r
320         }\r
321       }\r
322       catch (Throwable t) {\r
323         throw new RuntimeException(t.getMessage());\r
324       }\r
325     }\r
326   }\r
327 \r
328   protected class StructuredContentField implements EntityAdapterDefinition.CalculatedField {\r
329     private String expression;\r
330 \r
331     public StructuredContentField(String anExpression) {\r
332       expression = anExpression;\r
333     }\r
334 \r
335     public Object getValue(EntityAdapter anEntityAdapter) {\r
336       try {\r
337         return StructuredContentParser.parse(ParameterExpander.evaluateStringExpression(anEntityAdapter, expression));\r
338       }\r
339       catch (Throwable t) {\r
340         throw new RuntimeException(t.getMessage());\r
341       }\r
342     }\r
343   }\r
344 \r
345   protected class ExpandedField implements EntityAdapterDefinition.CalculatedField {\r
346     private String expression;\r
347 \r
348     public ExpandedField(String anExpression) {\r
349       expression = anExpression;\r
350     }\r
351 \r
352     public Object getValue(EntityAdapter anEntityAdapter) {\r
353       try {\r
354         return ParameterExpander.expandExpression(anEntityAdapter, expression);\r
355       }\r
356       catch (Throwable t) {\r
357         throw new RuntimeException(t.getMessage());\r
358       }\r
359     }\r
360   }\r
361 \r
362   protected class EvaluatedField implements EntityAdapterDefinition.CalculatedField {\r
363     private String expression;\r
364 \r
365     public EvaluatedField(String anExpression) {\r
366       expression = anExpression;\r
367     }\r
368 \r
369     public Object getValue(EntityAdapter anEntityAdapter) {\r
370       try {\r
371         return ParameterExpander.evaluateExpression(anEntityAdapter, expression);\r
372       }\r
373       catch (Throwable t) {\r
374         throw new RuntimeException(t.getMessage());\r
375       }\r
376     }\r
377   }\r
378 \r
379   protected class ContentToChildrenField implements EntityAdapterDefinition.CalculatedField {\r
380     public Object getValue(EntityAdapter anEntityAdapter) {\r
381       try {\r
382         return anEntityAdapter.getRelation(\r
383                     "to_content="+anEntityAdapter.get("id"),\r
384                     "id",\r
385                     "content" );\r
386       }\r
387       catch (Throwable t) {\r
388         throw new RuntimeException(t.getMessage());\r
389       }\r
390     }\r
391   }\r
392   public static class MediaInfo {\r
393     private MediaHandler mediaHandler;\r
394 \r
395     public MediaInfo(MediaHandler aHandler) {\r
396       mediaHandler = aHandler;\r
397     }\r
398     public String getBigIcon() {\r
399       if (mediaHandler == null)\r
400         return "bla";\r
401       else\r
402         return mediaHandler.getBigIconName();\r
403     }\r
404 \r
405     public String getSmallIcon() {\r
406       if (mediaHandler == null)\r
407         return "bla";\r
408       else\r
409         return mediaHandler.getTinyIconName();\r
410     }\r
411 \r
412     public String getMediaType() {\r
413       return "";\r
414     }\r
415   }\r
416 \r
417   protected class MediaToMediaInfoField implements EntityAdapterDefinition.CalculatedField {\r
418     public Object getValue(EntityAdapter anEntityAdapter) {\r
419       try {\r
420         MediaHandler mediaHandler = MediaHelper.getHandler(((EntityUploadedMedia) anEntityAdapter.getEntity()).getMediaType());\r
421 \r
422         return new MediaInfo(mediaHandler);\r
423       }\r
424       catch (Throwable t) {\r
425         throw new RuntimeException(t.getMessage());\r
426       }\r
427     }\r
428   }\r
429 \r
430   protected class MediaToBigIconField implements EntityAdapterDefinition.CalculatedField {\r
431     public Object getValue(EntityAdapter anEntityAdapter) {\r
432       try {\r
433         return MediaHelper.getHandler(((EntityUploadedMedia) anEntityAdapter.getEntity()).getMediaType()).getBigIconName();\r
434       }\r
435       catch (Throwable t) {\r
436         throw new RuntimeException(t.getMessage());\r
437       }\r
438     }\r
439   }\r
440 \r
441   protected class ContentToCommentsField implements EntityAdapterDefinition.CalculatedField {\r
442     private String extracondition;\r
443     private String order;\r
444 \r
445     public ContentToCommentsField() {\r
446       this ( " and is_published='1'", "webdb_create");\r
447     }\r
448 \r
449     public ContentToCommentsField(String anExtraCondition, String anOrder) {\r
450       order = anOrder;\r
451       extracondition = anExtraCondition;\r
452     }\r
453 \r
454     public Object getValue(EntityAdapter anEntityAdapter) {\r
455       try {\r
456         return anEntityAdapter.getRelation(\r
457                     "to_media="+anEntityAdapter.get("id")+" " + extracondition,\r
458                     order,\r
459                     "comment" );\r
460       }\r
461       catch (Throwable t) {\r
462         throw new RuntimeException(t.getMessage());\r
463       }\r
464     }\r
465   }\r
466 \r
467   protected class ContentToTopicsField implements EntityAdapterDefinition.CalculatedField {\r
468     private String topicCondition;\r
469     private String topicOrder;\r
470 \r
471     public ContentToTopicsField() {\r
472       this(null);\r
473     }\r
474 \r
475     public ContentToTopicsField(String aTopicCondition) {\r
476       this(aTopicCondition, "title");\r
477     }\r
478 \r
479     public ContentToTopicsField(String aTopicCondition, String aTopicOrder) {\r
480       topicCondition = aTopicCondition;\r
481       topicOrder = aTopicOrder;\r
482     }\r
483 \r
484     public Object getValue(EntityAdapter anEntityAdapter) {\r
485       try {\r
486 \r
487         ArrayList extraTable = new ArrayList();\r
488         extraTable.add("content_x_topic cxt");\r
489         String condition = "cxt.content_id="+anEntityAdapter.get("id")+\r
490           " and cxt.topic_id=t.id";\r
491 \r
492         if (topicCondition!=null && topicCondition.length()>0)\r
493           condition = "(" + topicCondition + ") and " + condition;\r
494 \r
495         return anEntityAdapter.getComplexRelation("t", extraTable,\r
496                     condition, topicOrder, "topic" );\r
497       }\r
498       catch (Throwable t) {\r
499         throw new RuntimeException(t.getMessage());\r
500       }\r
501     }\r
502   }\r
503 \r
504   protected class ContentToMediaField implements EntityAdapterDefinition.CalculatedField {\r
505     private String definition;\r
506     private boolean published;\r
507 \r
508     public ContentToMediaField(String aDefinition, boolean anOnlyPublished) {\r
509       definition = aDefinition;\r
510       published = anOnlyPublished;\r
511     }\r
512 \r
513     public ContentToMediaField(String aDefinition) {\r
514       this(aDefinition, true);\r
515     }\r
516 \r
517     public Object getValue(EntityAdapter anEntityAdapter) {\r
518       try {\r
519         String condition = "cxm.content_id="+ anEntityAdapter.get("id") +\r
520           " and cxm.media_id = m.id";\r
521         if (published)\r
522           condition = "is_published='t' and " + condition;\r
523 \r
524         List extraTables = new ArrayList();\r
525         extraTables.add("content_x_media cxm");\r
526 \r
527         return anEntityAdapter.getComplexRelation("m", extraTables, condition, "id", definition);\r
528       }\r
529       catch (Throwable t) {\r
530         throw new RuntimeException(t.getMessage());\r
531       }\r
532     }\r
533   }\r
534 \r
535   protected class ContentToFirstMediaField implements EntityAdapterDefinition.CalculatedField {\r
536     private String definition;\r
537     private boolean published;\r
538 \r
539     public ContentToFirstMediaField(String aDefinition, boolean anOnlyPublished) {\r
540       definition = aDefinition;\r
541       published = anOnlyPublished;\r
542     }\r
543 \r
544     public ContentToFirstMediaField(String aDefinition) {\r
545       this(aDefinition, true);\r
546     }\r
547 \r
548     public Object getValue(EntityAdapter anEntityAdapter) {\r
549       try {\r
550         String condition = "cxm.content_id="+ anEntityAdapter.get("id") +\r
551           " and cxm.media_id = m.id";\r
552         if (published)\r
553           condition = "is_published='t' and " + condition;\r
554 \r
555         List extraTables = new ArrayList();\r
556         extraTables.add("content_x_media cxm");\r
557 \r
558         return anEntityAdapter.getComplexToOneRelation("m", extraTables, condition, "id", definition);\r
559       }\r
560       catch (Throwable t) {\r
561         throw new RuntimeException(t.getMessage());\r
562       }\r
563     }\r
564   }\r
565 \r
566   protected class CommentToMediaField implements EntityAdapterDefinition.CalculatedField {\r
567     private String definition;\r
568     private boolean published;\r
569 \r
570     public CommentToMediaField(String aDefinition, boolean anOnlyPublished) {\r
571       definition = aDefinition;\r
572       published = anOnlyPublished;\r
573     }\r
574 \r
575     public CommentToMediaField(String aDefinition) {\r
576       this(aDefinition, true);\r
577     }\r
578 \r
579     public Object getValue(EntityAdapter anEntityAdapter) {\r
580       try {\r
581 \r
582         String condition = "cxm.comment_id="+ anEntityAdapter.get("id") +\r
583                   " and cxm.media_id = m.id";\r
584         if (published)\r
585            condition = "is_published='t' and " + condition;\r
586 \r
587         List extraTables = new ArrayList();\r
588         extraTables.add("comment_x_media cxm");\r
589         return anEntityAdapter.getComplexRelation("m", extraTables, condition, "id", definition);\r
590 \r
591       }\r
592       catch (Throwable t) {\r
593         throw new RuntimeException(t.getMessage());\r
594       }\r
595     }\r
596   }\r
597 \r
598   protected class ContentToIconField implements EntityAdapterDefinition.CalculatedField {\r
599     public Object getValue(EntityAdapter anEntityAdapter) {\r
600       EntityAdapter media;\r
601       Entity mediaType;\r
602       RewindableIterator iterator;\r
603       Map result;\r
604       MediaHandler mediaHandler;\r
605       String tinyIcon;\r
606       String iconAlt;\r
607 \r
608       try {\r
609         iterator = (RewindableIterator) (anEntityAdapter.get("to_uploaded_media"));\r
610         iterator.rewind();\r
611 \r
612         tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyText");\r
613         iconAlt = "Text";\r
614 \r
615         if (iterator.hasNext()) {\r
616           media = (EntityAdapter) iterator.next();\r
617 \r
618           mediaType = ((EntityUploadedMedia) (media.getEntity())).getMediaType();\r
619           mediaHandler = MediaHelper.getHandler( mediaType );\r
620 \r
621           tinyIcon = mediaHandler.getTinyIconName();\r
622           iconAlt = mediaHandler.getIconAltName();\r
623         }\r
624       }\r
625       catch (Throwable t) {\r
626         logger.error("ContentToIconField: " +t.getMessage());\r
627         throw new RuntimeException(t.getMessage());\r
628       }\r
629 \r
630       result = new HashMap();\r
631       result.put("tiny_icon", MirGlobal.config().getString("Producer.ImageRoot") + "/" + tinyIcon);\r
632       result.put("icon_alt", iconAlt);\r
633 \r
634       return result;\r
635     }\r
636   }\r
637 \r
638   protected class ContentCommentCountField implements EntityAdapterDefinition.CalculatedField {\r
639     private String extraCondition;\r
640 \r
641     public ContentCommentCountField(String anExtraCondition) {\r
642       super();\r
643 \r
644       extraCondition = anExtraCondition;\r
645     }\r
646 \r
647     public Object getValue(EntityAdapter anEntityAdapter) {\r
648       try {\r
649         return Integer.toString(\r
650             DatabaseComment.getInstance().getSize(\r
651                   "to_media="+anEntityAdapter.get("id")+" " + extraCondition));\r
652       }\r
653       catch (Throwable t) {\r
654         throw new RuntimeException(t.getMessage());\r
655       }\r
656     }\r
657   }\r
658 \r
659   protected class HumanReadableSizeField implements EntityAdapterDefinition.CalculatedField {\r
660       private String fieldName;\r
661 \r
662       public HumanReadableSizeField(String aFieldName) {\r
663         fieldName= aFieldName;\r
664       }\r
665 \r
666       public Object getValue(EntityAdapter anEntityAdapter) {\r
667         try {\r
668           String size = (String) anEntityAdapter.get(fieldName);\r
669           if (size!=null)\r
670             return NumberUtils.humanReadableSize(Double.parseDouble(size));\r
671           else\r
672             return "";\r
673         }\r
674         catch (Throwable t) {\r
675           throw new RuntimeException(t.getMessage());\r
676         }\r
677       }\r
678     }\r
679 \r
680 \r
681   protected class ContentMediaCountField implements EntityAdapterDefinition.CalculatedField {\r
682     private String table;\r
683     private boolean published;\r
684 \r
685     public ContentMediaCountField(String aTable, boolean anOnlyPublished) {\r
686       table = aTable;\r
687       published = anOnlyPublished;\r
688     }\r
689 \r
690     public ContentMediaCountField(String aTable) {\r
691       this(aTable, true);\r
692     }\r
693 \r
694     public Object getValue(EntityAdapter anEntityAdapter) {\r
695       try {\r
696         ArrayList extraTable = new ArrayList();\r
697         extraTable.add(table+" m");\r
698         String selectSql = "cxm.media_id=m.id and cxm.content_id="+\r
699           anEntityAdapter.get("id");\r
700         if (published)\r
701           selectSql+= " and m.is_published='t'";\r
702 \r
703         return Integer.toString(\r
704             DatabaseContentToMedia.getInstance().getSize(\r
705               "cxm", extraTable, selectSql));\r
706       }\r
707       catch (Throwable t) {\r
708         throw new RuntimeException(t.getMessage());\r
709       }\r
710     }\r
711   }\r
712 \r
713   protected class ContentToIsLockedField implements EntityAdapterDefinition.CalculatedField {\r
714     private ModuleContent contentModule;\r
715 \r
716     public ContentToIsLockedField() {\r
717       contentModule = new ModuleContent();\r
718     }\r
719 \r
720     public Object getValue(EntityAdapter anEntityAdapter) {\r
721       try {\r
722         return new Boolean(contentModule.queryArticleLock(anEntityAdapter.getEntity().getId())!=null);\r
723       }\r
724       catch (Throwable t) {\r
725         throw new RuntimeException(t.getMessage());\r
726       }\r
727     }\r
728   }\r
729     protected class ContentIsOriginalField implements EntityAdapterDefinition.CalculatedField {\r
730     public Object getValue(EntityAdapter anEntityAdapter) throws MirLocalizerFailure {\r
731       try {\r
732 \r
733         //ML: add check on article type\r
734         boolean result = (anEntityAdapter.get("parent")==null);\r
735 \r
736         return new Boolean(result);\r
737       }\r
738       catch (Throwable t) {\r
739         throw new MirLocalizerFailure(t);\r
740       }\r
741     }\r
742   }\r
743 \r
744   protected class ContentToOriginalField implements EntityAdapterDefinition.CalculatedField {\r
745     public Object getValue(EntityAdapter anEntityAdapter) throws MirLocalizerFailure {\r
746       try {\r
747         if (anEntityAdapter.get("parent")!=null)\r
748           return anEntityAdapter.get("parent");\r
749         else\r
750           return anEntityAdapter;\r
751       }\r
752       catch (Throwable t) {\r
753         throw new MirLocalizerFailure(t);\r
754       }\r
755     }\r
756   }\r
757 \r
758   protected class ContentToTranslationsField implements EntityAdapterDefinition.CalculatedField {\r
759     public Object getValue(EntityAdapter anEntityAdapter) {\r
760       try {\r
761         return anEntityAdapter.getRelation(\r
762                     "is_published='t' and to_content="+anEntityAdapter.get("id"),\r
763                     "id",\r
764                     "content" );\r
765       }\r
766       catch (Throwable t) {\r
767         throw new RuntimeException(t.getMessage());\r
768       }\r
769     }\r
770   }\r
771 \r
772   protected class ContentToLanguageNameField implements EntityAdapterDefinition.CalculatedField {\r
773     public Object getValue(EntityAdapter anEntityAdapter) throws MirLocalizerFailure {\r
774       try {\r
775         String result = "";\r
776         EntityAdapter language = (EntityAdapter) anEntityAdapter.get("language");\r
777         if (language != null) {\r
778           if (language.get("code").equals("ot")) {\r
779             result = ((String) anEntityAdapter.get("subtitle")).trim();\r
780             if (result == null || result.equals(""))\r
781               result = (String) language.get("name");\r
782           } else {\r
783             result = (String) language.get("name");\r
784           }\r
785         }\r
786 \r
787         return result;\r
788       }\r
789       catch (Throwable t) {\r
790         throw new MirLocalizerFailure(t);\r
791       }\r
792     }\r
793   }\r
794 \r
795   protected class ContentToTranslationFunction implements Generator.Function {\r
796     private EntityAdapter target;\r
797     private String targetId;\r
798     private String targetLanguageId;\r
799 \r
800     public ContentToTranslationFunction(EntityAdapter aTarget) {\r
801       target = aTarget;\r
802       targetId = (String) target.get("id");\r
803       targetLanguageId = (String) target.get("to_language");\r
804     }\r
805 \r
806     public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {\r
807       if (aParameters.size()!=1 || !(aParameters.get(0) instanceof String))\r
808         throw new GeneratorExc("1 string parameter expected");\r
809 \r
810       try {\r
811         String language = (String) aParameters.get(0);\r
812         String languageId = languageModule.languageIdForCode(language);\r
813         Object result = null;\r
814 \r
815         if (languageId != null && !targetLanguageId.equals(languageId)) {\r
816           result = target.getToOneRelation(\r
817               "is_published='t' and to_content=" + targetId + " and to_language='" + JDBCStringRoutines.escapeStringLiteral(languageId) + "'",\r
818               "id", "content");\r
819         }\r
820 \r
821         if (result == null)\r
822           result = target;\r
823 \r
824         return result;\r
825       }\r
826       catch (Throwable t) {\r
827         t.printStackTrace(System.out);\r
828         throw new GeneratorFailure(t);\r
829       }\r
830     }\r
831   }\r
832 \r
833   protected class ContentToTranslationField implements EntityAdapterDefinition.CalculatedField {\r
834     public Object getValue(EntityAdapter anEntityAdapter) throws MirLocalizerFailure {\r
835       try {\r
836         return new ContentToTranslationFunction((EntityAdapter) anEntityAdapter.get("to_original"));\r
837       }\r
838       catch (Throwable t) {\r
839         throw new MirLocalizerFailure(t);\r
840       }\r
841     }\r
842   }\r
843 }\r
844 \r