misc. fixes
[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 mircoders.entity.EntityUploadedMedia;
49 import mircoders.global.MirGlobal;
50 import mircoders.localizer.MirAdminInterfaceLocalizer;
51 import mircoders.localizer.MirDataModelLocalizer;
52 import mircoders.localizer.MirLocalizerExc;
53 import mircoders.localizer.MirLocalizerFailure;
54 import mircoders.storage.DatabaseArticleType;
55 import mircoders.storage.DatabaseAudio;
56 import mircoders.storage.DatabaseBreaking;
57 import mircoders.storage.DatabaseComment;
58 import mircoders.storage.DatabaseCommentStatus;
59 import mircoders.storage.DatabaseContent;
60 import mircoders.storage.DatabaseImageType;
61 import mircoders.storage.DatabaseImages;
62 import mircoders.storage.DatabaseLanguage;
63 import mircoders.storage.DatabaseMedia;
64 import mircoders.storage.DatabaseMediaType;
65 import mircoders.storage.DatabaseMediafolder;
66 import mircoders.storage.DatabaseMessages;
67 import mircoders.storage.DatabaseOther;
68 import mircoders.storage.DatabaseTopics;
69 import mircoders.storage.DatabaseUploadedMedia;
70 import mircoders.storage.DatabaseUsers;
71 import mircoders.storage.DatabaseVideo;
72
73 public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {
74   private EntityAdapterModel model;
75   protected LoggerWrapper logger;
76   protected MirPropertiesConfiguration configuration;
77
78   public MirBasicDataModelLocalizer() throws MirLocalizerFailure, MirLocalizerExc {
79     model=null;
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   public EntityAdapterModel adapterModel() throws MirLocalizerFailure {
91     if (model==null)
92       model = buildModel();
93
94     return model;
95   };
96
97   protected void constructContentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure {
98     try {
99       anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create");
100       anEntityAdapterDefinition.addDBDateField("changedate", "webdb_lastchange");
101       anEntityAdapterDefinition.addMirDateField("date", "date");
102       anEntityAdapterDefinition.addCalculatedField("to_topics", new ContentToTopicsField());
103       anEntityAdapterDefinition.addCalculatedField("to_comments", new ContentToCommentsField());
104       anEntityAdapterDefinition.addCalculatedField("language", new ContentToLanguageField());
105
106       anEntityAdapterDefinition.addCalculatedField("commentcount", new ContentCommentCountField(" and is_published='1'"));
107       anEntityAdapterDefinition.addCalculatedField("fullcommentcount", new ContentCommentCountField(""));
108
109       anEntityAdapterDefinition.addCalculatedField("to_uploaded_media", new ContentToMediaField( "uploadedMedia" ));
110       anEntityAdapterDefinition.addCalculatedField("to_media_images",  new ContentToMediaField( "image" ));
111       anEntityAdapterDefinition.addCalculatedField("to_media_audio", new ContentToMediaField( "audio" ));
112       anEntityAdapterDefinition.addCalculatedField("to_media_video", new ContentToMediaField( "video" ));
113       anEntityAdapterDefinition.addCalculatedField("to_media_other", new ContentToMediaField( "otherMedia" ));
114       anEntityAdapterDefinition.addCalculatedField("to_all_uploaded_media", new ContentToMediaField( "uploadedMedia", false));
115       anEntityAdapterDefinition.addCalculatedField("to_all_media_images",  new ContentToMediaField( "image", false));
116       anEntityAdapterDefinition.addCalculatedField("to_all_media_audio", new ContentToMediaField( "audio", false));
117       anEntityAdapterDefinition.addCalculatedField("to_all_media_video", new ContentToMediaField( "video", false));
118       anEntityAdapterDefinition.addCalculatedField("to_all_media_other", new ContentToMediaField( "otherMedia", false));
119       anEntityAdapterDefinition.addCalculatedField("to_media_icon", new ContentToIconField());
120
121       anEntityAdapterDefinition.addCalculatedField("article_type", new ContentToArticleTypeField());
122
123       anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));
124       anEntityAdapterDefinition.addCalculatedField("content_data_parsed", new FilteredField("content_data"));
125
126       anEntityAdapterDefinition.addCalculatedField("children", new ContentToChildrenField());
127       anEntityAdapterDefinition.addCalculatedField("parent", new ContentToParentField());
128
129       anEntityAdapterDefinition.addCalculatedField("publicurl", new ExpandedField(configuration.getString("Article.PublicUrl")));
130
131       anEntityAdapterDefinition.addCalculatedField("operations",
132           new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleArticleOperations()));
133     }
134     catch (Throwable t) {
135       throw new MirLocalizerFailure(t.getMessage(), t);
136     }
137   }
138
139   protected void constructCommentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure {
140     try {
141       anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create");
142       anEntityAdapterDefinition.addCalculatedField("to_content", new CommentToContentField());
143       anEntityAdapterDefinition.addCalculatedField("status", new CommentToStatusField());
144
145       anEntityAdapterDefinition.addCalculatedField("to_uploaded_media", new CommentToMediaField( "uploadedMedia" ));
146       anEntityAdapterDefinition.addCalculatedField("to_media_images",  new CommentToMediaField( "image" ));
147       anEntityAdapterDefinition.addCalculatedField("to_media_audio", new CommentToMediaField( "audio" ));
148       anEntityAdapterDefinition.addCalculatedField("to_media_video", new CommentToMediaField( "video" ));
149       anEntityAdapterDefinition.addCalculatedField("to_media_other", new CommentToMediaField( "otherMedia" ));
150       anEntityAdapterDefinition.addCalculatedField("to_all_uploaded_media", new CommentToMediaField( "uploadedMedia", false));
151       anEntityAdapterDefinition.addCalculatedField("to_all_media_images",  new CommentToMediaField( "image", false));
152       anEntityAdapterDefinition.addCalculatedField("to_all_media_audio", new CommentToMediaField( "audio", false));
153       anEntityAdapterDefinition.addCalculatedField("to_all_media_video", new CommentToMediaField( "video", false));
154       anEntityAdapterDefinition.addCalculatedField("to_all_media_other", new CommentToMediaField( "otherMedia", false));
155
156       anEntityAdapterDefinition.addCalculatedField("publicurl", new ExpandedField(configuration.getString("Comment.PublicUrl")));
157
158       anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));
159       anEntityAdapterDefinition.addCalculatedField("operations",
160           new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleCommentOperations()));
161     }
162     catch (Throwable t) {
163       throw new MirLocalizerFailure(t.getMessage(), t);
164     }
165   }
166
167   protected EntityAdapterModel buildModel() throws MirLocalizerFailure {
168     EntityAdapterModel result = new EntityAdapterModel();
169
170     try {
171       EntityAdapterDefinition definition;
172
173       definition = new EntityAdapterDefinition();
174       constructContentAdapterDefinition( definition );
175       result.addMapping( "content", DatabaseContent.getInstance(), definition);
176
177       definition = new EntityAdapterDefinition();
178       constructCommentAdapterDefinition( definition );
179       result.addMapping( "comment", DatabaseComment.getInstance(), definition);
180
181       result.addMapping( "articleType", DatabaseArticleType.getInstance(), new EntityAdapterDefinition());
182       result.addMapping( "commentStatus", DatabaseCommentStatus.getInstance(), new EntityAdapterDefinition());
183
184       definition = new EntityAdapterDefinition();
185       definition.addDBDateField("creationdate", "webdb_create");
186       result.addMapping( "breakingNews", DatabaseBreaking.getInstance(), definition);
187
188       result.addMapping( "imageType", DatabaseImageType.getInstance(), new EntityAdapterDefinition());
189       result.addMapping( "language", DatabaseLanguage.getInstance(), new EntityAdapterDefinition());
190       result.addMapping( "mediaFolder", DatabaseMediafolder.getInstance(), new EntityAdapterDefinition());
191       result.addMapping( "mediaType", DatabaseMediaType.getInstance(), new EntityAdapterDefinition());
192       result.addMapping( "internalMessage", DatabaseMessages.getInstance(), new EntityAdapterDefinition());
193       result.addMapping( "topic", DatabaseTopics.getInstance(), new EntityAdapterDefinition());
194       result.addMapping( "user", DatabaseUsers.getInstance(), new EntityAdapterDefinition());
195       result.addMapping( "media", DatabaseMedia.getInstance(), new EntityAdapterDefinition());
196       result.addMapping( "uploadedMedia", DatabaseUploadedMedia.getInstance(), new EntityAdapterDefinition());
197       result.addMapping( "image", DatabaseImages.getInstance(), new EntityAdapterDefinition());
198       result.addMapping( "audio", DatabaseAudio.getInstance(), new EntityAdapterDefinition());
199       result.addMapping( "video", DatabaseVideo.getInstance(), new EntityAdapterDefinition());
200       result.addMapping( "otherMedia", DatabaseOther.getInstance(), new EntityAdapterDefinition());
201     }
202     catch (Throwable t) {
203       throw new MirLocalizerFailure(t.getMessage(), t);
204     }
205
206     return result;
207   }
208
209   protected class CommentToContentField implements EntityAdapterDefinition.CalculatedField {
210     public Object getValue(EntityAdapter anEntityAdapter) {
211       try {
212         return anEntityAdapter.getToOneRelation(
213                     "id="+anEntityAdapter.get("to_media"),
214                     "id",
215                     "content" );
216       }
217       catch (Throwable t) {
218         throw new RuntimeException(t.getMessage());
219       }
220     }
221   }
222
223   protected class CommentToStatusField implements EntityAdapterDefinition.CalculatedField {
224     public Object getValue(EntityAdapter anEntityAdapter) {
225       try {
226         return anEntityAdapter.getToOneRelation(
227                     "id="+anEntityAdapter.get("to_comment_status"),
228                     "id",
229                     "commentStatus" );
230       }
231       catch (Throwable t) {
232         throw new RuntimeException(t.getMessage());
233       }
234     }
235   }
236
237   protected class EntityToSimpleOperationsField implements EntityAdapterDefinition.CalculatedField {
238     private List operations;
239
240     public EntityToSimpleOperationsField(List anOperations) {
241       operations = anOperations;
242     }
243
244     public Object getValue(EntityAdapter anEntityAdapter) {
245       try {
246         Iterator i = operations.iterator();
247         List availableOperations = new Vector();
248
249         while (i.hasNext()) {
250           MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =
251             (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();
252
253           if (operation.isAvailable(anEntityAdapter)) {
254             availableOperations.add(operation.getName());
255           }
256         };
257
258         return availableOperations;
259       }
260       catch (Throwable t) {
261         throw new RuntimeException(t.getMessage());
262       }
263     }
264   }
265
266   protected class FilteredField implements EntityAdapterDefinition.CalculatedField {
267     private String fieldName;
268
269     public FilteredField(String aFieldName) {
270       fieldName = aFieldName;
271     }
272
273     public Object getValue(EntityAdapter anEntityAdapter) {
274       try {
275         if (anEntityAdapter.get("is_html")!=null && anEntityAdapter.get("is_html").equals("1")) {
276           return MirGlobal.localizer().producerAssistant().filterHTMLText((String) anEntityAdapter.get(fieldName));
277         }
278         else {
279           return MirGlobal.localizer().producerAssistant().filterNonHTMLText((String) anEntityAdapter.get(fieldName));
280         }
281       }
282       catch (Throwable t) {
283         throw new RuntimeException(t.getMessage());
284       }
285     }
286   }
287
288   protected class ExpandedField implements EntityAdapterDefinition.CalculatedField {
289     private String expression;
290
291     public ExpandedField(String anExpression) {
292       expression = anExpression;
293     }
294
295     public Object getValue(EntityAdapter anEntityAdapter) {
296       try {
297         return ParameterExpander.expandExpression(anEntityAdapter, expression);
298       }
299       catch (Throwable t) {
300         throw new RuntimeException(t.getMessage());
301       }
302     }
303   }
304
305   protected class EvaluatedField implements EntityAdapterDefinition.CalculatedField {
306     private String expression;
307
308     public EvaluatedField(String anExpression) {
309       expression = anExpression;
310     }
311
312     public Object getValue(EntityAdapter anEntityAdapter) {
313       try {
314         return ParameterExpander.evaluateExpression(anEntityAdapter, expression);
315       }
316       catch (Throwable t) {
317         throw new RuntimeException(t.getMessage());
318       }
319     }
320   }
321
322   protected class ContentToParentField implements EntityAdapterDefinition.CalculatedField {
323     public Object getValue(EntityAdapter anEntityAdapter) {
324       try {
325         logger.debug("ContentToParentField.getValue");
326         return anEntityAdapter.getToOneRelation(
327                     "id="+anEntityAdapter.get("to_content"),
328                     "id",
329                     "content" );
330       }
331       catch (Throwable t) {
332         throw new RuntimeException(t.getMessage());
333       }
334     }
335   }
336
337   protected class ContentToChildrenField implements EntityAdapterDefinition.CalculatedField {
338     public Object getValue(EntityAdapter anEntityAdapter) {
339       try {
340         return anEntityAdapter.getRelation(
341                     "to_content="+anEntityAdapter.get("id"),
342                     "id",
343                     "content" );
344       }
345       catch (Throwable t) {
346         throw new RuntimeException(t.getMessage());
347       }
348     }
349   }
350
351   protected class ContentToLanguageField implements EntityAdapterDefinition.CalculatedField {
352     public Object getValue(EntityAdapter anEntityAdapter) {
353       try {
354         return anEntityAdapter.getToOneRelation(
355                     "id="+anEntityAdapter.get("to_language"),
356                     "id",
357                     "language" );
358       }
359       catch (Throwable t) {
360         throw new RuntimeException(t.getMessage());
361       }
362     }
363   }
364
365   protected class ContentToArticleTypeField implements EntityAdapterDefinition.CalculatedField {
366     public Object getValue(EntityAdapter anEntityAdapter) {
367       try {
368         return anEntityAdapter.getToOneRelation(
369                     "id="+anEntityAdapter.get("to_article_type"),
370                     "id",
371                     "articleType" );
372       }
373       catch (Throwable t) {
374         throw new RuntimeException(t.getMessage());
375       }
376     }
377   }
378
379   protected class ContentToCommentsField implements EntityAdapterDefinition.CalculatedField {
380     public Object getValue(EntityAdapter anEntityAdapter) {
381       try {
382         return anEntityAdapter.getRelation(
383                     "to_media="+anEntityAdapter.get("id")+" and is_published='1'",
384                     "webdb_create",
385                     "comment" );
386       }
387       catch (Throwable t) {
388         throw new RuntimeException(t.getMessage());
389       }
390     }
391   }
392
393   protected class ContentToTopicsField implements EntityAdapterDefinition.CalculatedField {
394     public Object getValue(EntityAdapter anEntityAdapter) {
395       try {
396         return anEntityAdapter.getRelation(
397                     "exists (select * from content_x_topic where content_id="+anEntityAdapter.get("id")+" and topic_id=id)",
398                     "title",
399                     "topic" );
400       }
401       catch (Throwable t) {
402         throw new RuntimeException(t.getMessage());
403       }
404     }
405   }
406
407   protected class ContentToMediaField implements EntityAdapterDefinition.CalculatedField {
408     private String definition;
409     private boolean published;
410
411     public ContentToMediaField(String aDefinition, boolean anOnlyPublished) {
412       definition = aDefinition;
413       published = anOnlyPublished;
414     }
415
416     public ContentToMediaField(String aDefinition) {
417       this(aDefinition, true);
418     }
419
420     public Object getValue(EntityAdapter anEntityAdapter) {
421       try {
422         String condition = "exists (select * from content_x_media where content_id="+anEntityAdapter.get("id")+" and media_id=id)";
423         if (published)
424           condition = "is_published='t' and " + condition;
425         return anEntityAdapter.getRelation(
426            condition,
427           "id",
428           definition);
429       }
430       catch (Throwable t) {
431         throw new RuntimeException(t.getMessage());
432       }
433     }
434   }
435
436   protected class CommentToMediaField implements EntityAdapterDefinition.CalculatedField {
437     private String definition;
438     private boolean published;
439
440     public CommentToMediaField(String aDefinition, boolean anOnlyPublished) {
441       definition = aDefinition;
442       published = anOnlyPublished;
443     }
444
445     public CommentToMediaField(String aDefinition) {
446       this(aDefinition, true);
447     }
448
449     public Object getValue(EntityAdapter anEntityAdapter) {
450       try {
451         String condition = "exists (select * from comment_x_media where comment_id="+anEntityAdapter.get("id")+" and media_id=id)";
452         if (published)
453           condition = "is_published='t' and " + condition;
454         return anEntityAdapter.getRelation(
455            condition,
456           "id",
457           definition);
458       }
459       catch (Throwable t) {
460         throw new RuntimeException(t.getMessage());
461       }
462     }
463   }
464
465   protected class ContentToIconField implements EntityAdapterDefinition.CalculatedField {
466     public Object getValue(EntityAdapter anEntityAdapter) {
467       EntityAdapter media;
468       Entity mediaType;
469       RewindableIterator iterator;
470       Map result;
471       MirMedia mediaHandler;
472       String tinyIcon;
473       String iconAlt;
474
475       try {
476         iterator = (RewindableIterator) (anEntityAdapter.get("to_uploaded_media"));
477         iterator.rewind();
478
479         tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyText");
480         iconAlt = "Text";
481
482         if (iterator.hasNext()) {
483           media = (EntityAdapter) iterator.next();
484
485           mediaType = ((EntityUploadedMedia) (media.getEntity())).getMediaType();
486           mediaHandler = MediaHelper.getHandler( mediaType );
487
488           if (mediaHandler.isVideo()) {
489             tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyVideo");
490             iconAlt = "Video";
491           }
492           else if (mediaHandler.isAudio()) {
493             tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyAudio");
494             iconAlt = "Audio";
495           }
496           else if (mediaHandler.isImage()) {
497             tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyImage");
498             iconAlt = "Image";
499           }
500           else {
501             tinyIcon = mediaHandler.getTinyIconName();
502             iconAlt = mediaHandler.getIconAltName();
503           }
504
505         }
506       }
507       catch (Throwable t) {
508         logger.error("ContentToIconField: " +t.getMessage());
509         throw new RuntimeException(t.getMessage());
510       }
511
512       result = new HashMap();
513       result.put("tiny_icon", MirGlobal.config().getString("Producer.ImageRoot") + "/" + tinyIcon);
514       result.put("icon_alt", iconAlt);
515
516       return result;
517     }
518   }
519
520   protected class ContentCommentCountField implements EntityAdapterDefinition.CalculatedField {
521     private String extraCondition;
522
523     public ContentCommentCountField(String anExtraCondition) {
524       super();
525
526       extraCondition = anExtraCondition;
527     }
528
529     public Object getValue(EntityAdapter anEntityAdapter) {
530       try {
531         return Integer.toString(
532             DatabaseComment.getInstance().getSize(
533                   "to_media="+anEntityAdapter.get("id")+" " + extraCondition));
534       }
535       catch (Throwable t) {
536         throw new RuntimeException(t.getMessage());
537       }
538     }
539   }
540 }