better logging for the filter engine
[mir.git] / source / mircoders / abuse / FilterEngine.java
index 1f6cc42..73da851 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,17 +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.  
+   *  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();
@@ -127,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 
@@ -256,7 +254,21 @@ public class FilterEngine {
       Entity entity = DatabaseFilter.getInstance().createNewEntity();
       populateFilterEntity(entity, aType, anExpression, aComments, aTag,
           anArticleAction, aCommentAction);
-      entity.setFieldValue("priority", "1");
+
+
+      String priority = "1";
+
+      if (filters.size() > 0) {
+        try {
+          String lastPriorityString = ((Filter) filters.get(filters.size()-1)).getEntity().getFieldValue("priority");
+          int lastPriority = Integer.parseInt(lastPriorityString);
+          priority = Integer.toString(lastPriority + 1);
+        }
+        catch (Exception e) {
+        }
+      }
+
+      entity.setFieldValue("priority", priority);
       entity.setFieldValue("filter_group_id", getEntity().getId());
       entity.insert();
 
@@ -266,10 +278,78 @@ public class FilterEngine {
       return "";
     }
 
+    public String moveFilterUp(String anId) {
+      Filter filter = getFilterForId(anId);
+      String priority = filter.getEntity().getFieldValue("priority");
+      int index = filters.indexOf(filter);
+      if (index>=1) {
+        Filter filterBefore= (Filter) filters.remove(index-1);
+        filters.add(index, filterBefore);
+        filter.getEntity().setFieldValue("priority", filterBefore.getEntity().getFieldValue("priority"));
+        filterBefore.getEntity().setFieldValue("priority", priority);
+        filter.getEntity().update();
+        filterBefore.getEntity().update();
+      }
+
+      return "";
+    }
+
+    public String moveFilterToTop(String anId) {
+      Filter filter = getFilterForId(anId);
+      String priority = filter.getEntity().getFieldValue("priority");
+      int index = filters.indexOf(filter);
+      if (index>0) {
+        filters.remove(index);
+        Filter filterBefore= (Filter) filters.get(0);
+        filters.add(0, filter);
+        filter.getEntity().setFieldValue("priority", filterBefore.getEntity().getFieldValue("priority"));
+        filterBefore.getEntity().setFieldValue("priority", priority);
+        filter.getEntity().update();
+        filterBefore.getEntity().update();
+      }
+
+      return "";
+    }
+
+    public String moveFilterDown(String anId) {
+      Filter filter = getFilterForId(anId);
+      String priority = filter.getEntity().getFieldValue("priority");
+      int index = filters.indexOf(filter);
+      if (index<filters.size()-1) {
+        Filter filterAfter = (Filter) filters.remove(index+1);
+        filters.add(index, filterAfter);
+        filter.getEntity().setFieldValue("priority", filterAfter.getEntity().getFieldValue("priority"));
+        filterAfter.getEntity().setFieldValue("priority", priority);
+        filter.getEntity().update();
+        filterAfter.getEntity().update();
+      }
+
+      return "";
+    }
+
+    public String moveFilterToBottom(String anId) {
+      Filter filter = getFilterForId(anId);
+      String priority = filter.getEntity().getFieldValue("priority");
+      int index = filters.indexOf(filter);
+      if (index>=0 && index<filters.size()-1) {
+        filters.remove(index);
+        Filter filterBefore= (Filter) filters.get(filters.size()-1);
+        filters.add(filters.size(), filter);
+        filter.getEntity().setFieldValue("priority", filterBefore.getEntity().getFieldValue("priority"));
+        filterBefore.getEntity().setFieldValue("priority", priority);
+        filter.getEntity().update();
+        filterBefore.getEntity().update();
+      }
+
+      return "";
+    }
+
+
     public String getName() {
       return entity.getFieldValue("name");
     }
   }
