filter page bugs resolved
authorzapata <zapata>
Wed, 9 Nov 2005 22:11:06 +0000 (22:11 +0000)
committerzapata <zapata>
Wed, 9 Nov 2005 22:11:06 +0000 (22:11 +0000)
source/mir/generator/FreemarkerGenerator.java
source/mir/storage/Database.java
source/mir/storage/DatabaseHelper.java [new file with mode: 0755]
source/mircoders/abuse/FilterEngine.java
source/mircoders/storage/DatabaseArticleType.java
templates/admin/filterlist.template

index 576442a..795807a 100755 (executable)
@@ -37,6 +37,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Collection;
 
 import mir.log.LoggerWrapper;
 import mir.util.GeneratorFormatAdapters;
@@ -65,17 +66,17 @@ public class FreemarkerGenerator implements Generator {
   }
 
   public void generate(Object anOutputWriter, Map aValues, LoggerWrapper aLogger) throws GeneratorExc, GeneratorFailure {
-    if (!(anOutputWriter instanceof PrintWriter))
+    if (!(anOutputWriter instanceof PrintWriter)) {
       throw new GeneratorExc("Writer for a FreemarkerGenerator must be a PrintWriter");
+    }
 
     try {
       template.process((TemplateModelRoot) makeMapAdapter(aValues), (PrintWriter) anOutputWriter);
     }
     catch (Throwable t) {
-      t.printStackTrace();
-      aLogger.error("Exception occurred: "+t.getMessage());
-      t.printStackTrace(aLogger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
-      throw new GeneratorFailure( t );
+      aLogger.error("Exception occurred: "+t.getMessage(), t);
+
+      throw new GeneratorFailure(t);
     }
   }
 
@@ -100,35 +101,48 @@ public class FreemarkerGenerator implements Generator {
   }
 
   public static TemplateModel makeAdapter(Object anObject) throws TemplateModelException {
-    if (anObject == null)
+    if (anObject == null) {
       return null;
+    }
 
-    if (anObject instanceof TemplateModel)
+    if (anObject instanceof TemplateModel) {
       return (TemplateModel) anObject;
-    else if (anObject instanceof Generator.Function)
+    }
+    else if (anObject instanceof Generator.Function) {
       return makeFunctionAdapter((Generator.Function) anObject);
-    else if (anObject instanceof Integer)
+    }
+    else if (anObject instanceof Integer) {
       return makeStringAdapter(anObject.toString());
+    }
     else if (anObject instanceof Boolean) {
-      if (((Boolean) anObject).booleanValue())
+      if (((Boolean) anObject).booleanValue()) {
         return makeStringAdapter("1");
-      else
+      }
+      else {
         return makeStringAdapter("0");
+      }
     }
-    else if (anObject instanceof String)
+    else if (anObject instanceof String) {
       return makeStringAdapter((String) anObject);
-    else if (anObject instanceof Map)
+    }
+    else if (anObject instanceof Map) {
       return makeMapAdapter((Map) anObject);
-    else if (anObject instanceof Iterator)
+    }
+    else if (anObject instanceof Iterator) {
       return makeIteratorAdapter((Iterator) anObject);
-    else if (anObject instanceof List)
-      return makeIteratorAdapter(((List) anObject).iterator());
-    else if (anObject instanceof Number)
+    }
+    else if (anObject instanceof Collection) {
+      return makeIteratorAdapter(((Collection) anObject).iterator());
+    }
+    else if (anObject instanceof Number) {
       return makeAdapter(new GeneratorFormatAdapters.NumberFormatAdapter((Number) anObject));
-    else if (anObject instanceof Date)
+    }
+    else if (anObject instanceof Date) {
       return makeAdapter(new GeneratorFormatAdapters.DateFormatAdapter((Date) anObject));
-    else
+    }
+    else {
       return makeBeanAdapter(anObject);
+    }
   }
 
   private static class MapAdapter implements TemplateModelRoot {
@@ -203,15 +217,10 @@ public class FreemarkerGenerator implements Generator {
     }
 
     public TemplateModel get(int anIndex) throws TemplateModelException {
-      TemplateModel result;
-
       getUntil(anIndex);
 
-      if (anIndex<valuesCache.size())
-      {
-        result = (TemplateModel) valuesCache.get(anIndex);
-
-        return result;
+      if (anIndex<valuesCache.size()) {
+        return (TemplateModel) valuesCache.get(anIndex);
       }
                        throw new TemplateModelException( "Iterator out of bounds" );
     }
@@ -242,66 +251,10 @@ public class FreemarkerGenerator implements Generator {
     }
   }
 
-  private static class ListAdapter implements TemplateListModel {
-    List list;
-    List valuesCache;
-    int position;
-
-    private ListAdapter(List aList) {
-      list = aList;
-      valuesCache = new ArrayList();
-      position=0;
-    }
-
-    public boolean isEmpty() {
-      return list.isEmpty();
-    }
-
-    public TemplateModel get(int i) throws TemplateModelException {
-
-      if (i>=valuesCache.size() && i<list.size()) {
-        for(int j=valuesCache.size(); j<=i; j++) {
-          valuesCache.add(makeAdapter(list.get(j)));
-        }
-      }
-
-      if (i<valuesCache.size())
-        return (TemplateModel) valuesCache.get(i);
-      
-                       throw new TemplateModelException( "Iterator out of bounds" );
-    }
-
-    public boolean hasNext() {
-      return position<list.size();
-    }
-
-    public boolean isRewound() {
-      return position==0;
-    }
-
-    public TemplateModel next() throws TemplateModelException {
-      TemplateModel result;
-
-      if (hasNext()) {
-        result = get(position);
-        position++;
-      }
-      else {
-        throw new TemplateModelException( "Iterator out of bounds" );
-      }
-
-      return result;
-    }
-
-    public void rewind() {
-      position = 0;
-    }
-  }
-
   private static class FunctionAdapter implements TemplateMethodModel {
     private Generator.Function function;
 
-    public FunctionAdapter(Generator.Function aFunction) {
+    FunctionAdapter(Generator.Function aFunction) {
       function = aFunction;
     }
 
@@ -341,8 +294,9 @@ public class FreemarkerGenerator implements Generator {
 
     public TemplateModel get(String aKey) throws TemplateModelException {
       try {
-        if (PropertyUtils.isReadable(object, aKey))
+        if (PropertyUtils.isReadable(object, aKey)) {
           return makeAdapter(PropertyUtils.getSimpleProperty(object, aKey));
+        }
                                return makeAdapter(MethodUtils.invokeExactMethod(object, "get", aKey));
       }
       catch (Throwable t) {
index 5550c87..481efa5 100755 (executable)
@@ -35,7 +35,6 @@ import mir.entity.Entity;
 import mir.entity.EntityList;
 import mir.entity.StorableObjectEntity;
 import mir.log.LoggerWrapper;
-import mir.misc.StringUtil;
 import mir.storage.store.*;
 import mir.util.JDBCStringRoutines;
 import mir.util.StreamCopier;
@@ -56,23 +55,22 @@ import java.util.*;
 /**
  * Implements database access.
  *
- * @version $Id: Database.java,v 1.44.2.33 2005/08/21 17:09:21 zapata Exp $
+ * @version $Id: Database.java,v 1.44.2.34 2005/11/09 22:11:06 zapata Exp $
  * @author rk
  * @author Zapata
  *
  */
 public class Database {
-       private static int DEFAULT_LIMIT = 20;
-  private static Class GENERIC_ENTITY_CLASS = mir.entity.StorableObjectEntity.class;
+       private static final int DEFAULT_LIMIT = 20;
+  private static final Class GENERIC_ENTITY_CLASS = StorableObjectEntity.class;
   protected static final ObjectStore o_store = ObjectStore.getInstance();
-  private static final int _millisPerHour = 60 * 60 * 1000;
 
   protected LoggerWrapper logger;
 
   protected String mainTable;
   protected String primaryKeyField = "id";
 
-  protected List fieldNames;
+  private List fieldNames;
   private int[] fieldTypes;
   private Map fieldNameToType;
 
@@ -81,29 +79,26 @@ public class Database {
   //
   private Set binaryFields;
 
-  TimeZone timezone;
-  SimpleDateFormat internalDateFormat;
-  SimpleDateFormat userInputDateFormat;
+  private TimeZone timezone;
+  private SimpleDateFormat userInputDateFormat;
 
   public Database() throws DatabaseFailure {
     MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();
     logger = new LoggerWrapper("Database");
     timezone = TimeZone.getTimeZone(configuration.getString("Mir.DefaultTimezone"));
-    internalDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-    internalDateFormat.setTimeZone(timezone);
 
     userInputDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
     userInputDateFormat.setTimeZone(timezone);
 
     binaryFields = new HashSet();
 
-    String theAdaptorName = configuration.getString("Database.Adaptor");
+    String adapterName = configuration.getString("Database.Adaptor");
 
     try {
       entityClass = GENERIC_ENTITY_CLASS;
     }
     catch (Throwable e) {
-      logger.error("Error in Database() constructor with " + theAdaptorName + " -- " + e.getMessage());
+      logger.error("Error in Database() constructor with " + adapterName + " -- " + e.getMessage());
       throw new DatabaseFailure("Error in Database() constructor.", e);
     }
   }
@@ -246,20 +241,7 @@ public class Database {
 
             if (!aResultSet.wasNull()) {
               java.util.Date date = new java.util.Date(timestamp.getTime());
-
-              Calendar calendar = new GregorianCalendar();
-              calendar.setTime(date);
-              calendar.setTimeZone(timezone);
-              outValue = internalDateFormat.format(date);
-
-              int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
-              String tzOffset = StringUtil.zeroPaddingNumber(Math.abs(offset) / _millisPerHour, 2, 2);
-
-              if (offset<0)
-                outValue = outValue + "-";
-              else
-                outValue = outValue + "+";
-              outValue = outValue + tzOffset;
+              outValue = DatabaseHelper.convertDateToInternalRepresenation(date);
             }
 
             break;
@@ -268,7 +250,8 @@ public class Database {
             outValue = "<unsupported value>";
             logger.warn("Unsupported Datatype: at " + aFieldIndex + " (" + aType + ")");
         }
-      } catch (SQLException e) {
+      }
+      catch (SQLException e) {
         throw new DatabaseFailure("Could not get Value out of Resultset -- ",
           e);
       }
@@ -618,21 +601,17 @@ public class Database {
    * @param theEntity
    */
   public void update(Entity theEntity) throws DatabaseFailure {
-    Connection connection = null;
-
     invalidateStore();
 
     RecordUpdater generator = new RecordUpdater(getTableName(), theEntity.getId());
 
-    String field;
-
     // build sql statement
     for (int i = 0; i < getFieldNames().size(); i++) {
-      field = (String) getFieldNames().get(i);
+      String field = (String) getFieldNames().get(i);
 
       if (!(field.equals(primaryKeyField) ||
-            field.equals("webdb_create") ||
-            field.equals("webdb_lastchange") ||
+            "webdb_create".equals(field) ||
+            "webdb_lastchange".equals(field) ||
             binaryFields.contains(field))) {
 
         if (theEntity.hasFieldValue(field)) {
@@ -669,6 +648,7 @@ public class Database {
         }
       }
     }
+    Connection connection = null;
 
     try {
       connection = obtainConnection();
diff --git a/source/mir/storage/DatabaseHelper.java b/source/mir/storage/DatabaseHelper.java
new file mode 100755 (executable)
index 0000000..ab8c48e
--- /dev/null
@@ -0,0 +1,86 @@
+/*\r
+ * Copyright (C) 2005 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 mir.storage;\r
+\r
+import mir.config.MirPropertiesConfiguration;\r
+import mir.misc.StringUtil;\r
+\r
+import java.text.DateFormat;\r
+import java.text.SimpleDateFormat;\r
+import java.util.Date;\r
+import java.util.TimeZone;\r
+import java.util.GregorianCalendar;\r
+import java.util.Calendar;\r
+\r
+public class DatabaseHelper {\r
+  public static final TimeZone INTERNAL_TIMEZONE = TimeZone.getTimeZone(\r
+      MirPropertiesConfiguration.instance().getString("Mir.DefaultTimezone"));\r
+  public static final DateFormat INTERNAL_DATE_FORMAT =\r
+      new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");\r
+\r
+  static {\r
+    INTERNAL_DATE_FORMAT.setTimeZone(INTERNAL_TIMEZONE);\r
+  }\r
+\r
+  public static final String convertDateToInternalRepresenation(Date aDate) {\r
+    Calendar calendar = new GregorianCalendar();\r
+    calendar.setTime(aDate);\r
+    calendar.setTimeZone(INTERNAL_TIMEZONE);\r
+    int offset = calendar.get(Calendar.ZONE_OFFSET);\r
+    boolean positive = true;\r
+    if (offset<0) {\r
+      positive=false;\r
+      offset = -offset;\r
+    }\r
+    int offsethours = offset / (60*60*1000);\r
+\r
+    return INTERNAL_DATE_FORMAT.format(aDate) + (positive?"+":"-") +\r
+        StringUtil.zeroPaddingNumber(offsethours, 2, 2);\r
+  }\r
+\r
+  public static final String getInternalTimeZoneOffset(Date aDate) {\r
+    Calendar calendar = new GregorianCalendar();\r
+    calendar.setTime(aDate);\r
+    calendar.setTimeZone(INTERNAL_TIMEZONE);\r
+\r
+    int offset = calendar.get(Calendar.DST_OFFSET);\r
+    boolean positive = true;\r
+    if (offset<0) {\r
+      positive=false;\r
+      offset = -offset;\r
+    }\r
+    int offsethours = offset / 60*60*1000;\r
+    int offsetminutes = ( offset / 60*1000 ) % 60;\r
+\r
+    return (positive?"+":"-") +\r
+            StringUtil.zeroPaddingNumber(offsethours, 2, 2) + ":" +\r
+            StringUtil.zeroPaddingNumber(offsetminutes, 2, 2);\r
+  }\r
+}\r
index 1981946..4032102 100755 (executable)
@@ -30,7 +30,6 @@
 
 package mircoders.abuse;
 
-import mir.config.MirPropertiesConfiguration;
 import mir.entity.Entity;
 import mir.entity.adapter.EntityAdapter;
 import mir.entity.adapter.EntityAdapterModel;
@@ -38,34 +37,32 @@ import mir.entity.adapter.EntityIteratorAdapter;
 import mir.log.LoggerWrapper;
 import mir.session.Request;
 import mir.storage.DatabaseExc;
+import mir.storage.DatabaseHelper;
 import mircoders.global.MirGlobal;
 import mircoders.storage.DatabaseFilter;
 import mircoders.storage.DatabaseFilterGroup;
 
-import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 /** The FilterEngine manages a list of all filters and filter groups.
  *  Use the testPosting() method to apply all filters on an 
  *  Entity (for ex. an article or a comment)
  */
 public class FilterEngine {
-  private Map filterTypes;
-  private List filterTypeIds;
+  private final Map filterTypes = new HashMap();
+  private final List filterTypeIds = new ArrayList();
 
-  private List filterGroups;
-  private Map idToFilterGroup;
-  private LoggerWrapper logger;
+  private final List filterGroups = new ArrayList();
+  private final Map idToFilterGroup = new HashMap();
+  private final LoggerWrapper logger = new LoggerWrapper("Global.Abuse.FilterEngine");
   private EntityAdapterModel model;
-  private SimpleDateFormat dateFormat;
-  private MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();
 
   public FilterEngine(EntityAdapterModel aModel) {
-    logger = new LoggerWrapper("Global.Abuse.FilterEngine");
-    filterGroups = new ArrayList();
-    idToFilterGroup = new HashMap();
-
-    filterTypes = new HashMap();
-    filterTypeIds = new ArrayList();
     try {
       Iterator i = MirGlobal.localizer().openPostings().getAntiAbuseFilterTypes().iterator();
       while (i.hasNext()) {
@@ -81,18 +78,18 @@ public class FilterEngine {
 
     model = aModel;
 
-    dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-    dateFormat.setTimeZone(TimeZone.getTimeZone(configuration.getString("Mir.DefaultTimezone")));
     reload();
   }
+
   /** applies all filters from all filter groups to an Entity.
    *  The entity may be, for example, an article, or a comment.
    *  It returns a filter that matches if it finds one, null otherwise  
    */
-  public Filter testPosting(Entity anEntity, Request aRequest) {
+  public synchronized Filter testPosting(Entity anEntity, Request aRequest) {
     Iterator i = filterGroups.iterator();
     while (i.hasNext()) {
       FilterGroup group = (FilterGroup) i.next();
+
       Iterator j = group.getFilters().iterator();
       while (j.hasNext()) {
         Filter filter = (Filter) j.next();
@@ -128,7 +125,7 @@ public class FilterEngine {
       return result;
     }
     catch (Throwable t) {
-      throw new RuntimeException("can't get article actions");
+      throw new RuntimeException("can't get article actions: " + t.getMessage());
     }
   }
   /** This class reflects a row of the filter_group 
@@ -314,7 +311,9 @@ public class FilterEngine {
    }
 
     public void updateLastHit(Date aDate) {
-      entity.setFieldValue("last_hit", dateFormat.format(aDate));
+      entity.setFieldValue("last_hit",
+          DatabaseHelper.convertDateToInternalRepresenation(
+              new Date(System.currentTimeMillis())));
       entity.update();
     }
 
@@ -452,12 +451,12 @@ public class FilterEngine {
     return getFilterGroupForId(aFilterGroupId).getFilterEntityAdapterList();
   }
 
-  private void introduceFilterGroup(FilterGroup aFilterGroup) {
+  private synchronized void introduceFilterGroup(FilterGroup aFilterGroup) {
     filterGroups.add(aFilterGroup);
     idToFilterGroup.put(aFilterGroup.getEntity().getId(), aFilterGroup);
   }
 
-  private void removeFilterGroup(FilterGroup aFilterGroup) {
+  private synchronized void removeFilterGroup(FilterGroup aFilterGroup) {
     filterGroups.remove(aFilterGroup);
     idToFilterGroup.remove(aFilterGroup.getEntity().getId());
   }
index 0091e0a..b0858e8 100755 (executable)
@@ -35,21 +35,20 @@ import mir.storage.Database;
 import mir.storage.DatabaseFailure;
 
 public class DatabaseArticleType extends Database {
-
   private static DatabaseArticleType instance;
 
-  public synchronized static DatabaseArticleType getInstance() throws DatabaseFailure {
-    if (instance == null) {
-      instance = new DatabaseArticleType();
-    }
-    return instance;
-  }
-
   private DatabaseArticleType() throws DatabaseFailure {
-    super();
-
     logger = new LoggerWrapper("Database.ArticleType");
     mainTable = "article_type";
   }
 
+  public static DatabaseArticleType getInstance() throws DatabaseFailure {
+    synchronized (DatabaseArticleType.class) {
+      if (instance == null) {
+        instance = new DatabaseArticleType();
+      }
+    }
+
+    return instance;
+  }
 }
index c708b52..f859b3d 100755 (executable)
@@ -18,7 +18,7 @@
     </p>
     <call ListStart()>\r
     <call SpannedListHead([
-          lang("filter.type"), 
+          lang("filter.type"),
           lang("filter.expression")], ["1","3"])>
     <call ListHead([
           lang("filter.articleaction"),
           lang("filter.last_hit")])>
     <call SpannedListHead([
           lang("filter.comment")], ["4"])>
-    <list filters as f>    
+    <list filters as f>
         <call SpannedListEntry([
           lang("filtertype."+f.type),
           utility.encodeHTML(f.expression)],
           ["1","3"],
-          "module=Abuse&id="+f.id+"&groupid="+groupid, 
-           ["&do=editfilter", "&do=deletefilter"], 
+          "module=Abuse&id="+f.id+"&groupid="+groupid,
+           ["&do=editfilter", "&do=deletefilter"],
            [lang("edit"), lang("delete")])>
-          <if f.last_hit>\r
+          <if f.lasthit>\r
               <call ListEntry([
                 lang("content.operation."+f.articleaction),
                 lang("comment.operation."+f.commentaction),
                 utility.encodeHTML(f.tag),
-                f.last_hit.format(config["Mir.DefaultDateTimeFormat"], config["Mir.DefaultTimezone"])
-                ], 
-                "module=Abuse&id="+f.id+"&groupid="+groupid, 
-                ["&do=movefilterup", "&do=movefilterdown"], 
+                f.lasthit.format(config["Mir.DefaultDateTimeFormat"], config["Mir.DefaultTimezone"])
+                ],
+                "module=Abuse&id="+f.id+"&groupid="+groupid,
+                ["&do=movefilterup", "&do=movefilterdown"],
                 [lang("filters.moveup"), lang("filters.movedown")])
               >
           <else>
                 lang("comment.operation."+f.commentaction),
                 utility.encodeHTML(f.tag),
                 "-"
-                ], 
-                "module=Abuse&id="+f.id+"&groupid="+groupid, 
-                ["&do=movefilterup", "&do=movefilterdown"], 
+                ],
+                "module=Abuse&id="+f.id+"&groupid="+groupid,
+                ["&do=movefilterup", "&do=movefilterdown"],
                 [lang("filters.moveup"), lang("filters.movedown")])
               >
           </if>
           <call SpannedListEntry([
             utility.prettyEncodeHTML(f.comment)],
             ["4"],
-            "module=Abuse&id="+f.id+"&groupid="+groupid, 
-             ["&do=movefiltertop", "&do=movefilterbottom"], 
+            "module=Abuse&id="+f.id+"&groupid="+groupid,
+             ["&do=movefiltertop", "&do=movefilterbottom"],
              [lang("filters.movetop"), lang("filters.movebottom")])>
         <tr height="2" class="${TABLE_HEAD_CLASS}"><td colspan="6"> </td></tr>
     </list>\r
     <call ListEnd()>\r
-    
+
     <p>
       <a class="link-box" href="${config.actionRoot}?module=Abuse&amp;do=showfiltergroups">[ &lt; ] ${lang("back")}</a>&nbsp;&nbsp;
       <a class="link-box" href="${config.actionRoot}?module=Abuse&amp;groupid=${groupid}&amp;do=addfilter">[+] ${lang("add")}</a> &nbsp;