/* * Rapid Beans Framework: Filter.java * * Copyright (C) 2009 Martin Bluemel * * Creation Date: 11/24/2007 * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software Foundation; * either version 3 of the License, or (at your option) any later version. * This program 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 Lesser General Public License for more details. * You should have received a copies of the GNU Lesser General Public License and the * GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>. */ package org.rapidbeans.datasource; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import org.rapidbeans.core.basic.PropertyCollection; import org.rapidbeans.core.basic.RapidBean; import org.rapidbeans.core.exception.RapidBeansRuntimeException; import org.rapidbeans.core.type.TypePropertyCollection; import org.rapidbeans.core.type.TypeRapidBean; import org.rapidbeans.datasource.query.Query; import org.rapidbeans.datasource.query.QueryExprConditionType; /** * A Filter defines a set of filter rules applied to a set of beans. You apply * this filter to a document and then simply query if a bean is included. * * @author Martin Bluemel */ public class Filter { /** * The document to filter. */ private Document document = null; /** * the include rules. */ private ArrayList<Query> includesRules = new ArrayList<Query>(); /** * the include rules. */ private ArrayList<Query> excludesRules = new ArrayList<Query>(); /** * contains references to all filtered beans. */ private IdMap idMap = new IdMap(); /** * contains references to all filtered types. */ private HashMap<String, TypeRapidBean> typeMap = new HashMap<String, TypeRapidBean>(); /** * test if a bean applies to the filter. * * @param bean * the bean to test * * @return if the bean applies */ public boolean applies(final RapidBean bean) { if (this.document == null) { throw new RapidBeansRuntimeException("Filter not correctly initialized"); } return this.idMap.contains(bean.getType().getName(), bean.getIdString()); } /** * test if a bean type applies to the filter. * * @param type * the type to test * * @return if the bean applies */ public boolean applies(final TypeRapidBean type) { if (this.document == null) { throw new RapidBeansRuntimeException("Filter not correctly initialized"); } return this.typeMap.get(type.getName()) != null; } /** * Add an "includes" rule to the filter * * @param includesRule * a query that describes the objects to include */ public void addIncludes(final String includesRule) { this.includesRules.add(new Query(includesRule)); } /** * Add an "excludes" rule to the filter * * @param excludesRule * a query that describes the objects to exclude */ public void addExcludes(final String excludesRule) { this.excludesRules.add(new Query(excludesRule)); } /** * applies the given filter to the filter document. * * @param doc * the document to filter */ public void setDocument(final Document doc) { this.document = doc; this.idMap = new IdMap(); if (this.includesRules != null && this.includesRules.size() > 0) { for (final Query includesRule : this.includesRules) { if (includesRule.getQueryExpressionTreeRoot() instanceof QueryExprConditionType) { final String typename = ((QueryExprConditionType) includesRule.getQueryExpressionTreeRoot()) .getTypename(); if (this.typeMap.get(typename) == null) { this.typeMap.put(typename, TypeRapidBean.forName(typename)); } } for (final RapidBean bean : doc.findBeansByQuery(includesRule)) { if (this.idMap.findBean(bean.getType().getName(), bean.getIdString()) == null) { this.idMap.insert(bean); RapidBean parentBean = bean.getParentBean(); while (parentBean != null && this.idMap.findBean(parentBean.getType().getName(), parentBean.getIdString()) == null) { this.idMap.insert(parentBean); parentBean = parentBean.getParentBean(); } } } } } else { // take all beans of the document for (final String typename : doc.findAllTypenames()) { final TypeRapidBean rbtype = TypeRapidBean.forName(typename); this.typeMap.put(typename, rbtype); for (final RapidBean bean : doc.findBeansByType(typename)) { this.idMap.insert(bean); } } } for (final Query excludesRule : this.excludesRules) { for (final RapidBean bean : doc.findBeansByQuery(excludesRule)) { if (this.idMap.findBean(bean.getType().getName(), bean.getIdString()) != null) { deleteWithChildsFromIdMap(bean); } } if (excludesRule.getQueryExpressionTreeRoot() instanceof QueryExprConditionType) { final String typename = ((QueryExprConditionType) excludesRule.getQueryExpressionTreeRoot()) .getTypename(); if (this.typeMap.get(typename) != null && this.idMap.findAllIds(typename).size() == 0) { this.typeMap.remove(typename); } } } } @SuppressWarnings("unchecked") private void deleteWithChildsFromIdMap(final RapidBean bean) { this.idMap.delete(bean); for (PropertyCollection colProp : bean.getColProperties()) { final Collection<RapidBean> col = (Collection<RapidBean>) colProp.getValue(); if (col == null) { continue; } final TypePropertyCollection colPropType = (TypePropertyCollection) colProp.getType(); if (colPropType.isComposition()) { for (RapidBean bean1 : col) { deleteWithChildsFromIdMap(bean1); } } } } }