+  
   /** This class reflects a row of the filter database table. 
    * To actually run a filter on data, use the test() method. 
    * This class will automatically retreive and use the correct 
@@ -312,7 +392,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();
     }
 
@@ -358,7 +440,7 @@ public class FilterEngine {
       while (i.hasNext()) {
         EntityAdapter entityAdapter = (EntityAdapter) i.next();
         List filters = new ArrayList();
-        Iterator j = (Iterator) entityAdapter.get("to_filters");
+        Iterator j = (Iterator) entityAdapter.getIterator("to_filters");
         while (j.hasNext()) {
           filters.add(((EntityAdapter) j.next()).getEntity());
         }
@@ -368,7 +450,7 @@ public class FilterEngine {
       }
     }
     catch (Throwable e) {
-      logger.error("Can't load filters: " + e.getMessage());
+      logger.error("Can't load filters: " + e.getMessage(), e);
     }
   }
 
@@ -391,13 +473,53 @@ public class FilterEngine {
   public synchronized void addFilterGroup(String aName) throws DatabaseExc {
     Entity entity = DatabaseFilterGroup.getInstance().createNewEntity();
     entity.setFieldValue("name", aName);
-    entity.setFieldValue("priority", "1");
+
+    String priority = "1";
+
+    if (filterGroups.size() > 0) {
+      try {
+        String lastPriorityString = ((FilterGroup) filterGroups.get(filterGroups.size()-1)).getEntity().getFieldValue("priority");
+        int lastPriority = Integer.parseInt(lastPriorityString);
+        priority = Integer.toString(lastPriority + 1);
+      }
+      catch (Exception e) {
+      }
+    }
+    entity.setFieldValue("priority", priority);
     entity.insert();
 
     FilterGroup filterGroup = new FilterGroup(entity);
     introduceFilterGroup(filterGroup);
   }
 
+  public synchronized void moveFilterGroupUp(String anId) {
+    FilterGroup group = (FilterGroup) idToFilterGroup.get(anId);
+    String priority = group.getEntity().getFieldValue("priority");
+    int index = filterGroups.indexOf(group);
+    if (index>=1) {
+      FilterGroup groupBefore = (FilterGroup) filterGroups.remove(index-1);
+      filterGroups.add(index, groupBefore);
+      group.getEntity().setFieldValue("priority", groupBefore.getEntity().getFieldValue("priority"));
+      groupBefore.getEntity().setFieldValue("priority", priority);
+      group.getEntity().update();
+      groupBefore.getEntity().update();
+    }
+  }
+
+  public synchronized void moveFilterGroupDown(String anId) {
+    FilterGroup group = (FilterGroup) idToFilterGroup.get(anId);
+    String priority = group.getEntity().getFieldValue("priority");
+    int index = filterGroups.indexOf(group);
+    if (index<filterGroups.size()-1) {
+      FilterGroup groupAfter = (FilterGroup) filterGroups.remove(index+1);
+      filterGroups.add(index, groupAfter);
+      group.getEntity().setFieldValue("priority", groupAfter.getEntity().getFieldValue("priority"));
+      groupAfter.getEntity().setFieldValue("priority", priority);
+      group.getEntity().update();
+      groupAfter.getEntity().update();
+    }
+  }
+
   public synchronized void deleteFilterGroup(String anId) {
 
     FilterGroup filterGroup = getFilterGroupForId(anId);
@@ -431,6 +553,23 @@ public class FilterEngine {
         aComments, aTag, anArticleAction, aCommentAction);
   }
 
+  public synchronized String moveFilterUp(String aGroupId, String anId) {
+    return getFilterGroupForId(aGroupId).moveFilterUp(anId);
+  }
+
+  public synchronized String moveFilterDown(String aGroupId, String anId) {
+    return getFilterGroupForId(aGroupId).moveFilterDown(anId);
+  }
+
+  public synchronized String moveFilterToTop(String aGroupId, String anId) {
+    return getFilterGroupForId(aGroupId).moveFilterToTop(anId);
+  }
+
+  public synchronized String moveFilterToBottom(String aGroupId, String anId) {
+    return getFilterGroupForId(aGroupId).moveFilterToBottom(anId);
+  }
+
+
 
   public FilterGroup getFilterGroupForId(String anId) {
     FilterGroup result = (FilterGroup) idToFilterGroup.get(anId);
@@ -450,12 +589,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());
   }