per request from an .nl editor I've made a commentlist per article. This is
authorzapata <zapata>
Mon, 19 Aug 2002 04:20:04 +0000 (04:20 +0000)
committerzapata <zapata>
Mon, 19 Aug 2002 04:20:04 +0000 (04:20 +0000)
also a proof of concept test of an idea of mine...

14 files changed:
source/mir/generator/FreemarkerGenerator.java
source/mir/generator/Generator.java
source/mir/producer/ResourceBundleProducerNode.java
source/mir/util/GeneratorHTMLFunctions.java [new file with mode: 0755]
source/mir/util/ResourceBundleGeneratorFunction.java [new file with mode: 0755]
source/mircoders/localizer/MirAdminInterfaceLocalizer.java [new file with mode: 0755]
source/mircoders/localizer/MirCachingLocalizerDecorator.java
source/mircoders/localizer/MirLocalizer.java
source/mircoders/localizer/basic/MirBasicAdminInterfaceLocalizer.java [new file with mode: 0755]
source/mircoders/localizer/basic/MirBasicDataModelLocalizer.java
source/mircoders/localizer/basic/MirBasicLocalizer.java
source/mircoders/localizer/basic/MirBasicProducerAssistantLocalizer.java
source/mircoders/servlet/ServletModuleComment.java
source/mircoders/servlet/ServletModuleLocalizer.java [new file with mode: 0755]

index bcb4020..e92bd74 100755 (executable)
@@ -41,13 +41,21 @@ public class FreemarkerGenerator implements Generator {
     return new IteratorAdapter(anIterator);
   }
 
+  private static TemplateMethodModel makeFunctionAdapter(Generator.GeneratorFunction aFunction) {
+    return new FunctionAdapter(aFunction);
+  }
+
   private static TemplateModel makeAdapter(Object anObject) throws TemplateModelException {
     if (anObject == null)
       return null;
     if (anObject instanceof TemplateModel)
       return (TemplateModel) anObject;
+    else if (anObject instanceof Generator.GeneratorFunction)
+      return makeFunctionAdapter((Generator.GeneratorFunction) anObject);
     else if (anObject instanceof MessageResources)
       return new MessageMethodModel((MessageResources) anObject);
+    else if (anObject instanceof Integer)
+      return makeStringAdapter(((Integer) anObject).toString());
     else if (anObject instanceof String)
       return makeStringAdapter((String) anObject);
     else if (anObject instanceof Map)
@@ -162,7 +170,7 @@ public class FreemarkerGenerator implements Generator {
         position++;
       }
       else
-              throw new TemplateModelException( "Iterator out of bounds" );
+        throw new TemplateModelException( "Iterator out of bounds" );
 
       return result;
     }
@@ -228,6 +236,28 @@ public class FreemarkerGenerator implements Generator {
     }
   }
 
