ef1d75063e045d94a87fb349ec942cb37b6f1cd7
[mir.git] / source / mircoders / localizer / basic / MirBasicDataModelLocalizer.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  any library licensed under the Apache Software License,
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23  * (or with modified versions of the above that use the same license as the above),
24  * and distribute linked combinations including the two.  You must obey the
25  * GNU General Public License in all respects for all of the code used other than
26  * the above mentioned libraries.  If you modify this file, you may extend this
27  * exception to your version of the file, but you are not obligated to do so.
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30 package mircoders.localizer.basic;
31
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Vector;
37
38 import mir.config.MirPropertiesConfiguration;
39 import mir.entity.Entity;
40 import mir.entity.adapter.EntityAdapter;
41 import mir.entity.adapter.EntityAdapterDefinition;
42 import mir.entity.adapter.EntityAdapterModel;
43 import mir.log.LoggerWrapper;
44 import mir.media.MediaHelper;
45 import mir.media.MirMedia;
46 import mir.util.ParameterExpander;
47 import mir.util.RewindableIterator;
48 import mir.util.StructuredContentParser;
49 import mircoders.entity.EntityUploadedMedia;
50 import mircoders.global.MirGlobal;
51 import mircoders.localizer.MirAdminInterfaceLocalizer;
52 import mircoders.localizer.MirDataModelLocalizer;
53 import mircoders.localizer.MirLocalizerExc;
54 import mircoders.localizer.MirLocalizerFailure;
55 import mircoders.storage.DatabaseArticleType;
56 import mircoders.storage.DatabaseAudio;
57 import mircoders.storage.DatabaseBreaking;
58 import mircoders.storage.DatabaseComment;
59 import mircoders.storage.DatabaseCommentStatus;
60 import mircoders.storage.DatabaseContent;
61 import mircoders.storage.DatabaseContentToMedia;
62 import mircoders.storage.DatabaseContentToTopics;
63 import mircoders.storage.DatabaseImageType;
64 import mircoders.storage.DatabaseImages;
65 import mircoders.storage.DatabaseLanguage;
66 import mircoders.storage.DatabaseMediaType;
67 import mircoders.storage.DatabaseMediafolder;
68 import mircoders.storage.DatabaseMessages;
69 import mircoders.storage.DatabaseOther;
70 import mircoders.storage.DatabaseTopics;
71 import mircoders.storage.DatabaseUploadedMedia;
72 import mircoders.storage.DatabaseUsers;
73 import mircoders.storage.DatabaseVideo;
74
75 public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {
76   protected LoggerWrapper logger;
77   protected MirPropertiesConfiguration configuration;
78
79   public MirBasicDataModelLocalizer() throws MirLocalizerFailure, MirLocalizerExc {
80     logger = new LoggerWrapper("Localizer.DataModel");
81
82     try {
83       configuration = MirPropertiesConfiguration.instance();
84     }
85     catch (Throwable e) {
86       throw new MirLocalizerFailure("Can't get configuration: " + e.getMessage(), e);
87     }
88   }
89
90   protected void constructContentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure, MirLocalizerExc {
91     try {
92       anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));
93       anEntityAdapterDefinition.addDBDateField("changedate", "webdb_lastchange", configuration.getString("Mir.DefaultTimezone"));
94       anEntityAdapterDefinition.addMirDateField("date", "date", configuration.getString("Mir.DefaultTimezone"));
95       anEntityAdapterDefinition.addCalculatedField("to_topics", new ContentToTopicsField());
96       anEntityAdapterDefinition.addCalculatedField("to_comments", new ContentToCommentsField());
97       anEntityAdapterDefinition.addCalculatedField("language", new ContentToLanguageField());
98
99       anEntityAdapterDefinition.addCalculatedField("commentcount", new ContentCommentCountField(" and is_published='1'"));
100       anEntityAdapterDefinition.addCalculatedField("fullcommentcount", new ContentCommentCountField(""));
101
102       
103       anEntityAdapterDefinition.addCalculatedField("mediacount", new ContentMediaCountField("uploaded_media", true));
104       anEntityAdapterDefinition.addCalculatedField("fullmediacount", new ContentMediaCountField("uploaded_media", false));
105     
106       anEntityAdapterDefinition.addCalculatedField("to_uploaded_media", new ContentToMediaField( "uploadedMedia" ));      
107       anEntityAdapterDefinition.addCalculatedField("to_media_images",  new ContentToMediaField( "image" ));
108       anEntityAdapterDefinition.addCalculatedField("to_media_audio", new ContentToMediaField( "audio" ));
109       anEntityAdapterDefinition.addCalculatedField("to_media_video", new ContentToMediaField( "video" ));
110       anEntityAdapterDefinition.addCalculatedField("to_media_other", new ContentToMediaField( "otherMedia" ));
111       anEntityAdapterDefinition.addCalculatedField("to_all_uploaded_media", new ContentToMediaField( "uploadedMedia", false));
112       anEntityAdapterDefinition.addCalculatedField("to_all_media_images",  new ContentToMediaField( "image", false));
113       anEntityAdapterDefinition.addCalculatedField("to_all_media_audio", new ContentToMediaField( "audio", false));
114       anEntityAdapterDefinition.addCalculatedField("to_all_media_video", new ContentToMediaField( "video", false));
115       anEntityAdapterDefinition.addCalculatedField("to_all_media_other", new ContentToMediaField( "otherMedia", false));
116       anEntityAdapterDefinition.addCalculatedField("to_media_icon", new ContentToIconField());
117
118       anEntityAdapterDefinition.addCalculatedField("article_type", new ContentToArticleTypeField());
119
120       anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));
121       anEntityAdapterDefinition.addCalculatedField("content_data_parsed", new FilteredField("content_data"));
122
123       anEntityAdapterDefinition.addCalculatedField("children", new ContentToChildrenField());
124       anEntityAdapterDefinition.addCalculatedField("parent", new ContentToParentField());
125
126       anEntityAdapterDefinition.addCalculatedField("publicurl", new ExpandedField(configuration.getString("Article.PublicUrl")));
127
128       anEntityAdapterDefinition.addCalculatedField("operations",
129           new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleArticleOperations()));
130     }
131     catch (Throwable t) {
132       throw new MirLocalizerFailure(t.getMessage(), t);
133     }
134   }
135
136   protected void constructCommentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure {
137     try {
138       anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));
139       anEntityAdapterDefinition.addCalculatedField("to_content", new CommentToContentField());
140       anEntityAdapterDefinition.addCalculatedField("status", new CommentToStatusField());
141
142       anEntityAdapterDefinition.addCalculatedField("to_uploaded_media", new CommentToMediaField( "uploadedMedia" ));
143       anEntityAdapterDefinition.addCalculatedField("to_media_images",  new CommentToMediaField( "image" ));
144       anEntityAdapterDefinition.addCalculatedField("to_media_audio", new CommentToMediaField( "audio" ));
145       anEntityAdapterDefinition.addCalculatedField("to_media_video", new CommentToMediaField( "video" ));
146       anEntityAdapterDefinition.addCalculatedField("to_media_other", new CommentToMediaField( "otherMedia" ));
147       anEntityAdapterDefinition.addCalculatedField("to_all_uploaded_media", new CommentToMediaField( "uploadedMedia", false));
148       anEntityAdapterDefinition.addCalculatedField("to_all_media_images",  new CommentToMediaField( "image", false));
149       anEntityAdapterDefinition.addCalculatedField("to_all_media_audio", new CommentToMediaField( "audio", false));
150       anEntityAdapterDefinition.addCalculatedField("to_all_media_video", new CommentToMediaField( "video", false));
151       anEntityAdapterDefinition.addCalculatedField("to_all_media_other", new CommentToMediaField( "otherMedia", false));
152
153       anEntityAdapterDefinition.addCalculatedField("publicurl", new ExpandedField(configuration.getString("Comment.PublicUrl")));
154
155       anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));
156       anEntityAdapterDefinition.addCalculatedField("operations",
157           new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleCommentOperations()));
158     }
159     catch (Throwable t) {
160       throw new MirLocalizerFailure(t.getMessage(), t);
161     }
162   }
163
164   public EntityAdapterModel adapterModel() throws MirLocalizerFailure, MirLocalizerExc {
165     EntityAdapterModel result = new EntityAdapterModel();
166
167     try {
168       EntityAdapterDefinition definition;
169
170       definition = new EntityAdapterDefinition();
171       constructContentAdapterDefinition( definition );
172       result.addMapping( "content", DatabaseContent.getInstance(), definition);
173
174       definition = new EntityAdapterDefinition();
175       constructCommentAdapterDefinition( definition );
176       result.addMapping( "comment", DatabaseComment.getInstance(), definition);
177       result.addMapping( "commentStatus", DatabaseCommentStatus.getInstance(), new EntityAdapterDefinition());
178
179       result.addMapping( "articleType", DatabaseArticleType.getInstance(), new EntityAdapterDefinition());
180
181       result.addMapping( "mediaType", DatabaseMediaType.getInstance(), new EntityAdapterDefinition());
182
183
184       definition = new EntityAdapterDefinition();
185       definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));
186       result.addMapping( "breakingNews", DatabaseBreaking.getInstance(), definition);
187
188       definition = new EntityAdapterDefinition();
189       definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));
190       result.addMapping( "internalMessage", DatabaseMessages.getInstance(), definition);
191
192       definition = new EntityAdapterDefinition();
193       definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());
194       result.addMapping( "uploadedMedia", DatabaseUploadedMedia.getInstance(), definition);
195       definition = new EntityAdapterDefinition();
196       definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());
197       result.addMapping( "image", DatabaseImages.getInstance(), definition);
198       definition = new EntityAdapterDefinition();
199       definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());
200       result.addMapping( "audio", DatabaseAudio.getInstance(), definition);
201       definition = new EntityAdapterDefinition();
202       definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());
203       result.addMapping( "video", DatabaseVideo.getInstance(), definition);
204       definition = new EntityAdapterDefinition();
205       definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());
206       result.addMapping( "otherMedia", DatabaseOther.getInstance(), definition);
207
208
209       result.addMapping( "mediaFolder", DatabaseMediafolder.getInstance(), new EntityAdapterDefinition());
210       result.addMapping( "imageType", DatabaseImageType.getInstance(), new EntityAdapterDefinition());
211       result.addMapping( "language", DatabaseLanguage.getInstance(), new EntityAdapterDefinition());
212       result.addMapping( "mediaType", DatabaseMediaType.getInstance(), new EntityAdapterDefinition());
213       result.addMapping( "topic", DatabaseTopics.getInstance(), new EntityAdapterDefinition());
214       result.addMapping( "user", DatabaseUsers.getInstance(), new EntityAdapterDefinition());
215       result.addMapping( "otherMedia", DatabaseOther.getInstance(), new EntityAdapterDefinition());
216
217       result.addMapping( "content_x_topic", DatabaseContentToTopics.getInstance(), new EntityAdapterDefinition());
218
219     }
220     catch (Throwable t) {
221       throw new MirLocalizerFailure(t.getMessage(), t);
222     }
223
224     return result;
225   }
226
227   protected class CommentToContentField implements EntityAdapterDefinition.CalculatedField {
228     public Object getValue(EntityAdapter anEntityAdapter) {
229       try {
230         return anEntityAdapter.getToOneRelation(
231                     "id="+anEntityAdapter.get("to_media"),
232                     "id",
233                     "content" );
234       }
235       catch (Throwable t) {
236         throw new RuntimeException(t.getMessage());
237       }
238     }
239   }
240
241   protected class CommentToStatusField implements EntityAdapterDefinition.CalculatedField {
242     public Object getValue(EntityAdapter anEntityAdapter) {
243       try {
244         return anEntityAdapter.getToOneRelation(
245                     "id="+anEntityAdapter.get("to_comment_status"),
246                     "id",
247                     "commentStatus" );
248       }
249       catch (Throwable t) {
250         throw new RuntimeException(t.getMessage());
251       }
252     }
253   }
254
255   protected class EntityToSimpleOperationsField implements EntityAdapterDefinition.CalculatedField {
256     private List operations;
257
258     public EntityToSimpleOperationsField(List anOperations) {
259       operations = anOperations;
260     }
261
262     public Object getValue(EntityAdapter anEntityAdapter) {
263       try {
264         Iterator i = operations.iterator();
265         List availableOperations = new Vector();
266
267         while (i.hasNext()) {
268           MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =
269             (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();
270
271           if (operation.isAvailable(anEntityAdapter)) {
272             availableOperations.add(operation.getName());
273           }
274         };
275
276         return availableOperations;
277       }
278       catch (Throwable t) {
279         throw new RuntimeException(t.getMessage());
280       }
281     }
282   }
283
284   protected class FilteredField implements EntityAdapterDefinition.CalculatedField {
285     private String fieldName;
286
287     public FilteredField(String aFieldName) {
288       fieldName = aFieldName;
289     }
290
291     public Object getValue(EntityAdapter anEntityAdapter) {
292       try {
293         if (anEntityAdapter.get("is_html")!=null && anEntityAdapter.get("is_html").equals("1")) {
294           return MirGlobal.localizer().producerAssistant().filterHTMLText((String) anEntityAdapter.get(fieldName));
295         }
296         else {
297           return MirGlobal.localizer().producerAssistant().filterNonHTMLText((String) anEntityAdapter.get(fieldName));
298         }
299       }
300       catch (Throwable t) {
301         throw new RuntimeException(t.getMessage());
302       }
303     }
304   }
305
306   protected class StructuredContentField implements EntityAdapterDefinition.CalculatedField {
307     private String expression;
308
309     public StructuredContentField(String anExpression) {
310       expression = anExpression;
311     }
312
313     public Object getValue(EntityAdapter anEntityAdapter) {
314       try {
315         return StructuredContentParser.parse(ParameterExpander.evaluateStringExpression(anEntityAdapter, expression));
316       }
317       catch (Throwable t) {
318         throw new RuntimeException(t.getMessage());
319       }
320     }
321   }
322
323   protected class ExpandedField implements EntityAdapterDefinition.CalculatedField {
324     private String expression;
325
326     public ExpandedField(String anExpression) {
327       expression = anExpression;
328     }
329
330     public Object getValue(EntityAdapter anEntityAdapter) {
331       try {
332         return ParameterExpander.expandExpression(anEntityAdapter, expression);
333       }
334       catch (Throwable t) {
335         throw new RuntimeException(t.getMessage());
336       }
337     }
338   }
339
340   protected class EvaluatedField implements EntityAdapterDefinition.CalculatedField {
341     private String expression;
342
343     public EvaluatedField(String anExpression) {
344       expression = anExpression;
345     }
346
347     public Object getValue(EntityAdapter anEntityAdapter) {
348       try {
349         return ParameterExpander.evaluateExpression(anEntityAdapter, expression);
350       }
351       catch (Throwable t) {
352         throw new RuntimeException(t.getMessage());
353       }
354     }
355   }
356
357   protected class ContentToParentField implements EntityAdapterDefinition.CalculatedField {
358     public Object getValue(EntityAdapter anEntityAdapter) {
359       try {
360         logger.debug("ContentToParentField.getValue");
361         return anEntityAdapter.getToOneRelation(
362                     "id="+anEntityAdapter.get("to_content"),
363                     "id",
364                     "content" );
365       }
366       catch (Throwable t) {
367         throw new RuntimeException(t.getMessage());
368       }
369     }
370   }
371
372   protected class ContentToChildrenField implements EntityAdapterDefinition.CalculatedField {
373     public Object getValue(EntityAdapter anEntityAdapter) {
374       try {
375         return anEntityAdapter.getRelation(
376                     "to_content="+anEntityAdapter.get("id"),
377                     "id",
378                     "content" );
379       }
380       catch (Throwable t) {
381         throw new RuntimeException(t.getMessage());
382       }
383     }
384   }
385
386   protected class ContentToLanguageField implements EntityAdapterDefinition.CalculatedField {
387     public Object getValue(EntityAdapter anEntityAdapter) {
388       try {
389         return anEntityAdapter.getToOneRelation(
390                     "id="+anEntityAdapter.get("to_language"),
391                     "id",
392                     "language" );
393       }
394       catch (Throwable t) {
395         throw new RuntimeException(t.getMessage());
396       }
397     }
398   }
399
400   protected class ContentToArticleTypeField implements EntityAdapterDefinition.CalculatedField {
401     public Object getValue(EntityAdapter anEntityAdapter) {
402       try {
403         return anEntityAdapter.getToOneRelation(
404                     "id="+anEntityAdapter.get("to_article_type"),
405                     "id",
406                     "articleType" );
407       }
408       catch (Throwable t) {
409         throw new RuntimeException(t.getMessage());
410       }
411     }
412   }
413
414   protected class MediaToMediaFolderField implements EntityAdapterDefinition.CalculatedField {
415     public Object getValue(EntityAdapter anEntityAdapter) {
416       try {
417         return anEntityAdapter.getToOneRelation(
418                     "id="+anEntityAdapter.get("to_media_folder"),
419                     "id",
420                     "mediaFolder" );
421       }
422       catch (Throwable t) {
423         throw new RuntimeException(t.getMessage());
424       }
425     }
426   }
427
428   protected class ContentToCommentsField implements EntityAdapterDefinition.CalculatedField {
429     private String extracondition;
430     private String order;
431
432     public ContentToCommentsField() {
433       this ( " and is_published='1'", "webdb_create");
434     }
435
436     public ContentToCommentsField(String anExtraCondition, String anOrder) {
437       order = anOrder;
438       extracondition = anExtraCondition;
439     }
440
441     public Object getValue(EntityAdapter anEntityAdapter) {
442       try {
443         return anEntityAdapter.getRelation(
444                     "to_media="+anEntityAdapter.get("id")+" " + extracondition,
445                     order,
446                     "comment" );
447       }
448       catch (Throwable t) {
449         throw new RuntimeException(t.getMessage());
450       }
451     }
452   }
453
454   protected class ContentToTopicsField implements EntityAdapterDefinition.CalculatedField {
455     private String topicCondition;
456     private String topicOrder;
457
458     public ContentToTopicsField() {
459       this(null);
460     }
461
462     public ContentToTopicsField(String aTopicCondition) {
463       this(aTopicCondition, "title");
464     }
465
466     public ContentToTopicsField(String aTopicCondition, String aTopicOrder) {
467       topicCondition = aTopicCondition;
468       topicOrder = aTopicOrder;
469     }
470
471     public Object getValue(EntityAdapter anEntityAdapter) {
472       try {
473         
474         Vector extraTable = new Vector();
475         extraTable.add("content_x_topic cxt");
476         String condition = "cxt.content_id="+anEntityAdapter.get("id")+
477           " and cxt.topic_id=t.id";
478         
479         if (topicCondition!=null && topicCondition.length()>0)
480           condition = "(" + topicCondition + ") and " + condition;
481
482         return anEntityAdapter.getComplexRelation("t", extraTable,
483                     condition, topicOrder, "topic" );                    
484       }
485       catch (Throwable t) {
486         throw new RuntimeException(t.getMessage());
487       }
488     }
489   }
490
491   protected class ContentToMediaField implements EntityAdapterDefinition.CalculatedField {
492     private String definition;
493     private boolean published;
494
495     public ContentToMediaField(String aDefinition, boolean anOnlyPublished) {
496       definition = aDefinition;
497       published = anOnlyPublished;
498     }
499
500     public ContentToMediaField(String aDefinition) {
501       this(aDefinition, true);
502     }
503
504     public Object getValue(EntityAdapter anEntityAdapter) {
505       try {
506         String condition = "cxm.content_id="+ anEntityAdapter.get("id") +
507           " and cxm.media_id = m.id";        
508         if (published)
509           condition = "is_published='t' and " + condition;
510
511         List extraTables = new Vector();
512         extraTables.add("content_x_media cxm");        
513           
514         return anEntityAdapter.getComplexRelation("m", extraTables, condition, "id", definition);
515       }
516       catch (Throwable t) {
517         throw new RuntimeException(t.getMessage());
518       }
519     }
520   }
521
522   protected class CommentToMediaField implements EntityAdapterDefinition.CalculatedField {
523     private String definition;
524     private boolean published;
525
526     public CommentToMediaField(String aDefinition, boolean anOnlyPublished) {
527       definition = aDefinition;
528       published = anOnlyPublished;
529     }
530
531     public CommentToMediaField(String aDefinition) {
532       this(aDefinition, true);
533     }
534
535     public Object getValue(EntityAdapter anEntityAdapter) {
536       try {
537
538         String condition = "cxm.comment_id="+ anEntityAdapter.get("id") +
539                   " and cxm.media_id = m.id";        
540         if (published)
541            condition = "is_published='t' and " + condition;
542
543         List extraTables = new Vector();
544         extraTables.add("comment_x_media cxm");          
545         return anEntityAdapter.getComplexRelation("m", extraTables, condition, "id", definition);
546
547       }
548       catch (Throwable t) {
549         throw new RuntimeException(t.getMessage());
550       }
551     }
552   }
553
554   protected class ContentToIconField implements EntityAdapterDefinition.CalculatedField {
555     public Object getValue(EntityAdapter anEntityAdapter) {
556       EntityAdapter media;
557       Entity mediaType;
558       RewindableIterator iterator;
559       Map result;
560       MirMedia mediaHandler;
561       String tinyIcon;
562       String iconAlt;
563
564       try {
565         iterator = (RewindableIterator) (anEntityAdapter.get("to_uploaded_media"));
566         iterator.rewind();
567
568         tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyText");
569         iconAlt = "Text";
570
571         // TODO only first media counts?
572         if (iterator.hasNext()) {
573           media = (EntityAdapter) iterator.next();
574
575           mediaType = ((EntityUploadedMedia) (media.getEntity())).getMediaType();
576           mediaHandler = MediaHelper.getHandler( mediaType );
577
578           if (mediaHandler.isVideo()) {
579             tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyVideo");
580             iconAlt = "Video";
581           }
582           else if (mediaHandler.isAudio()) {
583             tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyAudio");
584             iconAlt = "Audio";
585           }
586           else if (mediaHandler.isImage()) {
587             tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyImage");
588             iconAlt = "Image";
589           }
590           else {
591             tinyIcon = mediaHandler.getTinyIconName();
592             iconAlt = mediaHandler.getIconAltName();
593           }
594
595         }
596       }
597       catch (Throwable t) {
598         logger.error("ContentToIconField: " +t.getMessage());
599         throw new RuntimeException(t.getMessage());
600       }
601
602       result = new HashMap();
603       result.put("tiny_icon", MirGlobal.config().getString("Producer.ImageRoot") + "/" + tinyIcon);
604       result.put("icon_alt", iconAlt);
605
606       return result;
607     }
608   }
609
610   protected class ContentCommentCountField implements EntityAdapterDefinition.CalculatedField {
611     private String extraCondition;
612
613     public ContentCommentCountField(String anExtraCondition) {
614       super();
615
616       extraCondition = anExtraCondition;
617     }
618
619     public Object getValue(EntityAdapter anEntityAdapter) {
620       try {
621         return Integer.toString(
622             DatabaseComment.getInstance().getSize(
623                   "to_media="+anEntityAdapter.get("id")+" " + extraCondition));
624       }
625       catch (Throwable t) {
626         throw new RuntimeException(t.getMessage());
627       }
628     }
629   }
630
631   protected class ContentMediaCountField implements EntityAdapterDefinition.CalculatedField {
632     private String table;
633     private boolean published;
634
635     public ContentMediaCountField(String aTable, boolean anOnlyPublished) {
636       table = aTable;
637       published = anOnlyPublished;
638     }
639
640     public ContentMediaCountField(String aTable) {
641       this(aTable, true);
642     }
643
644     public Object getValue(EntityAdapter anEntityAdapter) {
645       try {        
646         Vector extraTable = new Vector();
647         extraTable.add(table+" m");
648         String selectSql = "cxm.media_id=m.id and cxm.content_id="+
649           anEntityAdapter.get("id");
650         if (published)
651           selectSql+= " and m.is_published='t'";
652
653         return Integer.toString(
654             DatabaseContentToMedia.getInstance().getSize(
655               "cxm", extraTable, selectSql));
656       }
657       catch (Throwable t) {
658         throw new RuntimeException(t.getMessage());
659       }
660     }
661   }
662 }