Java tutorial
/************************************************************************************** * Copyright (C) 2008 EsperTech, Inc. All rights reserved. * * http://esper.codehaus.org * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * **************************************************************************************/ package com.espertech.esper.filter; import java.util.*; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import com.espertech.esper.client.EventBean; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.Log; /** * This class holds a list of indizes storing filter constants in {@link FilterParamIndexBase} nodes * and a set of {@link FilterHandle}. * An instance of this class represents a leaf-node (no indizes stored, just filter callbacks) * but can also be non-leaf (some indizes exist) in a filter evaluation tree. * Events are evaluated by asking each of the indizes to evaluate the event and by * adding any filter callbacks in this node to the "matches" list of callbacks. */ public final class FilterHandleSetNode implements EventEvaluator { private final Set<FilterHandle> callbackSet; private final List<FilterParamIndexBase> indizes; private final ReadWriteLock nodeRWLock; /** * Constructor. */ public FilterHandleSetNode() { callbackSet = new LinkedHashSet<FilterHandle>(); indizes = new LinkedList<FilterParamIndexBase>(); nodeRWLock = new ReentrantReadWriteLock(); } /** * Returns an indication of whether there are any callbacks or index nodes at all in this set. * NOTE: the client to this method must use the read-write lock of this object to lock, if required by the client * code. * @return true if there are neither indizes nor filter callbacks stored, false if either exist. */ protected boolean isEmpty() { return callbackSet.isEmpty() && indizes.isEmpty(); } /** * Returns the number of filter callbacks stored. * NOTE: the client to this method must use the read-write lock of this object to lock, if required by the client * code. * @return number of filter callbacks stored */ protected int getFilterCallbackCount() { return callbackSet.size(); } /** * Returns to lock to use for making changes to the filter callback or inzides collections stored by this node. * @return lock to use in multithreaded environment */ protected final ReadWriteLock getNodeRWLock() { return nodeRWLock; } /** * Returns list of indexes - not returning an iterator. Client classes should not change this collection. * @return list of indizes */ public List<FilterParamIndexBase> getIndizes() { return indizes; } /** * Evaluate an event by asking each index to match the event. Any filter callbacks at this node automatically * match the event and do not need to be further evaluated, and are thus added to the "matches" list of callbacks. * NOTE: This client should not use the lock before calling this method. * @param theEvent is the event wrapper supplying the event property values * @param matches is the list of callbacks to add to for any matches found */ public final void matchEvent(EventBean theEvent, Collection<FilterHandle> matches) { nodeRWLock.readLock().lock(); try { // Ask each of the indizes to match against the attribute values for (FilterParamIndexBase index : indizes) { index.matchEvent(theEvent, matches); } // Add each filter callback stored in this node to the matching list for (FilterHandle filterCallback : callbackSet) { matches.add(filterCallback); } } finally { nodeRWLock.readLock().unlock(); } } /** * Returns an indication whether the filter callback exists in this node. * NOTE: the client to this method must use the read-write lock of this object to lock, if required by the client * code. * @param filterCallback is the filter callback to check for * @return true if callback found, false if not */ protected boolean contains(FilterHandle filterCallback) { return callbackSet.contains(filterCallback); } /** * Add an index. The same index can be added twice - there is no checking done. * NOTE: the client to this method must use the read-write lock of this object to lock, if required by the client * code. * @param index - index to add */ protected final void add(FilterParamIndexBase index) { indizes.add(index); } /** * Remove an index, returning true if it was found and removed or false if not in collection. * NOTE: the client to this method must use the read-write lock of this object to lock, if required by the client * code. * @param index is the index to remove * @return true if found, false if not existing */ protected final boolean remove(FilterParamIndexBase index) { return indizes.remove(index); } /** * Add a filter callback. The filter callback set allows adding the same callback twice with no effect. * If a client to the class needs to check that the callback already existed, the contains method does that. * NOTE: the client to this method must use the read-write lock of this object to lock, if required by the client * code. * @param filterCallback is the callback to add */ protected final void add(FilterHandle filterCallback) { callbackSet.add(filterCallback); } /** * Remove a filter callback, returning true if it was found and removed or false if not in collection. * NOTE: the client to this method must use the read-write lock of this object to lock, if required by the client * code. * @param filterCallback is the callback to remove * @return true if found, false if not existing */ protected final boolean remove(FilterHandle filterCallback) { return callbackSet.remove(filterCallback); } private static final Log log = LogFactory.getLog(FilterHandleSetNode.class); }