testing extratable selectByWhereClause
authorrk <rk>
Mon, 24 Nov 2003 19:57:54 +0000 (19:57 +0000)
committerrk <rk>
Mon, 24 Nov 2003 19:57:54 +0000 (19:57 +0000)
doc/INSTALL.mir
doc/LOCALIZER.HOWTO
doc/README
source/mir/storage/Database.java
source/mircoders/localizer/basic/MirBasicDataModelLocalizer.java
source/mircoders/storage/DatabaseContentToTopics.java

index 4405418..d011c7b 100755 (executable)
@@ -1,6 +1,6 @@
 MIR INSTALLATION HOWTO
 
-Last updated: $Date: 2003/07/06 04:02:29 $
+Last updated: $Date: 2003/11/24 19:57:54 $
 ----------------------------------------------------------------
 
 Here is a short installation-howto of Mir.
@@ -95,7 +95,7 @@ manupulation.
 The database name should be the same as in config.properties. Please look at
 the section "Database.*" to look up the names or change them to your needs. 
 
-It is wise in terms of system seurity to use an unprivileged user for this
+It is wise in terms of system security to use an unprivileged user for this
 task instead of the superuser. This is because if Mir uses the superuser to
 connect to the database and anybody manages to find out the password Mir 
 uses to connect, the attacker can take over the complete database. So, in
@@ -260,4 +260,4 @@ You can give these a try if anything goes wrong:
 
 ----------------------------------------------------------------
 
-$Date: 2003/07/06 04:02:29 $ - the Mir coders
+$Date: 2003/11/24 19:57:54 $ - the Mir coders
index 3bbc22e..5fd5170 100755 (executable)
@@ -1,2 +1,20 @@
-This is the HOWTO of Mir Localization feature
-Version: $Date: 2003/10/28 15:18:17 $
+Version: $Date: 2003/11/24 19:57:54 $
+
+This is the HOWTO of the Localization infrastructure 
+which allows easy low-level customization of Mir.
+
+
+1. Mir.Localizer
+
+In the file config.properties-dist 
+Mir.Localizer=mircoders.localizer.basic.MirBasicLocalizer
+
+JUST NOTES:
+
+-Document how to enable your own CVS tree
+-Localizer code must be in etc/extrasource
+-build.xml is aware of etc/extrasource
+-contents of etc can be stored in extra cvs
+-which of etc is known to ant?
+-outside of etc nothing should be altered!
+-producers can be configured in config.properties
index 5653316..6ad2fb0 100755 (executable)
@@ -1,4 +1,4 @@
-last changed $Date: 2002/12/24 01:45:54 $
+last changed $Date: 2003/11/24 19:57:54 $
 -----------------------------------------
 
 GENERAL INFO
@@ -83,6 +83,6 @@ In the upcoming 1.1 release
 * completely rewrite of the producer layer. Runs in it's own thread.
   Configurable via an XML file to dynamically choose the structure the site
   should take, what should be archived...
-* Introduction of the Localization infracstructure to allow easy low-level
+* Introduction of the Localization infrastructure to allow easy low-level
   customization of Mir.
 
index a4b3e37..fde49b2 100755 (executable)
@@ -75,7 +75,7 @@ import com.codestudio.util.SQLManager;
  * Treiber, Host, User und Passwort, ueber den der Zugriff auf die
  * Datenbank erfolgt.
  *
- * @version $Id: Database.java,v 1.44.2.7 2003/10/23 14:55:29 rk Exp $
+ * @version $Id: Database.java,v 1.44.2.8 2003/11/24 19:57:54 rk Exp $
  * @author rk
  *
  */
@@ -258,12 +258,13 @@ public class Database implements StorageObject {
     return metadataFields;
   }
 
