X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=source%2Fmircoders%2Fabuse%2FFilterEngine.java;fp=source%2Fmircoders%2Fabuse%2FFilterEngine.java;h=73da851370611ad34808b9ab5c80530100b9d5e0;hb=c9ac8fa71b679f8d967aac901bbef945c13b94c9;hp=0000000000000000000000000000000000000000;hpb=d63595f89aaa4b6a524dc0b4af9e0eef888f4c6b;p=mir.git diff --git a/source/mircoders/abuse/FilterEngine.java b/source/mircoders/abuse/FilterEngine.java new file mode 100755 index 00000000..73da8513 --- /dev/null +++ b/source/mircoders/abuse/FilterEngine.java @@ -0,0 +1,605 @@ +/* + * 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.abuse; + +import mir.entity.Entity; +import mir.entity.adapter.EntityAdapter; +import mir.entity.adapter.EntityAdapterModel; +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.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 final Map filterTypes = new HashMap(); + private final List filterTypeIds = new ArrayList(); + + private final List filterGroups = new ArrayList(); + private final Map idToFilterGroup = new HashMap(); + private final LoggerWrapper logger = new LoggerWrapper("Global.Abuse.FilterEngine"); + private EntityAdapterModel model; + + public FilterEngine(EntityAdapterModel aModel) { + try { + Iterator i = MirGlobal.localizer().openPostings().getAntiAbuseFilterTypes().iterator(); + while (i.hasNext()) { + FilterType filterType = (FilterType) i.next(); + + filterTypes.put(filterType.getName(), filterType); + filterTypeIds.add(filterType.getName()); + } + } + catch (Throwable t) { + throw new RuntimeException(t.getMessage()); + } + + model = aModel; + + 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 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(); + try { + if (filter.test(anEntity, aRequest)) { + return filter; + } + } + catch (Throwable t) { + logger.warn("Exception thrown while testing filter " + filter.getType() + " ( " + filter.getExpression() + ") " + t.toString()); + } + } + } + + return null; + } + + public List getFilterTypes() { + try { + List result = new ArrayList(); + + Iterator i = filterTypeIds.iterator(); + while (i.hasNext()) { + String id = (String) i.next(); + + Map action = new HashMap(); + action.put("resource", id); + action.put("identifier", id); + + result.add(action); + } + + return result; + } + catch (Throwable t) { + throw new RuntimeException("can't get article actions: " + t.getMessage()); + } + } + /** This class reflects a row of the filter_group + * database table. Filters groups allow you to organize + * your filters. For example: group1=spammer , + * group2=nazis etc. + */ + public class FilterGroup { + private List filters; + private Entity entity; + private Map idToFilter; + + public FilterGroup(Entity anEntity) { + this (anEntity, Collections.EMPTY_LIST); + } + + public FilterGroup(Entity anEntity, List aFilters) { + entity = anEntity; + filters = new ArrayList(); + idToFilter = new HashMap(); + Iterator i = aFilters.iterator(); + + while (i.hasNext()) { + Entity entity = (Entity) i.next(); + try { + Filter filter = new Filter(entity); + introduceFilter(filter); + } + catch (AbuseExc e) { + } + } + } + + public Entity getEntity() { + return entity; + } + + public EntityAdapter getEntityAdapter() { + return model.makeEntityAdapter("filterGroup", entity); + } + + public List getFilterEntityAdapterList() { + List result = new ArrayList(); + + Iterator i = filters.iterator(); + while (i.hasNext()) { + Filter filter = (Filter) i.next(); + result.add(filter.getEntityAdapter()); + } + + return result; + } + + public List getFilters() { + return filters; + } + + public Filter getFilterForId(String anId) { + Filter result = (Filter) idToFilter.get(anId); + if (result==null) { + throw new NullPointerException("No such filter"); + } + + return result; + } + + private void introduceFilter(Filter aFilter) { + filters.add(aFilter); + idToFilter.put(aFilter.getEntity().getId(), aFilter); + } + + private void removeFilter(Filter aFilter) { + filters.remove(aFilter); + idToFilter.remove(aFilter.getEntity().getId()); + } + + private void deleteFilter(String anId) { + Filter filter = getFilterForId(anId); + removeFilter(filter); + DatabaseFilter.getInstance().delete(anId); + } + + public void populateFilterEntity(Entity anEntity, String aType, String anExpression, + String aComments, String aTag, String anArticleAction, + String aCommentAction) { + + anEntity.setFieldValue("type", aType); + anEntity.setFieldValue("expression", anExpression); + anEntity.setFieldValue("comment", aComments); + anEntity.setFieldValue("tag", aTag); + anEntity.setFieldValue("articleaction", anArticleAction); + anEntity.setFieldValue("commentaction", aCommentAction); + } + + public String updateFilter(String anId, String aType, String anExpression, + String aComments, String aTag, String anArticleAction, + String aCommentAction) { + + try { + getFilterTypeForId(aType).constructFilterInstance(anExpression); + } + catch (AbuseExc e) { + return e.getMessage(); + } + + Entity entity = getFilterForId(anId).getEntity(); + populateFilterEntity(entity, aType, anExpression, aComments, aTag, + anArticleAction, aCommentAction); + entity.update(); + + return ""; + } + + public String createFilter(String aType, String anExpression, + String aComments, String aTag, String anArticleAction, + String aCommentAction) throws DatabaseExc { + FilterInstance instance; + + try { + instance = getFilterTypeForId(aType).constructFilterInstance(anExpression); + } + catch (AbuseExc e) { + return e.getMessage(); + } + + Entity entity = DatabaseFilter.getInstance().createNewEntity(); + populateFilterEntity(entity, aType, anExpression, aComments, aTag, + anArticleAction, aCommentAction); + + + 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(); + + Filter filter = new Filter(entity, instance); + introduceFilter(filter); + + 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=0 && index 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