+  private static class FunctionAdapter implements TemplateMethodModel {
+    Generator.GeneratorFunction function;
+
+    public FunctionAdapter(Generator.GeneratorFunction aFunction) {
+      function = aFunction;
+    }
+
+    public TemplateModel exec(List anArguments) throws TemplateModelException {
+      try {
+        return makeAdapter(function.perform(anArguments));
+      }
+      catch (Throwable t) {
+        throw new TemplateModelException(t.getMessage());
+      }
+    }
+
+    public boolean isEmpty() {
+      return false;
+    }
+
+  }
+
   public static class FreemarkerGeneratorLibrary implements GeneratorLibrary {
     private FileTemplateCache  templateCache;
 
index 9a546d7..64abdef 100755 (executable)
@@ -9,4 +9,8 @@ public interface Generator {
   public static interface GeneratorLibrary {
     public Generator makeGenerator(String anIdentifier) throws GeneratorExc, GeneratorFailure;
   }
+
+  public static interface GeneratorFunction {
+    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure;
+  }
 }
index 37a9655..730d62a 100755 (executable)
@@ -29,7 +29,7 @@ public class ResourceBundleProducerNode extends ProducerNodeDecorator {
     try {
       if (languageIdentifier!=null) {
         messages =
-            new MessageMethodModel(
+            new ResourceBundleGeneratorFunction(
                 new Locale(ParameterExpander.expandExpression( aValueMap, languageIdentifier ), null ),
                 MessageResources.getMessageResources(ParameterExpander.expandExpression( aValueMap, bundleIdentifier ))
             );
diff --git a/source/mir/util/GeneratorHTMLFunctions.java b/source/mir/util/GeneratorHTMLFunctions.java
new file mode 100755 (executable)
index 0000000..3d3078f
--- /dev/null
@@ -0,0 +1,42 @@
+package mir.util;
+
+import java.util.*;
+import java.net.*;
+
+import mir.misc.*;
+import mir.generator.*;
+
+/**
+ * <p>Title: </p>
+ * <p>Description: </p>
+ * <p>Copyright: Copyright (c) 2002</p>
+ * <p>Company: </p>
+ * @author unascribed
+ * @version 1.0
+ */
+
+public class GeneratorHTMLFunctions {
+  private GeneratorHTMLFunctions() {}
+
+  public static class encodeURIGeneratorFunction implements Generator.GeneratorFunction {
+    public Object perform(List aParameters) throws GeneratorExc {
+      if (aParameters.size()!=1)
+        throw new GeneratorExc("encodeHTMLGeneratorFunction: only 1 parameter expected");
+      if (!(aParameters.get(0) instanceof String))
+        throw new GeneratorExc("encodeHTMLGeneratorFunction: parameter must be a string");
+
+      return URLEncoder.encode((String) aParameters.get(0));
+    };
+  }
+
+  public static class encodeHTMLGeneratorFunction implements Generator.GeneratorFunction {
+    public Object perform(List aParameters) throws GeneratorExc {
+      if (aParameters.size()!=1)
+        throw new GeneratorExc("encodeHTMLGeneratorFunction: only 1 parameter expected");
+      if (!(aParameters.get(0) instanceof String))
+        throw new GeneratorExc("encodeHTMLGeneratorFunction: parameter must be a string");
+
+      return StringUtil.encodeHtml((String) aParameters.get(0));
+    };
+  }
+}
\ No newline at end of file
diff --git a/source/mir/util/ResourceBundleGeneratorFunction.java b/source/mir/util/ResourceBundleGeneratorFunction.java
new file mode 100755 (executable)
index 0000000..fc0152e
--- /dev/null
@@ -0,0 +1,37 @@
+package mir.util;
+
+import java.util.*;
+import org.apache.struts.util.MessageResources;
+
+import mir.generator.*;
+
+public class ResourceBundleGeneratorFunction implements Generator.GeneratorFunction {
+  private MessageResources messages;
+  private Locale locale;
+
+  public ResourceBundleGeneratorFunction(Locale aLocale, MessageResources aMessages) {
+    this.locale = aLocale;
+    this.messages = aMessages;
+  }
+
+  public Object perform(List aParameters) throws GeneratorExc {
+    List extraParameters = new Vector(aParameters);
+
+    if (aParameters.size()<1)
+      throw new GeneratorExc("ResourceBundleGeneratorFunction: at least 1 parameter expected");
+
+    if (!(aParameters.get(0) instanceof String))
+      throw new GeneratorExc("encodeHTMLGeneratorFunction: parameters must be strings");
+
+    String key = (String) aParameters.get(0);
+    extraParameters.remove(0);
+    String message = messages.getMessage(locale, key, extraParameters.toArray());
+
+    if (message == null) {
+      return new String("??" + key + "??");
+    }
+    else {
+      return message;
+    }
+  };
+}
\ No newline at end of file
diff --git a/source/mircoders/localizer/MirAdminInterfaceLocalizer.java b/source/mircoders/localizer/MirAdminInterfaceLocalizer.java
new file mode 100755 (executable)
index 0000000..8a5c9a6
--- /dev/null
@@ -0,0 +1,18 @@
+package mircoders.localizer;
+
+import java.util.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import mir.entity.*;
+import mir.entity.adapter.*;
+
+public interface MirAdminInterfaceLocalizer {
+  public Map simpleCommentOperations();
+  public Map simpleArticleOperations();
+
+  public interface MirSimpleEntityOperation {
+    public boolean isAvailable(EntityAdapter anEntity);
+    public void perform(EntityAdapter anEntity);
+  }
+}
\ No newline at end of file
index 65313d0..bf26533 100755 (executable)
@@ -7,6 +7,7 @@ public class MirCachingLocalizerDecorator implements MirLocalizer {
   private MirOpenPostingLocalizer openPostingsLocalizer;
   private MirProducerAssistantLocalizer producerAssistantLocalizer;
   private MirDataModelLocalizer dataModelLocalizer;
+  private MirAdminInterfaceLocalizer adminInterfaceLocalizer;
 
   public MirCachingLocalizerDecorator(MirLocalizer aLocalizer) {
     localizer = aLocalizer;
@@ -52,4 +53,13 @@ public class MirCachingLocalizerDecorator implements MirLocalizer {
     return dataModelLocalizer;
   }
 
+  public MirAdminInterfaceLocalizer adminInterface() throws MirLocalizerFailure, MirLocalizerException {
+    if (adminInterfaceLocalizer==null) {
+      adminInterfaceLocalizer = localizer.adminInterface();
+    }
+
+    return adminInterfaceLocalizer;
+  };
+
+
 }
\ No newline at end of file
index c27561d..aeb0400 100755 (executable)
@@ -2,8 +2,10 @@ package mircoders.localizer;
 
 public interface MirLocalizer {
   public MirProducerLocalizer producers() throws MirLocalizerFailure, MirLocalizerException;
+  public MirAdminInterfaceLocalizer adminInterface() throws MirLocalizerFailure, MirLocalizerException;
   public MirOpenPostingLocalizer openPostings() throws MirLocalizerFailure, MirLocalizerException;
   public MirProducerAssistantLocalizer producerAssistant() throws MirLocalizerFailure, MirLocalizerException;
   public MirGeneratorLocalizer generators() throws MirLocalizerFailure, MirLocalizerException;
   public MirDataModelLocalizer dataModel() throws MirLocalizerFailure, MirLocalizerException;
+
 }
\ No newline at end of file
diff --git a/source/mircoders/localizer/basic/MirBasicAdminInterfaceLocalizer.java b/source/mircoders/localizer/basic/MirBasicAdminInterfaceLocalizer.java
new file mode 100755 (executable)
index 0000000..044789c
--- /dev/null
@@ -0,0 +1,131 @@
+package mircoders.localizer.basic;
+
+import java.util.*;
+import mir.entity.adapter.*;
+import mir.storage.*;
+import mir.entity.*;
+import mircoders.localizer.*;
+import mircoders.entity.*;
+import mircoders.storage.*;
+
+
+public class MirBasicAdminInterfaceLocalizer implements MirAdminInterfaceLocalizer {
+  private Map simpleCommentOperations;
+  private Map simpleArticleOperations;
+
+  public MirBasicAdminInterfaceLocalizer() throws MirLocalizerFailure, MirLocalizerException {
+    simpleCommentOperations = new HashMap();
+    simpleArticleOperations = new HashMap();
+
+    buildSimpleCommentOperations(simpleCommentOperations);
+    buildSimpleArticleOperations(simpleArticleOperations);
+  }
+
+  public Map simpleCommentOperations() {
+    return simpleCommentOperations;
+  };
+
+  public Map simpleArticleOperations() {
+    return simpleArticleOperations;
+  };
+
+  public void buildSimpleCommentOperations(Map anOperations) throws MirLocalizerFailure, MirLocalizerException {
+    anOperations.put("hide", new HideCommentOperation());
+    anOperations.put("unhide", new UnhideCommentOperation());
+  };
+
+  public void buildSimpleArticleOperations(Map anOperations)  throws MirLocalizerFailure, MirLocalizerException {
+    anOperations.put("hide", new HideArticleOperation());
+    anOperations.put("unhide", new UnhideArticleOperation());
+  };
+
+  protected abstract static class EntityModifyingOperation implements MirSimpleEntityOperation {
+    public boolean isAvailable(EntityAdapter anEntity) {
+      try {
+
+        Entity entity = anEntity.getEntity();
+        return (entity instanceof EntityComment) && isAvailable((EntityComment) entity);
+      }
+      catch (Throwable t) {
+        return false;
+      }
+    };
+
+    public void perform(EntityAdapter anEntity) {
+      Entity entity = anEntity.getEntity();
+      try {
+        performModification(entity);
+        entity.update();
+      }
+      catch (Throwable t) {
+      }
+    };
+
+    protected abstract boolean isAvailable(Entity anEntity) throws StorageObjectException ;
+    protected abstract void performModification(Entity anEntity) throws StorageObjectException ;
+  }
+
+  public static abstract class CommentModifyingOperation extends EntityModifyingOperation {
+    protected boolean isAvailable(Entity anEntity) throws StorageObjectException {
+      return anEntity instanceof EntityComment && isAvailable((EntityComment) anEntity);
+    }
+
+    protected void performModification(Entity anEntity) throws StorageObjectException {
+      performModification((EntityComment) anEntity);
+      DatabaseContent.getInstance().setUnproduced("id="+anEntity.getValue("to_media"));
+    };
+
+    protected abstract boolean isAvailable(EntityComment aComment) throws StorageObjectException ;
+    protected abstract void performModification(EntityComment aComment) throws StorageObjectException ;
+  }
+
+  public static abstract class ArticleModifyingOperation extends EntityModifyingOperation {
+    protected boolean isAvailable(Entity anEntity) throws StorageObjectException {
+      return anEntity instanceof EntityContent && isAvailable((EntityComment) anEntity);
+    }
+
+    protected void performModification(Entity anEntity) throws StorageObjectException {
+      performModification((EntityContent) anEntity);
+      anEntity.setValueForProperty("is_produced", "0");
+    };
+
+    protected abstract boolean isAvailable(EntityContent anArticle) throws StorageObjectException ;
+    protected abstract void performModification(EntityContent anArticle) throws StorageObjectException ;
+  }
+
+  private static class HideCommentOperation extends CommentModifyingOperation {
+    protected boolean isAvailable(EntityComment aComment) {
+      return aComment.getValue("is_published").equals("1");
+    }
+    protected void performModification(EntityComment aComment) throws StorageObjectException {
+      aComment.setValueForProperty("is_published", "0");
+    }
+  }
+
+  private static class UnhideCommentOperation extends CommentModifyingOperation {
+    protected boolean isAvailable(EntityComment aComment) {
+      return aComment.getValue("is_published").equals("0");
+    }
+    protected void performModification(EntityComment aComment) throws StorageObjectException {
+      aComment.setValueForProperty("is_published", "1");
+    }
+  }
+
+  private static class HideArticleOperation extends ArticleModifyingOperation {
+    protected boolean isAvailable(EntityContent anArticle) {
+      return anArticle.getValue("is_published").equals("1");
+    }
+    protected void performModification(EntityContent anArticle) throws StorageObjectException {
+      anArticle.setValueForProperty("is_published", "0");
+    }
+  }
+
+  private static class UnhideArticleOperation extends ArticleModifyingOperation {
+    protected boolean isAvailable(EntityContent anArticle) {
+      return anArticle.getValue("is_published").equals("0");
+    }
+    protected void performModification(EntityContent anArticle) throws StorageObjectException {
+      anArticle.setValueForProperty("is_published", "1");
+    }
+  }
+}
\ No newline at end of file
index bbcb860..4edec5b 100755 (executable)
@@ -53,6 +53,7 @@ public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {
       anEntityAdapterDefinition.addCalculatedField("to_content", new CommentToContentField());\r
 \r
       anEntityAdapterDefinition.addCalculatedField("description_parsed", new FilteredField("description"));\r
+      anEntityAdapterDefinition.addCalculatedField("operations", new CommentToOperationsField());\r
     }\r
     catch (Throwable t) {\r
       throw new MirLocalizerFailure(t.getMessage(), t);\r
@@ -110,6 +111,33 @@ public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {
       }\r
     }\r
   }\r
+\r
+  protected class CommentToOperationsField implements EntityAdapterDefinition.CalculatedField {\r
+    public Object getValue(EntityAdapter anEntityAdapter) {\r
+      try {\r
+        Map operations = MirGlobal.localizer().adminInterface().simpleCommentOperations();\r
+        Iterator i = operations.entrySet().iterator();\r
+        List availableOperations = new Vector();\r
+\r
+        while (i.hasNext()) {\r
+          Map.Entry entry = (Map.Entry) i.next();\r
+\r
+          MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =\r
+            (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) entry.getValue();\r
+\r
+          if (operation.isAvailable(anEntityAdapter)) {\r
+            availableOperations.add(entry.getKey());\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
     String fieldName;\r
 \r
index b16b0e0..40eef61 100755 (executable)
@@ -27,4 +27,9 @@ public class MirBasicLocalizer implements MirLocalizer {
     return new MirBasicDataModelLocalizer();
   };
 
+  public MirAdminInterfaceLocalizer adminInterface() throws MirLocalizerFailure, MirLocalizerException {
+    return new MirBasicAdminInterfaceLocalizer();
+  };
+
+
 }
\ No newline at end of file
index 550d514..2923ed0 100755 (executable)
@@ -25,6 +25,7 @@ public class MirBasicProducerAssistantLocalizer implements MirProducerAssistantL
     configMap.put("productionHost", MirGlobal.getConfigProperty("Producer.ProductionHost"));
     configMap.put("openAction", MirGlobal.getConfigProperty("Producer.OpenAction"));
     configMap.put("docRoot", MirGlobal.getConfigProperty("RootUri"));
+    configMap.put("actionRoot", MirGlobal.getConfigProperty("RootUri")+"/servlet/Mir");
     configMap.put("now", new DateToMapAdapter((new GregorianCalendar()).getTime()));
     configMap.put("videoHost", MirGlobal.getConfigProperty("Producer.Video.Host"));
     configMap.put("audioHost", MirGlobal.getConfigProperty("Producer.Audio.Host"));
@@ -34,6 +35,8 @@ public class MirBasicProducerAssistantLocalizer implements MirProducerAssistantL
     configMap.put("defEncoding", MirGlobal.getConfigProperty("Mir.DefaultEncoding"));
 
     utilityMap.put("compressWhitespace", new freemarker.template.utility.CompressWhitespace() );
+    utilityMap.put("encodeHTML", new GeneratorHTMLFunctions.encodeHTMLGeneratorFunction());
+    utilityMap.put("encodeURI", new GeneratorHTMLFunctions.encodeURIGeneratorFunction());
 
     aValueSet.put("config", configMap);
     aValueSet.put("utility", utilityMap);
index dc5383d..57f225f 100755 (executable)
@@ -6,6 +6,7 @@ import java.util.*;
 import java.net.*;
 import javax.servlet.*;
 import javax.servlet.http.*;
+import org.apache.struts.util.MessageResources;
 
 import freemarker.template.*;
 
@@ -14,9 +15,14 @@ import mir.module.*;
 import mir.misc.*;
 import mir.entity.*;
 import mir.storage.*;
-
+import mir.generator.*;
 import mir.entity.*;
+import mir.entity.adapter.*;
+import mir.util.*;
+
 import mircoders.storage.*;
+import mircoders.global.*;
+import mircoders.localizer.*;
 import mircoders.module.*;
 
 /*
@@ -29,98 +35,205 @@ import mircoders.module.*;
 public class ServletModuleComment extends ServletModule
 {
 
-       private ModuleContent     moduleContent;
-
-       // Singelton / Kontruktor
-       private static ServletModuleComment instance = new ServletModuleComment();
-       public static ServletModule getInstance() { return instance; }
-
-       private ServletModuleComment() {
-               theLog = Logfile.getInstance(MirConfig.getProp("Home") + MirConfig.getProp("ServletModule.Comment.Logfile"));
-               templateListString = MirConfig.getProp("ServletModule.Comment.ListTemplate");
-               templateObjektString = MirConfig.getProp("ServletModule.Comment.ObjektTemplate");
-               templateConfirmString = MirConfig.getProp("ServletModule.Comment.ConfirmTemplate");
-               try {
-                       mainModule = new ModuleComment(DatabaseComment.getInstance());
-                       moduleContent = new ModuleContent(DatabaseContent.getInstance());
-               }
-               catch (StorageObjectException e) {
-                       theLog.printError("servletmodule: comment could not be initialized");
-               }
-       }
-
-
-       public void list(HttpServletRequest req, HttpServletResponse res)
-               throws ServletModuleException
-       {
-                       // Parameter auswerten
-                       SimpleHash mergeData = new SimpleHash();
-                       String query_text = req.getParameter("query_text");
-                       mergeData.put("query_text",query_text);
-                       if (query_text!=null) mergeData.put("query_text_encoded",URLEncoder.encode(query_text));
-                       String query_field = req.getParameter("query_field");
-                       mergeData.put("query_field",query_field);
-                       String query_is_published = req.getParameter("query_is_published");
-                       mergeData.put("query_is_published",query_is_published);
-
-                       String offset = req.getParameter("offset");
-                       if (offset==null || offset.equals("")) offset="0";
-                       mergeData.put("offset",offset);
-
-                       // patching order
-                       String order = req.getParameter("order");
-                       if(order!=null) {
-                               mergeData.put("order", order);
-                               mergeData.put("order_encoded", URLEncoder.encode(order));
-                               if (order.equals("webdb_create")) order="webdb_create desc";
-                       }
-
-                       // sql basteln
-                       String whereClause=""; boolean isFirst=true;
-                       if (query_text!=null && !query_text.equalsIgnoreCase("")) {
-                               whereClause += "lower("+query_field+") like lower('%"+query_text+"%')"; isFirst=false;}
-                       if (query_is_published != null && !query_is_published.equals("")) {
-                               if (isFirst==false) whereClause+=" and ";
-                               whereClause += "is_published='"+query_is_published+"'";
-                               isFirst=false;
-                       }
-
-                       theLog.printDebugInfo("sql-whereclause: " + whereClause + " order: " + order + " offset: " + offset);
-
-                       // fetch und ausliefern
-                       try {
-
-                               if (query_text!=null || query_is_published!=null ) {
-                                       EntityList theList = mainModule.getByWhereClause(whereClause, order, (new Integer(offset)).intValue());
-                                       if (theList!=null && theList.size()>0) {
-
-                                               //make articleHash for comment
-                                               StringBuffer buf= new StringBuffer("id in (");boolean first=true;
-                                               for(int i=0;i<theList.size();i++) {
-                                                       if (first==false) buf.append(",");
-                                                       first=false;
-                                                       buf.append(theList.elementAt(i).getValue("to_media"));
-                                               }
-                                               buf.append(")");
-                                               SimpleHash articleHash = HTMLTemplateProcessor.makeSimpleHash(moduleContent.getByWhereClause(buf.toString(),-1));
-                                               mergeData.put("articleHash", articleHash);
-
-                                               // get comment
-                                               mergeData.put("contentlist",theList);
-                                               mergeData.put("count", (new Integer(theList.getCount())).toString());
-                                               mergeData.put("from", (new Integer(theList.getFrom())).toString());
-                                               mergeData.put("to", (new Integer(theList.getTo())).toString());
-                                               if (theList.hasNextBatch())
-                                                       mergeData.put("next", (new Integer(theList.getNextBatch())).toString());
-                                               if (theList.hasPrevBatch())
-                                                       mergeData.put("prev", (new Integer(theList.getPrevBatch())).toString());
-                                       }
-                               }
-                               // raus damit
-                               HTMLTemplateProcessor.process(res, templateListString, mergeData, res.getWriter(), getLocale(req));
-                       }
-                       catch (ModuleException e) {throw new ServletModuleException(e.toString());}
-                       catch (IOException e) {throw new ServletModuleException(e.toString());}
-                       catch (Exception e) {throw new ServletModuleException(e.toString());}
-       }
+  private ModuleContent     moduleContent;
+
+  // Singelton / Kontruktor
+  private static ServletModuleComment instance = new ServletModuleComment();
+  public static ServletModule getInstance() { return instance; }
+
+  private ServletModuleComment() {
+    theLog = Logfile.getInstance(MirConfig.getProp("Home") + MirConfig.getProp("ServletModule.Comment.Logfile"));
+    templateListString = MirConfig.getProp("ServletModule.Comment.ListTemplate");
+    templateObjektString = MirConfig.getProp("ServletModule.Comment.ObjektTemplate");
+    templateConfirmString = MirConfig.getProp("ServletModule.Comment.ConfirmTemplate");
+    try {
+      mainModule = new ModuleComment(DatabaseComment.getInstance());
+      moduleContent = new ModuleContent(DatabaseContent.getInstance());
+    }
+    catch (StorageObjectException e) {
+      theLog.printError("servletmodule: comment could not be initialized");
+    }
+  }
+
+  public void list(HttpServletRequest req, HttpServletResponse res)
+      throws ServletModuleException
+  {
+    // Parameter auswerten
+    SimpleHash mergeData = new SimpleHash();
+    String query_text = req.getParameter("query_text");
+    mergeData.put("query_text",query_text);
+    if (query_text!=null) mergeData.put("query_text_encoded",URLEncoder.encode(query_text));
+    String query_field = req.getParameter("query_field");
+    mergeData.put("query_field",query_field);
+    String query_is_published = req.getParameter("query_is_published");
+    mergeData.put("query_is_published",query_is_published);
+
+    String offset = req.getParameter("offset");
+    if (offset==null || offset.equals("")) offset="0";
+    mergeData.put("offset",offset);
+
+    // patching order
+    String order = req.getParameter("order");
+    if(order!=null) {
+      mergeData.put("order", order);
+      mergeData.put("order_encoded", URLEncoder.encode(order));
+      if (order.equals("webdb_create")) order="webdb_create desc";
+    }
+
+    // sql basteln
+    String whereClause=""; boolean isFirst=true;
+    if (query_text!=null && !query_text.equalsIgnoreCase("")) {
+    whereClause += "lower("+query_field+") like lower('%"+query_text+"%')"; isFirst=false;}
+    if (query_is_published != null && !query_is_published.equals("")) {
+      if (isFirst==false) whereClause+=" and ";
+      whereClause += "is_published='"+query_is_published+"'";
+      isFirst=false;
+    }
+
+    theLog.printDebugInfo("sql-whereclause: " + whereClause + " order: " + order + " offset: " + offset);
+
+    // fetch und ausliefern
+    try {
+
+      if (query_text!=null || query_is_published!=null ) {
+        EntityList theList = mainModule.getByWhereClause(whereClause, order, (new Integer(offset)).intValue());
+        if (theList!=null && theList.size()>0) {
+
+          //make articleHash for comment
+          StringBuffer buf= new StringBuffer("id in (");boolean first=true;
+          for(int i=0;i<theList.size();i++) {
+            if (first==false) buf.append(",");
+            first=false;
+            buf.append(theList.elementAt(i).getValue("to_media"));
+          }
+          buf.append(")");
+          SimpleHash articleHash = HTMLTemplateProcessor.makeSimpleHash(moduleContent.getByWhereClause(buf.toString(),-1));
+          mergeData.put("articleHash", articleHash);
+
+          // get comment
+          mergeData.put("contentlist",theList);
+          mergeData.put("count", (new Integer(theList.getCount())).toString());
+          mergeData.put("from", (new Integer(theList.getFrom())).toString());
+          mergeData.put("to", (new Integer(theList.getTo())).toString());
+          if (theList.hasNextBatch())
+            mergeData.put("next", (new Integer(theList.getNextBatch())).toString());
+          if (theList.hasPrevBatch())
+            mergeData.put("prev", (new Integer(theList.getPrevBatch())).toString());
+        }
+      }
+      // raus damit
+      HTMLTemplateProcessor.process(res, templateListString, mergeData, res.getWriter(), getLocale(req));
+    }
+    catch (ModuleException e) {throw new ServletModuleException(e.toString());}
+    catch (IOException e) {throw new ServletModuleException(e.toString());}
+    catch (Exception e) {throw new ServletModuleException(e.toString());}
+  }
+
+  public void showArticleCommentList(Object aWriter, int anOffset, int anArticleId, Locale aLocale) throws ServletModuleException {
+    int nrCommentsPerPage = 20;
+
+    Object comments;
+    Map generationData;
+    Generator generator;
+    int totalNrComments;
+    EntityAdapterModel model;
+    MessageResources messages = MessageResources.getMessageResources("bundles.admin");
+
+    try {
+      generator = MirGlobal.localizer().generators().makeGeneratorLibrary().makeGenerator("admin/commentlist2.template");
+      model = MirGlobal.localizer().dataModel().adapterModel();
+
+//    commentList = mainModule.getByWhereClause(whereClause, order, offset);
+
+      generationData = new HashMap();
+      MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(generationData);
+
+      comments =
+        new CachingRewindableIterator(
+          new EntityIteratorAdapter( "to_media = " + anArticleId,
+               "webdb_create desc",
+               nrCommentsPerPage,
+               model,
+              "comment",
+              nrCommentsPerPage,
+              anOffset
+          )
+        );
+
+      totalNrComments = model.getMappingForName("comment").getStorage().getSize("to_media = " + anArticleId);
+
+      generationData.put( "comments", comments);
+      generationData.put( "offset", new Integer(anOffset));
+      generationData.put( "articleid", new Integer(anArticleId));
+      generationData.put( "lang", new MessageMethodModel(aLocale, messages) );
+      generationData.put( "thisurl", "module=Comment&do=listarticlecomments&offset="+anOffset+"&articleid="+anArticleId);
+
+      if (anOffset>0) {
+        generationData.put( "previousurl", "module=Comment&do=listarticlecomments&offset="+
+                            Math.max( 0, anOffset - nrCommentsPerPage )+"&articleid="+anArticleId);
+        generationData.put("previous", new Integer(Math.max( 0, anOffset - nrCommentsPerPage )));
+      }
+
+      if (anOffset + nrCommentsPerPage < totalNrComments) {
+        generationData.put( "nexturl", "module=Comment&do=listarticlecomments&offset="+
+                            Math.min( anOffset + nrCommentsPerPage, totalNrComments-1 )+"&articleid="+anArticleId);
+        generationData.put("next", new Integer(Math.min( anOffset + nrCommentsPerPage, totalNrComments-1 )));
+      }
+
+      generator.generate(aWriter, generationData, new PrintWriter(new NullWriter()));
+    }
+    catch (Throwable t) {
+      t.printStackTrace(System.out);
+      throw new ServletModuleException(t.getMessage());
+    }
+  }
+
+  public void listarticlecomments(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
+  {
+    String articleIdString = req.getParameter("articleid");
+    String offsetString = req.getParameter("offset");
+    int offset = 0;
+    int articleId = 0;
+
+    try {
+      offset = Integer.parseInt(offsetString);
+    }
+    catch (Throwable t) {
+    }
+
+    try {
+      articleId  = Integer.parseInt(articleIdString);
+
+      showArticleCommentList( res.getWriter(), offset, articleId, getLocale(req));
+    }
+    catch (ServletModuleException e) {
+      throw e;
+    }
+    catch (Throwable e) {
+      e.printStackTrace(System.out);
+      throw new ServletModuleException(e.getMessage());
+    }
+  }
+
+  public void performarticlecommentsoperation(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException {
+    String commentIdString = req.getParameter("commentid");
+    String articleIdString = req.getParameter("articleid");
+    String offsetString = req.getParameter("offset");
+    String operation = req.getParameter("operation");
+    int offset = 0;
+    int articleId = 0;
+
+    try {
+      articleId  = Integer.parseInt(articleIdString);
+
+      showArticleCommentList( res.getWriter(), offset, articleId, getLocale(req));
+    }
+    catch (ServletModuleException e) {
+      throw e;
+    }
+    catch (Throwable e) {
+      e.printStackTrace(System.out);
+      throw new ServletModuleException(e.getMessage());
+    }
+  }
 }
diff --git a/source/mircoders/servlet/ServletModuleLocalizer.java b/source/mircoders/servlet/ServletModuleLocalizer.java
new file mode 100755 (executable)
index 0000000..9c58d9f
--- /dev/null
@@ -0,0 +1,41 @@
+package mircoders.servlet;
+
+import java.util.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import mir.servlet.*;
+import mir.entity.adapter.*;
+import mircoders.global.*;
+import mircoders.localizer.*;
+import mircoders.storage.*;
+import mircoders.entity.*;
+
+public class ServletModuleLocalizer extends ServletModule {
+  private static ServletModuleLocalizer instance = new ServletModuleLocalizer();
+
+  public static ServletModule getInstance() { return instance; }
+
+  public void commentoperation(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException
+  {
+    try {
+      String operationKey = req.getParameter("operation");
+      String commentId = req.getParameter("commentid");
+      EntityComment comment = (EntityComment) DatabaseComment.getInstance().selectById(commentId);
+      MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =
+          (MirAdminInterfaceLocalizer.MirSimpleEntityOperation)
+          MirGlobal.localizer().adminInterface().simpleCommentOperations().get(operationKey);
+
+      EntityAdapter adapter = MirGlobal.localizer().dataModel().adapterModel().makeEntityAdapter("comment", comment);
+
+      operation.perform( adapter );
+
+      res.sendRedirect(req.getParameter("returnuri"));
+    }
+    catch (Throwable t) {
+      t.printStackTrace(System.out);
+      throw new ServletModuleException(t.getMessage());
+    }
+  }
+}
\ No newline at end of file