-  /*
-  *   Gets value out of ResultSet according to type and converts to String
-  *   @param inValue  Wert aus ResultSet.
-  *   @param aType  Datenbanktyp.
-  *   @return liefert den Wert als String zurueck. Wenn keine Umwandlung moeglich
-  *           dann /unsupported value/
+  /**
+   *   Gets value out of ResultSet according to type and converts to String
+   *   @param rs  ResultSet.
+   *   @param aType  a type from java.sql.Types.*
+   *   @param index  index in ResultSet
+   *   @return returns the value as String. If no conversion is possible
+   *                            /unsupported value/ is returned
    */
   private String getValueAsString(ResultSet rs, int valueIndex, int aType)
     throws StorageObjectFailure {
@@ -389,10 +390,10 @@ public class Database implements StorageObject {
     return outValue;
   }
 
-  /*
-  *   select-Operator um einen Datensatz zu bekommen.
-  *   @param id Primaerschluessel des Datensatzes.
-  *   @return liefert EntityObject des gefundenen Datensatzes oder null.
+  /**
+   *   select-Operator um einen Datensatz zu bekommen.
+   *   @param id Primaerschluessel des Datensatzes.
+   *   @return liefert EntityObject des gefundenen Datensatzes oder null.
    */
   public Entity selectById(String id) throws StorageObjectExc {
     if ((id == null) || id.equals("")) {
@@ -463,6 +464,22 @@ public class Database implements StorageObject {
   }
 
   /**
+   * This method makes it possible to make selects across multiple tables
+   * 
+   * @param mainTablePrefix prefix for the mainTable
+   * @param extraTables a vector of tables for relational select
+   * @param aWhereClause whereClause
+   * @return EntityList of selected Objects
+   * @throws StorageObjectFailure
+   */
+
+  public EntityList selectByWhereClauseWithExtraTables(String mainTablePrefix, 
+                                               Vector extraTables, String aWhereClause )
+   throws StorageObjectFailure {
+       return selectByWhereClause( mainTablePrefix, extraTables, aWhereClause, "", 0, -1);
+  }
+
+  /**
    *   select-Operator um Datensaetze zu bekommen, die key = value erfuellen.
    *   @param key  Datenbankfeld der Bedingung.
    *   @param value  Wert die der key anehmen muss.
@@ -537,7 +554,7 @@ public class Database implements StorageObject {
   }
 
   /**
-   * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck.
+   * select-Operator returns EntityList with matching rows in Database.
    * @param aWhereClause where-Clause
    * @param anOrderByClause orderBy-Clause
    * @param offset ab welchem Datensatz
@@ -547,19 +564,41 @@ public class Database implements StorageObject {
    */
   public EntityList selectByWhereClause(String aWhereClause, String anOrderByClause,
             int offset, int limit) throws StorageObjectFailure {
+    return selectByWhereClause("", null, aWhereClause, anOrderByClause, offset, limit);              
+  }
 
+  /**
+   * select-Operator returns EntityList with matching rows in Database.
+   * @param aWhereClause where-Clause
+   * @param anOrderByClause orderBy-Clause
+   * @param offset ab welchem Datensatz
+   * @param limit wieviele Datens?tze
+   * @return EntityList mit den gematchten Entities
+   * @exception StorageObjectException
+   */
+  public EntityList selectByWhereClause(String mainTablePrefix, Vector extraTables,
+      String aWhereClause, String anOrderByClause,
+                       int offset, int limit) throws StorageObjectFailure {
+    
+    String useTable = theTable;
+    if (mainTablePrefix!=null && mainTablePrefix.trim().length()>0)
+    useTable+=" "+mainTablePrefix;
+    
     // check o_store for entitylist
-    if (StoreUtil.implementsStorableObject(theEntityClass)) {
-      StoreIdentifier search_sid =
-          new StoreIdentifier(
-            theEntityClass, StoreContainerType.STOC_TYPE_ENTITYLIST,
-            StoreUtil.getEntityListUniqueIdentifierFor(theTable, aWhereClause, anOrderByClause, offset, limit));
-      EntityList hit = (EntityList) o_store.use(search_sid);
-
-      if (hit != null) {
-        logger.debug("CACHE (hit): " + search_sid.toString());
-
-        return hit;
+    // only if no relational select
+    if (extraTables==null) {
+      if (StoreUtil.implementsStorableObject(theEntityClass)) {
+        StoreIdentifier search_sid =
+            new StoreIdentifier(
+              theEntityClass, StoreContainerType.STOC_TYPE_ENTITYLIST,
+              StoreUtil.getEntityListUniqueIdentifierFor(useTable, aWhereClause, anOrderByClause, offset, limit));
+        EntityList hit = (EntityList) o_store.use(search_sid);
+  
+        if (hit != null) {
+          logger.debug("CACHE (hit): " + search_sid.toString());
+  
+          return hit;
+        }
       }
     }
 
@@ -573,17 +612,23 @@ public class Database implements StorageObject {
 
     // build sql-statement
 
-    /** @todo count sql string should only be assembled if we really count
-     *  see below at the end of method //rk */
     if ((aWhereClause != null) && (aWhereClause.trim().length() == 0)) {
       aWhereClause = null;
     }
 
     StringBuffer countSql =
-      new StringBuffer("select count(*) from ").append(theTable);
+      new StringBuffer("select count(*) from ").append(useTable);
     StringBuffer selectSql =
-      new StringBuffer("select * from ").append(theTable);
-
+      new StringBuffer("select * from ").append(useTable);
+    // append extratables, if necessary
+    if (extraTables!=null) {
+      for (int i=0;i < extraTables.size();i++) {
+        countSql.append( ", " + extraTables.elementAt(i));
+        selectSql.append( ", " + extraTables.elementAt(i));
+      }
+    }
+    
     if (aWhereClause != null) {
       selectSql.append(" where ").append(aWhereClause);
       countSql.append(" where ").append(aWhereClause);
@@ -611,15 +656,12 @@ public class Database implements StorageObject {
         }
 
         theReturnList = new EntityList();
-
         Entity theResultEntity;
-
         while (rs.next()) {
           theResultEntity = makeEntityFromResultSet(rs);
           theReturnList.add(theResultEntity);
           offsetCount++;
         }
-
         rs.close();
       }
 
@@ -632,8 +674,6 @@ public class Database implements StorageObject {
 
         if ((limit > -1) && (offset > -1)) {
           if (offsetCount == limit) {
-            /** @todo counting should be deffered to entitylist
-             *  getSize() should be used */
             rs = executeSql(stmt, countSql.toString());
 
             if (rs != null) {
@@ -664,7 +704,7 @@ public class Database implements StorageObject {
           theReturnList.setNextBatch(offset + limit);
         }
 
-        if (StoreUtil.implementsStorableObject(theEntityClass)) {
+        if (extraTables==null && StoreUtil.implementsStorableObject(theEntityClass)) {
           StoreIdentifier sid = theReturnList.getStoreIdentifier();
           logger.debug("CACHE (add): " + sid.toString());
           o_store.add(sid);
index e5d0c7f..744e546 100755 (executable)
-/*\r
- * Copyright (C) 2001, 2002 The Mir-coders group\r
- *\r
- * This file is part of Mir.\r
- *\r
- * Mir is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * Mir is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with Mir; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * In addition, as a special exception, The Mir-coders gives permission to link\r
- * the code of this program with  any library licensed under the Apache Software License,\r
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
- * (or with modified versions of the above that use the same license as the above),\r
- * and distribute linked combinations including the two.  You must obey the\r
- * GNU General Public License in all respects for all of the code used other than\r
- * the above mentioned libraries.  If you modify this file, you may extend this\r
- * exception to your version of the file, but you are not obligated to do so.\r
- * If you do not wish to do so, delete this exception statement from your version.\r
- */\r
-package mircoders.localizer.basic;\r
-\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Vector;\r
-\r
-import mir.config.MirPropertiesConfiguration;\r
-import mir.entity.Entity;\r
-import mir.entity.adapter.EntityAdapter;\r
-import mir.entity.adapter.EntityAdapterDefinition;\r
-import mir.entity.adapter.EntityAdapterModel;\r
-import mir.log.LoggerWrapper;\r
-import mir.media.MediaHelper;\r
-import mir.media.MirMedia;\r
-import mir.util.ParameterExpander;\r
-import mir.util.RewindableIterator;\r
-import mir.util.StructuredContentParser;\r
-import mircoders.entity.EntityUploadedMedia;\r
-import mircoders.global.MirGlobal;\r
-import mircoders.localizer.MirAdminInterfaceLocalizer;\r
-import mircoders.localizer.MirDataModelLocalizer;\r
-import mircoders.localizer.MirLocalizerExc;\r
-import mircoders.localizer.MirLocalizerFailure;\r
-import mircoders.storage.DatabaseArticleType;\r
-import mircoders.storage.DatabaseAudio;\r
-import mircoders.storage.DatabaseBreaking;\r
-import mircoders.storage.DatabaseComment;\r
-import mircoders.storage.DatabaseCommentStatus;\r
-import mircoders.storage.DatabaseContent;\r
-import mircoders.storage.DatabaseContentToMedia;\r
-import mircoders.storage.DatabaseContentToTopics;\r
-import mircoders.storage.DatabaseImageType;\r
-import mircoders.storage.DatabaseImages;\r
-import mircoders.storage.DatabaseLanguage;\r
-import mircoders.storage.DatabaseMediaType;\r
-import mircoders.storage.DatabaseMediafolder;\r
-import mircoders.storage.DatabaseMessages;\r
-import mircoders.storage.DatabaseOther;\r
-import mircoders.storage.DatabaseTopics;\r
-import mircoders.storage.DatabaseUploadedMedia;\r
-import mircoders.storage.DatabaseUsers;\r
-import mircoders.storage.DatabaseVideo;\r
-\r
-public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {\r
-  protected LoggerWrapper logger;\r
-  protected MirPropertiesConfiguration configuration;\r
-\r
-  public MirBasicDataModelLocalizer() throws MirLocalizerFailure, MirLocalizerExc {\r
-    logger = new LoggerWrapper("Localizer.DataModel");\r
-\r
-    try {\r
-      configuration = MirPropertiesConfiguration.instance();\r
-    }\r
-    catch (Throwable e) {\r
-      throw new MirLocalizerFailure("Can't get configuration: " + e.getMessage(), e);\r
-    }\r
-  }\r
-\r
-  protected void constructContentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure, MirLocalizerExc {\r
-    try {\r
-      anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
-      anEntityAdapterDefinition.addDBDateField("changedate", "webdb_lastchange", configuration.getString("Mir.DefaultTimezone"));\r
-      anEntityAdapterDefinition.addMirDateField("date", "date", configuration.getString("Mir.DefaultTimezone"));\r
-      anEntityAdapterDefinition.addCalculatedField("to_topics", new ContentToTopicsField());\r
-      anEntityAdapterDefinition.addCalculatedField("to_comments", new ContentToCommentsField());\r
-      anEntityAdapterDefinition.addCalculatedField("language", new ContentToLanguageField());\r
-\r
-      anEntityAdapterDefinition.addCalculatedField("commentcount", new ContentCommentCountField(" and is_published='1'"));\r
-      anEntityAdapterDefinition.addCalculatedField("fullcommentcount", new ContentCommentCountField(""));\r
-\r
-      anEntityAdapterDefinition.addCalculatedField("to_uploaded_media", new ContentToMediaField( "uploadedMedia" ));\r
-      anEntityAdapterDefinition.addCalculatedField("to_media_images",  new ContentToMediaField( "image" ));\r
-      anEntityAdapterDefinition.addCalculatedField("to_media_audio", new ContentToMediaField( "audio" ));\r
-      anEntityAdapterDefinition.addCalculatedField("to_media_video", new ContentToMediaField( "video" ));\r
-      anEntityAdapterDefinition.addCalculatedField("to_media_other", new ContentToMediaField( "otherMedia" ));\r
-      anEntityAdapterDefinition.addCalculatedField("to_all_uploaded_media", new ContentToMediaField( "uploadedMedia", false));\r
-      anEntityAdapterDefinition.addCalculatedField("to_all_media_images",  new ContentToMediaField( "image", false));\r
-      anEntityAdapterDefinition.addCalculatedField("to_all_media_audio", new ContentToMediaField( "audio", false));\r
-      anEntityAdapterDefinition.addCalculatedField("to_all_media_video", new ContentToMediaField( "video", false));\r
-      anEntityAdapterDefinition.addCalculatedField("to_all_media_other", new ContentToMediaField( "otherMedia", false));\r
-      anEntityAdapterDefinition.addCalculatedField("to_media_icon", new ContentToIconField());\r
-\r
-      anEntityAdapterDefinition.addCalculatedField("article_type", new ContentToArticleTypeField());\r
-\r
-      anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));\r
-      anEntityAdapterDefinition.addCalculatedField("content_data_parsed", new FilteredField("content_data"));\r
-\r
-      anEntityAdapterDefinition.addCalculatedField("children", new ContentToChildrenField());\r
-      anEntityAdapterDefinition.addCalculatedField("parent", new ContentToParentField());\r
-\r
-      anEntityAdapterDefinition.addCalculatedField("publicurl", new ExpandedField(configuration.getString("Article.PublicUrl")));\r
-\r
-      anEntityAdapterDefinition.addCalculatedField("operations",\r
-          new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleArticleOperations()));\r
-    }\r
-    catch (Throwable t) {\r
-      throw new MirLocalizerFailure(t.getMessage(), t);\r
-    }\r
-  }\r
-\r
-  protected void constructCommentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure {\r
-    try {\r
-      anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
-      anEntityAdapterDefinition.addCalculatedField("to_content", new CommentToContentField());\r
-      anEntityAdapterDefinition.addCalculatedField("status", new CommentToStatusField());\r
-\r
-      anEntityAdapterDefinition.addCalculatedField("to_uploaded_media", new CommentToMediaField( "uploadedMedia" ));\r
-      anEntityAdapterDefinition.addCalculatedField("to_media_images",  new CommentToMediaField( "image" ));\r
-      anEntityAdapterDefinition.addCalculatedField("to_media_audio", new CommentToMediaField( "audio" ));\r
-      anEntityAdapterDefinition.addCalculatedField("to_media_video", new CommentToMediaField( "video" ));\r
-      anEntityAdapterDefinition.addCalculatedField("to_media_other", new CommentToMediaField( "otherMedia" ));\r
-      anEntityAdapterDefinition.addCalculatedField("to_all_uploaded_media", new CommentToMediaField( "uploadedMedia", false));\r
-      anEntityAdapterDefinition.addCalculatedField("to_all_media_images",  new CommentToMediaField( "image", false));\r
-      anEntityAdapterDefinition.addCalculatedField("to_all_media_audio", new CommentToMediaField( "audio", false));\r
-      anEntityAdapterDefinition.addCalculatedField("to_all_media_video", new CommentToMediaField( "video", false));\r
-      anEntityAdapterDefinition.addCalculatedField("to_all_media_other", new CommentToMediaField( "otherMedia", false));\r
-\r
-      anEntityAdapterDefinition.addCalculatedField("publicurl", new ExpandedField(configuration.getString("Comment.PublicUrl")));\r
-\r
-      anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));\r
-      anEntityAdapterDefinition.addCalculatedField("operations",\r
-          new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleCommentOperations()));\r
-    }\r
-    catch (Throwable t) {\r
-      throw new MirLocalizerFailure(t.getMessage(), t);\r
-    }\r
-  }\r
-\r
-  public EntityAdapterModel adapterModel() throws MirLocalizerFailure, MirLocalizerExc {\r
-    EntityAdapterModel result = new EntityAdapterModel();\r
-\r
-    try {\r
-      EntityAdapterDefinition definition;\r
-\r
-      definition = new EntityAdapterDefinition();\r
-      constructContentAdapterDefinition( definition );\r
-      result.addMapping( "content", DatabaseContent.getInstance(), definition);\r
-\r
-      definition = new EntityAdapterDefinition();\r
-      constructCommentAdapterDefinition( definition );\r
-      result.addMapping( "comment", DatabaseComment.getInstance(), definition);\r
-\r
-      result.addMapping( "articleType", DatabaseArticleType.getInstance(), new EntityAdapterDefinition());\r
-      result.addMapping( "commentStatus", DatabaseCommentStatus.getInstance(), new EntityAdapterDefinition());\r
-\r
-      definition = new EntityAdapterDefinition();\r
-      definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
-      result.addMapping( "breakingNews", DatabaseBreaking.getInstance(), definition);\r
-\r
-      definition = new EntityAdapterDefinition();\r
-      definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
-      result.addMapping( "internalMessage", DatabaseMessages.getInstance(), definition);\r
-\r
-      definition = new EntityAdapterDefinition();\r
-      definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());\r
-      result.addMapping( "uploadedMedia", DatabaseUploadedMedia.getInstance(), definition);\r
-      definition = new EntityAdapterDefinition();\r
-      definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());\r
-      result.addMapping( "image", DatabaseImages.getInstance(), definition);\r
-      definition = new EntityAdapterDefinition();\r
-      definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());\r
-      result.addMapping( "audio", DatabaseAudio.getInstance(), definition);\r
-      definition = new EntityAdapterDefinition();\r
-      definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());\r
-      result.addMapping( "video", DatabaseVideo.getInstance(), definition);\r
-      definition = new EntityAdapterDefinition();\r
-      definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());\r
-      result.addMapping( "otherMedia", DatabaseOther.getInstance(), definition);\r
-\r
-\r
-      result.addMapping( "mediaFolder", DatabaseMediafolder.getInstance(), new EntityAdapterDefinition());\r
-      result.addMapping( "imageType", DatabaseImageType.getInstance(), new EntityAdapterDefinition());\r
-      result.addMapping( "language", DatabaseLanguage.getInstance(), new EntityAdapterDefinition());\r
-      result.addMapping( "mediaType", DatabaseMediaType.getInstance(), new EntityAdapterDefinition());\r
-      result.addMapping( "topic", DatabaseTopics.getInstance(), new EntityAdapterDefinition());\r
-      result.addMapping( "user", DatabaseUsers.getInstance(), new EntityAdapterDefinition());\r
-      result.addMapping( "otherMedia", DatabaseOther.getInstance(), new EntityAdapterDefinition());\r
-\r
-      result.addMapping( "content_x_topic", DatabaseContentToTopics.getInstance(), new EntityAdapterDefinition());\r
-\r
-    }\r
-    catch (Throwable t) {\r
-      throw new MirLocalizerFailure(t.getMessage(), t);\r
-    }\r
-\r
-    return result;\r
-  }\r
-\r
-  protected class CommentToContentField implements EntityAdapterDefinition.CalculatedField {\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return anEntityAdapter.getToOneRelation(\r
-                    "id="+anEntityAdapter.get("to_media"),\r
-                    "id",\r
-                    "content" );\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class CommentToStatusField implements EntityAdapterDefinition.CalculatedField {\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return anEntityAdapter.getToOneRelation(\r
-                    "id="+anEntityAdapter.get("to_comment_status"),\r
-                    "id",\r
-                    "commentStatus" );\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class EntityToSimpleOperationsField implements EntityAdapterDefinition.CalculatedField {\r
-    private List operations;\r
-\r
-    public EntityToSimpleOperationsField(List anOperations) {\r
-      operations = anOperations;\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        Iterator i = operations.iterator();\r
-        List availableOperations = new Vector();\r
-\r
-        while (i.hasNext()) {\r
-          MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =\r
-            (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();\r
-\r
-          if (operation.isAvailable(anEntityAdapter)) {\r
-            availableOperations.add(operation.getName());\r
-          }\r
-        };\r
-\r
-        return availableOperations;\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class FilteredField implements EntityAdapterDefinition.CalculatedField {\r
-    private String fieldName;\r
-\r
-    public FilteredField(String aFieldName) {\r
-      fieldName = aFieldName;\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        if (anEntityAdapter.get("is_html")!=null && anEntityAdapter.get("is_html").equals("1")) {\r
-          return MirGlobal.localizer().producerAssistant().filterHTMLText((String) anEntityAdapter.get(fieldName));\r
-        }\r
-        else {\r
-          return MirGlobal.localizer().producerAssistant().filterNonHTMLText((String) anEntityAdapter.get(fieldName));\r
-        }\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class StructuredContentField implements EntityAdapterDefinition.CalculatedField {\r
-    private String expression;\r
-\r
-    public StructuredContentField(String anExpression) {\r
-      expression = anExpression;\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return StructuredContentParser.parse(ParameterExpander.evaluateStringExpression(anEntityAdapter, expression));\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class ExpandedField implements EntityAdapterDefinition.CalculatedField {\r
-    private String expression;\r
-\r
-    public ExpandedField(String anExpression) {\r
-      expression = anExpression;\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return ParameterExpander.expandExpression(anEntityAdapter, expression);\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class EvaluatedField implements EntityAdapterDefinition.CalculatedField {\r
-    private String expression;\r
-\r
-    public EvaluatedField(String anExpression) {\r
-      expression = anExpression;\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return ParameterExpander.evaluateExpression(anEntityAdapter, expression);\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class ContentToParentField implements EntityAdapterDefinition.CalculatedField {\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        logger.debug("ContentToParentField.getValue");\r
-        return anEntityAdapter.getToOneRelation(\r
-                    "id="+anEntityAdapter.get("to_content"),\r
-                    "id",\r
-                    "content" );\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class ContentToChildrenField implements EntityAdapterDefinition.CalculatedField {\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return anEntityAdapter.getRelation(\r
-                    "to_content="+anEntityAdapter.get("id"),\r
-                    "id",\r
-                    "content" );\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class ContentToLanguageField implements EntityAdapterDefinition.CalculatedField {\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return anEntityAdapter.getToOneRelation(\r
-                    "id="+anEntityAdapter.get("to_language"),\r
-                    "id",\r
-                    "language" );\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class ContentToArticleTypeField implements EntityAdapterDefinition.CalculatedField {\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return anEntityAdapter.getToOneRelation(\r
-                    "id="+anEntityAdapter.get("to_article_type"),\r
-                    "id",\r
-                    "articleType" );\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class MediaToMediaFolderField implements EntityAdapterDefinition.CalculatedField {\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return anEntityAdapter.getToOneRelation(\r
-                    "id="+anEntityAdapter.get("to_media_folder"),\r
-                    "id",\r
-                    "mediaFolder" );\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class ContentToCommentsField implements EntityAdapterDefinition.CalculatedField {\r
-    private String extracondition;\r
-    private String order;\r
-\r
-    public ContentToCommentsField() {\r
-      this ( " and is_published='1'", "webdb_create");\r
-    }\r
-\r
-    public ContentToCommentsField(String anExtraCondition, String anOrder) {\r
-      order = anOrder;\r
-      extracondition = anExtraCondition;\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return anEntityAdapter.getRelation(\r
-                    "to_media="+anEntityAdapter.get("id")+" " + extracondition,\r
-                    order,\r
-                    "comment" );\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class ContentToTopicsField implements EntityAdapterDefinition.CalculatedField {\r
-    private String topicCondition;\r
-    private String topicOrder;\r
-\r
-    public ContentToTopicsField() {\r
-      this(null);\r
-    }\r
-\r
-    public ContentToTopicsField(String aTopicCondition) {\r
-      this(aTopicCondition, "title");\r
-    }\r
-\r
-    public ContentToTopicsField(String aTopicCondition, String aTopicOrder) {\r
-      topicCondition = aTopicCondition;\r
-      topicOrder = aTopicOrder;\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        String condition = "exists (select * from content_x_topic where content_id="+anEntityAdapter.get("id")+" and topic_id=id)";\r
-        if (topicCondition!=null && topicCondition.length()>0)\r
-          condition = "(" + topicCondition + ") and " + condition;\r
-\r
-        return anEntityAdapter.getRelation(\r
-                    condition,\r
-                    topicOrder,\r
-                    "topic" );\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class ContentToMediaField implements EntityAdapterDefinition.CalculatedField {\r
-    private String definition;\r
-    private boolean published;\r
-\r
-    public ContentToMediaField(String aDefinition, boolean anOnlyPublished) {\r
-      definition = aDefinition;\r
-      published = anOnlyPublished;\r
-    }\r
-\r
-    public ContentToMediaField(String aDefinition) {\r
-      this(aDefinition, true);\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        String condition = "exists (select * from content_x_media where content_id="+anEntityAdapter.get("id")+" and media_id=id)";\r
-        if (published)\r
-          condition = "is_published='t' and " + condition;\r
-        return anEntityAdapter.getRelation(\r
-           condition,\r
-          "id",\r
-          definition);\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class CommentToMediaField implements EntityAdapterDefinition.CalculatedField {\r
-    private String definition;\r
-    private boolean published;\r
-\r
-    public CommentToMediaField(String aDefinition, boolean anOnlyPublished) {\r
-      definition = aDefinition;\r
-      published = anOnlyPublished;\r
-    }\r
-\r
-    public CommentToMediaField(String aDefinition) {\r
-      this(aDefinition, true);\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        String condition = "exists (select * from comment_x_media where comment_id="+anEntityAdapter.get("id")+" and media_id=id)";\r
-        if (published)\r
-          condition = "is_published='t' and " + condition;\r
-        return anEntityAdapter.getRelation(\r
-           condition,\r
-          "id",\r
-          definition);\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class ContentToIconField implements EntityAdapterDefinition.CalculatedField {\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      EntityAdapter media;\r
-      Entity mediaType;\r
-      RewindableIterator iterator;\r
-      Map result;\r
-      MirMedia mediaHandler;\r
-      String tinyIcon;\r
-      String iconAlt;\r
-\r
-      try {\r
-        iterator = (RewindableIterator) (anEntityAdapter.get("to_uploaded_media"));\r
-        iterator.rewind();\r
-\r
-        tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyText");\r
-        iconAlt = "Text";\r
-\r
-        if (iterator.hasNext()) {\r
-          media = (EntityAdapter) iterator.next();\r
-\r
-          mediaType = ((EntityUploadedMedia) (media.getEntity())).getMediaType();\r
-          mediaHandler = MediaHelper.getHandler( mediaType );\r
-\r
-          if (mediaHandler.isVideo()) {\r
-            tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyVideo");\r
-            iconAlt = "Video";\r
-          }\r
-          else if (mediaHandler.isAudio()) {\r
-            tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyAudio");\r
-            iconAlt = "Audio";\r
-          }\r
-          else if (mediaHandler.isImage()) {\r
-            tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyImage");\r
-            iconAlt = "Image";\r
-          }\r
-          else {\r
-            tinyIcon = mediaHandler.getTinyIconName();\r
-            iconAlt = mediaHandler.getIconAltName();\r
-          }\r
-\r
-        }\r
-      }\r
-      catch (Throwable t) {\r
-        logger.error("ContentToIconField: " +t.getMessage());\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-\r
-      result = new HashMap();\r
-      result.put("tiny_icon", MirGlobal.config().getString("Producer.ImageRoot") + "/" + tinyIcon);\r
-      result.put("icon_alt", iconAlt);\r
-\r
-      return result;\r
-    }\r
-  }\r
-\r
-  protected class ContentCommentCountField implements EntityAdapterDefinition.CalculatedField {\r
-    private String extraCondition;\r
-\r
-    public ContentCommentCountField(String anExtraCondition) {\r
-      super();\r
-\r
-      extraCondition = anExtraCondition;\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        return Integer.toString(\r
-            DatabaseComment.getInstance().getSize(\r
-                  "to_media="+anEntityAdapter.get("id")+" " + extraCondition));\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-\r
-  protected class ContentMediaCountField implements EntityAdapterDefinition.CalculatedField {\r
-    private String table;\r
-    private boolean published;\r
-\r
-    public ContentMediaCountField(String aTable, boolean anOnlyPublished) {\r
-      table = aTable;\r
-      published = anOnlyPublished;\r
-    }\r
-\r
-    public ContentMediaCountField(String aTable) {\r
-      this(aTable, true);\r
-    }\r
-\r
-    public Object getValue(EntityAdapter anEntityAdapter) {\r
-      try {\r
-        String subQuery = "select * from "+table+" where id = media_id";\r
-        if (published)\r
-          subQuery = subQuery + " and is_published='t'";\r
-\r
-        return Integer.toString(\r
-            DatabaseContentToMedia.getInstance().getSize(\r
-                  "exists ("+subQuery+")"));\r
-      }\r
-      catch (Throwable t) {\r
-        throw new RuntimeException(t.getMessage());\r
-      }\r
-    }\r
-  }\r
-}\r
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mircoders.localizer.basic;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import mir.config.MirPropertiesConfiguration;
+import mir.entity.Entity;
+import mir.entity.adapter.EntityAdapter;
+import mir.entity.adapter.EntityAdapterDefinition;
+import mir.entity.adapter.EntityAdapterModel;
+import mir.log.LoggerWrapper;
+import mir.media.MediaHelper;
+import mir.media.MirMedia;
+import mir.util.ParameterExpander;
+import mir.util.RewindableIterator;
+import mir.util.StructuredContentParser;
+import mircoders.entity.EntityUploadedMedia;
+import mircoders.global.MirGlobal;
+import mircoders.localizer.MirAdminInterfaceLocalizer;
+import mircoders.localizer.MirDataModelLocalizer;
+import mircoders.localizer.MirLocalizerExc;
+import mircoders.localizer.MirLocalizerFailure;
+import mircoders.storage.DatabaseArticleType;
+import mircoders.storage.DatabaseAudio;
+import mircoders.storage.DatabaseBreaking;
+import mircoders.storage.DatabaseComment;
+import mircoders.storage.DatabaseCommentStatus;
+import mircoders.storage.DatabaseContent;
+import mircoders.storage.DatabaseContentToMedia;
+import mircoders.storage.DatabaseContentToTopics;
+import mircoders.storage.DatabaseImageType;
+import mircoders.storage.DatabaseImages;
+import mircoders.storage.DatabaseLanguage;
+import mircoders.storage.DatabaseMediaType;
+import mircoders.storage.DatabaseMediafolder;
+import mircoders.storage.DatabaseMessages;
+import mircoders.storage.DatabaseOther;
+import mircoders.storage.DatabaseTopics;
+import mircoders.storage.DatabaseUploadedMedia;
+import mircoders.storage.DatabaseUsers;
+import mircoders.storage.DatabaseVideo;
+
+public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {
+  protected LoggerWrapper logger;
+  protected MirPropertiesConfiguration configuration;
+
+  public MirBasicDataModelLocalizer() throws MirLocalizerFailure, MirLocalizerExc {
+    logger = new LoggerWrapper("Localizer.DataModel");
+
+    try {
+      configuration = MirPropertiesConfiguration.instance();
+    }
+    catch (Throwable e) {
+      throw new MirLocalizerFailure("Can't get configuration: " + e.getMessage(), e);
+    }
+  }
+
+  protected void constructContentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure, MirLocalizerExc {
+    try {
+      anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));
+      anEntityAdapterDefinition.addDBDateField("changedate", "webdb_lastchange", configuration.getString("Mir.DefaultTimezone"));
+      anEntityAdapterDefinition.addMirDateField("date", "date", configuration.getString("Mir.DefaultTimezone"));
+      anEntityAdapterDefinition.addCalculatedField("to_topics", new ContentToTopicsField());
+      anEntityAdapterDefinition.addCalculatedField("to_comments", new ContentToCommentsField());
+      anEntityAdapterDefinition.addCalculatedField("language", new ContentToLanguageField());
+
+      anEntityAdapterDefinition.addCalculatedField("commentcount", new ContentCommentCountField(" and is_published='1'"));
+      anEntityAdapterDefinition.addCalculatedField("fullcommentcount", new ContentCommentCountField(""));
+
+      anEntityAdapterDefinition.addCalculatedField("to_uploaded_media", new ContentToMediaField( "uploadedMedia" ));
+      anEntityAdapterDefinition.addCalculatedField("to_media_images",  new ContentToMediaField( "image" ));
+      anEntityAdapterDefinition.addCalculatedField("to_media_audio", new ContentToMediaField( "audio" ));
+      anEntityAdapterDefinition.addCalculatedField("to_media_video", new ContentToMediaField( "video" ));
+      anEntityAdapterDefinition.addCalculatedField("to_media_other", new ContentToMediaField( "otherMedia" ));
+      anEntityAdapterDefinition.addCalculatedField("to_all_uploaded_media", new ContentToMediaField( "uploadedMedia", false));
+      anEntityAdapterDefinition.addCalculatedField("to_all_media_images",  new ContentToMediaField( "image", false));
+      anEntityAdapterDefinition.addCalculatedField("to_all_media_audio", new ContentToMediaField( "audio", false));
+      anEntityAdapterDefinition.addCalculatedField("to_all_media_video", new ContentToMediaField( "video", false));
+      anEntityAdapterDefinition.addCalculatedField("to_all_media_other", new ContentToMediaField( "otherMedia", false));
+      anEntityAdapterDefinition.addCalculatedField("to_media_icon", new ContentToIconField());
+
+      anEntityAdapterDefinition.addCalculatedField("article_type", new ContentToArticleTypeField());
+
+      anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));
+      anEntityAdapterDefinition.addCalculatedField("content_data_parsed", new FilteredField("content_data"));
+
+      anEntityAdapterDefinition.addCalculatedField("children", new ContentToChildrenField());
+      anEntityAdapterDefinition.addCalculatedField("parent", new ContentToParentField());
+
+      anEntityAdapterDefinition.addCalculatedField("publicurl", new ExpandedField(configuration.getString("Article.PublicUrl")));
+
+      anEntityAdapterDefinition.addCalculatedField("operations",
+          new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleArticleOperations()));
+    }
+    catch (Throwable t) {
+      throw new MirLocalizerFailure(t.getMessage(), t);
+    }
+  }
+
+  protected void constructCommentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure {
+    try {
+      anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));
+      anEntityAdapterDefinition.addCalculatedField("to_content", new CommentToContentField());
+      anEntityAdapterDefinition.addCalculatedField("status", new CommentToStatusField());
+
+      anEntityAdapterDefinition.addCalculatedField("to_uploaded_media", new CommentToMediaField( "uploadedMedia" ));
+      anEntityAdapterDefinition.addCalculatedField("to_media_images",  new CommentToMediaField( "image" ));
+      anEntityAdapterDefinition.addCalculatedField("to_media_audio", new CommentToMediaField( "audio" ));
+      anEntityAdapterDefinition.addCalculatedField("to_media_video", new CommentToMediaField( "video" ));
+      anEntityAdapterDefinition.addCalculatedField("to_media_other", new CommentToMediaField( "otherMedia" ));
+      anEntityAdapterDefinition.addCalculatedField("to_all_uploaded_media", new CommentToMediaField( "uploadedMedia", false));
+      anEntityAdapterDefinition.addCalculatedField("to_all_media_images",  new CommentToMediaField( "image", false));
+      anEntityAdapterDefinition.addCalculatedField("to_all_media_audio", new CommentToMediaField( "audio", false));
+      anEntityAdapterDefinition.addCalculatedField("to_all_media_video", new CommentToMediaField( "video", false));
+      anEntityAdapterDefinition.addCalculatedField("to_all_media_other", new CommentToMediaField( "otherMedia", false));
+
+      anEntityAdapterDefinition.addCalculatedField("publicurl", new ExpandedField(configuration.getString("Comment.PublicUrl")));
+
+      anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));
+      anEntityAdapterDefinition.addCalculatedField("operations",
+          new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleCommentOperations()));
+    }
+    catch (Throwable t) {
+      throw new MirLocalizerFailure(t.getMessage(), t);
+    }
+  }
+
+  public EntityAdapterModel adapterModel() throws MirLocalizerFailure, MirLocalizerExc {
+    EntityAdapterModel result = new EntityAdapterModel();
+
+    try {
+      EntityAdapterDefinition definition;
+
+      definition = new EntityAdapterDefinition();
+      constructContentAdapterDefinition( definition );
+      result.addMapping( "content", DatabaseContent.getInstance(), definition);
+
+      definition = new EntityAdapterDefinition();
+      constructCommentAdapterDefinition( definition );
+      result.addMapping( "comment", DatabaseComment.getInstance(), definition);
+
+      result.addMapping( "articleType", DatabaseArticleType.getInstance(), new EntityAdapterDefinition());
+      result.addMapping( "commentStatus", DatabaseCommentStatus.getInstance(), new EntityAdapterDefinition());
+
+      definition = new EntityAdapterDefinition();
+      definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));
+      result.addMapping( "breakingNews", DatabaseBreaking.getInstance(), definition);
+
+      definition = new EntityAdapterDefinition();
+      definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));
+      result.addMapping( "internalMessage", DatabaseMessages.getInstance(), definition);
+
+      definition = new EntityAdapterDefinition();
+      definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());
+      result.addMapping( "uploadedMedia", DatabaseUploadedMedia.getInstance(), definition);
+      definition = new EntityAdapterDefinition();
+      definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());
+      result.addMapping( "image", DatabaseImages.getInstance(), definition);
+      definition = new EntityAdapterDefinition();
+      definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());
+      result.addMapping( "audio", DatabaseAudio.getInstance(), definition);
+      definition = new EntityAdapterDefinition();
+      definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());
+      result.addMapping( "video", DatabaseVideo.getInstance(), definition);
+      definition = new EntityAdapterDefinition();
+      definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());
+      result.addMapping( "otherMedia", DatabaseOther.getInstance(), definition);
+
+
+      result.addMapping( "mediaFolder", DatabaseMediafolder.getInstance(), new EntityAdapterDefinition());
+      result.addMapping( "imageType", DatabaseImageType.getInstance(), new EntityAdapterDefinition());
+      result.addMapping( "language", DatabaseLanguage.getInstance(), new EntityAdapterDefinition());
+      result.addMapping( "mediaType", DatabaseMediaType.getInstance(), new EntityAdapterDefinition());
+      result.addMapping( "topic", DatabaseTopics.getInstance(), new EntityAdapterDefinition());
+      result.addMapping( "user", DatabaseUsers.getInstance(), new EntityAdapterDefinition());
+      result.addMapping( "otherMedia", DatabaseOther.getInstance(), new EntityAdapterDefinition());
+
+      result.addMapping( "content_x_topic", DatabaseContentToTopics.getInstance(), new EntityAdapterDefinition());
+
+    }
+    catch (Throwable t) {
+      throw new MirLocalizerFailure(t.getMessage(), t);
+    }
+
+    return result;
+  }
+
+  protected class CommentToContentField implements EntityAdapterDefinition.CalculatedField {
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return anEntityAdapter.getToOneRelation(
+                    "id="+anEntityAdapter.get("to_media"),
+                    "id",
+                    "content" );
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class CommentToStatusField implements EntityAdapterDefinition.CalculatedField {
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return anEntityAdapter.getToOneRelation(
+                    "id="+anEntityAdapter.get("to_comment_status"),
+                    "id",
+                    "commentStatus" );
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class EntityToSimpleOperationsField implements EntityAdapterDefinition.CalculatedField {
+    private List operations;
+
+    public EntityToSimpleOperationsField(List anOperations) {
+      operations = anOperations;
+    }
+
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        Iterator i = operations.iterator();
+        List availableOperations = new Vector();
+
+        while (i.hasNext()) {
+          MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =
+            (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();
+
+          if (operation.isAvailable(anEntityAdapter)) {
+            availableOperations.add(operation.getName());
+          }
+        };
+
+        return availableOperations;
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class FilteredField implements EntityAdapterDefinition.CalculatedField {
+    private String fieldName;
+
+    public FilteredField(String aFieldName) {
+      fieldName = aFieldName;
+    }
+
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        if (anEntityAdapter.get("is_html")!=null && anEntityAdapter.get("is_html").equals("1")) {
+          return MirGlobal.localizer().producerAssistant().filterHTMLText((String) anEntityAdapter.get(fieldName));
+        }
+        else {
+          return MirGlobal.localizer().producerAssistant().filterNonHTMLText((String) anEntityAdapter.get(fieldName));
+        }
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class StructuredContentField implements EntityAdapterDefinition.CalculatedField {
+    private String expression;
+
+    public StructuredContentField(String anExpression) {
+      expression = anExpression;
+    }
+
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return StructuredContentParser.parse(ParameterExpander.evaluateStringExpression(anEntityAdapter, expression));
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class ExpandedField implements EntityAdapterDefinition.CalculatedField {
+    private String expression;
+
+    public ExpandedField(String anExpression) {
+      expression = anExpression;
+    }
+
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return ParameterExpander.expandExpression(anEntityAdapter, expression);
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class EvaluatedField implements EntityAdapterDefinition.CalculatedField {
+    private String expression;
+
+    public EvaluatedField(String anExpression) {
+      expression = anExpression;
+    }
+
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return ParameterExpander.evaluateExpression(anEntityAdapter, expression);
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class ContentToParentField implements EntityAdapterDefinition.CalculatedField {
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        logger.debug("ContentToParentField.getValue");
+        return anEntityAdapter.getToOneRelation(
+                    "id="+anEntityAdapter.get("to_content"),
+                    "id",
+                    "content" );
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class ContentToChildrenField implements EntityAdapterDefinition.CalculatedField {
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return anEntityAdapter.getRelation(
+                    "to_content="+anEntityAdapter.get("id"),
+                    "id",
+                    "content" );
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class ContentToLanguageField implements EntityAdapterDefinition.CalculatedField {
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return anEntityAdapter.getToOneRelation(
+                    "id="+anEntityAdapter.get("to_language"),
+                    "id",
+                    "language" );
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class ContentToArticleTypeField implements EntityAdapterDefinition.CalculatedField {
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return anEntityAdapter.getToOneRelation(
+                    "id="+anEntityAdapter.get("to_article_type"),
+                    "id",
+                    "articleType" );
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class MediaToMediaFolderField implements EntityAdapterDefinition.CalculatedField {
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return anEntityAdapter.getToOneRelation(
+                    "id="+anEntityAdapter.get("to_media_folder"),
+                    "id",
+                    "mediaFolder" );
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class ContentToCommentsField implements EntityAdapterDefinition.CalculatedField {
+    private String extracondition;
+    private String order;
+
+    public ContentToCommentsField() {
+      this ( " and is_published='1'", "webdb_create");
+    }
+
+    public ContentToCommentsField(String anExtraCondition, String anOrder) {
+      order = anOrder;
+      extracondition = anExtraCondition;
+    }
+
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return anEntityAdapter.getRelation(
+                    "to_media="+anEntityAdapter.get("id")+" " + extracondition,
+                    order,
+                    "comment" );
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class ContentToTopicsField implements EntityAdapterDefinition.CalculatedField {
+    private String topicCondition;
+    private String topicOrder;
+
+    public ContentToTopicsField() {
+      this(null);
+    }
+
+    public ContentToTopicsField(String aTopicCondition) {
+      this(aTopicCondition, "title");
+    }
+
+    public ContentToTopicsField(String aTopicCondition, String aTopicOrder) {
+      topicCondition = aTopicCondition;
+      topicOrder = aTopicOrder;
+    }
+
+       // TODO rewrite as relational select
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        String condition = "exists (select * from content_x_topic where content_id="+anEntityAdapter.get("id")+" and topic_id=id)";
+        if (topicCondition!=null && topicCondition.length()>0)
+          condition = "(" + topicCondition + ") and " + condition;
+
+        return anEntityAdapter.getRelation(
+                    condition,
+                    topicOrder,
+                    "topic" );
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class ContentToMediaField implements EntityAdapterDefinition.CalculatedField {
+    private String definition;
+    private boolean published;
+
+    public ContentToMediaField(String aDefinition, boolean anOnlyPublished) {
+      definition = aDefinition;
+      published = anOnlyPublished;
+    }
+
+    public ContentToMediaField(String aDefinition) {
+      this(aDefinition, true);
+    }
+
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+               // TODO rewrite as relational select
+        String condition = "exists (select * from content_x_media where content_id="+anEntityAdapter.get("id")+" and media_id=id)";
+        if (published)
+          condition = "is_published='t' and " + condition;
+        return anEntityAdapter.getRelation(
+           condition,
+          "id",
+          definition);
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class CommentToMediaField implements EntityAdapterDefinition.CalculatedField {
+    private String definition;
+    private boolean published;
+
+    public CommentToMediaField(String aDefinition, boolean anOnlyPublished) {
+      definition = aDefinition;
+      published = anOnlyPublished;
+    }
+
+    public CommentToMediaField(String aDefinition) {
+      this(aDefinition, true);
+    }
+
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+               // TODO rewrite as relational select
+        String condition = "exists (select * from comment_x_media where comment_id="+anEntityAdapter.get("id")+" and media_id=id)";
+        if (published)
+          condition = "is_published='t' and " + condition;
+        return anEntityAdapter.getRelation(
+           condition,
+          "id",
+          definition);
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class ContentToIconField implements EntityAdapterDefinition.CalculatedField {
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      EntityAdapter media;
+      Entity mediaType;
+      RewindableIterator iterator;
+      Map result;
+      MirMedia mediaHandler;
+      String tinyIcon;
+      String iconAlt;
+
+      try {
+        iterator = (RewindableIterator) (anEntityAdapter.get("to_uploaded_media"));
+        iterator.rewind();
+
+        tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyText");
+        iconAlt = "Text";
+
+        if (iterator.hasNext()) {
+          media = (EntityAdapter) iterator.next();
+
+          mediaType = ((EntityUploadedMedia) (media.getEntity())).getMediaType();
+          mediaHandler = MediaHelper.getHandler( mediaType );
+
+          if (mediaHandler.isVideo()) {
+            tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyVideo");
+            iconAlt = "Video";
+          }
+          else if (mediaHandler.isAudio()) {
+            tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyAudio");
+            iconAlt = "Audio";
+          }
+          else if (mediaHandler.isImage()) {
+            tinyIcon = MirGlobal.config().getString("Producer.Icon.TinyImage");
+            iconAlt = "Image";
+          }
+          else {
+            tinyIcon = mediaHandler.getTinyIconName();
+            iconAlt = mediaHandler.getIconAltName();
+          }
+
+        }
+      }
+      catch (Throwable t) {
+        logger.error("ContentToIconField: " +t.getMessage());
+        throw new RuntimeException(t.getMessage());
+      }
+
+      result = new HashMap();
+      result.put("tiny_icon", MirGlobal.config().getString("Producer.ImageRoot") + "/" + tinyIcon);
+      result.put("icon_alt", iconAlt);
+
+      return result;
+    }
+  }
+
+  protected class ContentCommentCountField implements EntityAdapterDefinition.CalculatedField {
+    private String extraCondition;
+
+    public ContentCommentCountField(String anExtraCondition) {
+      super();
+
+      extraCondition = anExtraCondition;
+    }
+
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        return Integer.toString(
+            DatabaseComment.getInstance().getSize(
+                  "to_media="+anEntityAdapter.get("id")+" " + extraCondition));
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+
+  protected class ContentMediaCountField implements EntityAdapterDefinition.CalculatedField {
+    private String table;
+    private boolean published;
+
+    public ContentMediaCountField(String aTable, boolean anOnlyPublished) {
+      table = aTable;
+      published = anOnlyPublished;
+    }
+
+    public ContentMediaCountField(String aTable) {
+      this(aTable, true);
+    }
+
+    public Object getValue(EntityAdapter anEntityAdapter) {
+      try {
+        String subQuery = "select * from "+table+" where id = media_id";
+        if (published)
+          subQuery = subQuery + " and is_published='t'";
+
+        return Integer.toString(
+            DatabaseContentToMedia.getInstance().getSize(
+                  "exists ("+subQuery+")"));
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+  }
+}
index 4a696e4..0695ac7 100755 (executable)
 
 package mircoders.storage;
 
-import java.sql.Connection;\r
-import java.sql.ResultSet;\r
-import java.sql.Statement;\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Vector;\r
-\r
-import mir.entity.EntityList;\r
-import mir.log.LoggerWrapper;\r
-import mir.storage.Database;\r
-import mir.storage.StorageObject;\r
-import mir.storage.StorageObjectFailure;\r
-import mircoders.entity.EntityContent;\r
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import mir.entity.EntityList;
+import mir.log.LoggerWrapper;
+import mir.storage.Database;
+import mir.storage.StorageObject;
+import mir.storage.StorageObjectFailure;
+import mircoders.entity.EntityContent;
 import mircoders.entity.EntityTopics;
 
 /**
@@ -83,11 +83,20 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
     EntityList returnList=null;
     if (content != null) {
       // get all to_topic from content_x_topic
+      // TODO rewrite with getByWhereClauseWithExtraTables
+      // select t.* from topics t, content_x_topic cxt where t.id=cxt.topic_id
+      // and cxt.content_id=<id>
+      
       String id = content.getId();
-      String subselect = "id in (select topic_id from " + theTable + " where content_id=" + id+")";
+      //String subselect = "id in (select topic_id from " + theTable + " where content_id=" + id+")";
 
       try {
-        returnList = DatabaseTopics.getInstance().selectByWhereClause(subselect,-1);
+        Vector extraTables = new Vector();
+        extraTables.add(theTable+" cxt");
+        returnList = DatabaseTopics.getInstance()
+                      .selectByWhereClauseWithExtraTables("t",extraTables, 
+                                              "t.id=cxt.topic_id and  cxt.content_id="+id );
+        // .selectByWhereClause(subselect,-1);
       }
       catch (Exception e) {
         logger.error("-- get topics failed " + e.toString());
@@ -169,7 +178,7 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
     logger.debug("to add = " + topicsToAdd.toString());
 
 
-    if (!topicsToDelete.isEmpty()) {
+    if (!topicsToDelete.isEmpty()) {      
       String sql =
           "delete from " + theTable + " " +
           "where content_id=" + anArticleId +
@@ -272,6 +281,9 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
     throws StorageObjectFailure {
     EntityList returnList=null;
     if (topic != null) {
+      // TODO rewrite with getByWhereClauseWithExtraTables 
+      // 
+      
       String id = topic.getId();
       String select = "select content_id from " + theTable + " where topic_id=" + id;
 
@@ -296,7 +308,7 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
         }
       }
       catch (Exception e) {
-        logger.error("-- get contetn failed");
+        logger.error("-- get content failed");
       }
       finally { freeConnection(con,stmt);}
     }