package org.jacorb.notification.engine;
/*
* JacORB - a free Java ORB
*
* Copyright (C) 1999-2014 Gerald Brose / The JacORB Team.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
import org.omg.CORBA.AnyHolder;
import org.omg.CosNotifyFilter.UnsupportedFilterableData;
/**
* @author Alphonse Bendt
*/
public class FilterProxyConsumerTask extends AbstractFilterTask
{
private static int sCount = 0;
private final int id_ = ++sCount;
private boolean orSemantic_ = false;
// //////////////////
public FilterProxyConsumerTask(TaskFactory factory, TaskExecutor executor)
{
super(factory, executor);
}
// //////////////////
public String toString()
{
return "[FilterProxyConsumerTask#" + id_ + "]";
}
public void reset()
{
super.reset();
orSemantic_ = false;
}
/**
* access the Filter hint for next Stage. if the current FilterStage has
* InterFilterGroupOperator.OR_OP enabled and a filter matched the evaluation of the
* SupplierAdmin Filters can be skipped.
*/
public boolean getSkip()
{
return orSemantic_;
}
/**
* match the attached Priority MappingFilter. the current Message is matched to the
* MappingFilter attached to the current FilterStage. In case of successful match operation the
* priority of the Messages is updated accordingly.
*/
private void updatePriority()
{
try
{
AnyHolder newPriority = new AnyHolder();
boolean priorityMatch = getMessage().match(
arrayCurrentFilterStage_[0].getPriorityFilter(), newPriority);
if (priorityMatch)
{
getMessage().setPriority(newPriority.value.extract_long());
}
} catch (UnsupportedFilterableData e)
{
logger_.error("Error evaluating PriorityFilter", e);
}
}
/**
* match the attached Lifetime MappingFilter. the current Message is matched to the
* MappingFilter attached to the current FilterStage. In case of successful match operation the
* lifetime of the Messages is updated accordingly.
*/
private void updateLifetime()
{
try
{
AnyHolder newLifetime = new AnyHolder();
boolean lifetimeMatch = getMessage().match(
arrayCurrentFilterStage_[0].getLifetimeFilter(), newLifetime);
if (lifetimeMatch)
{
getMessage().setTimeout(newLifetime.value.extract_long());
}
} catch (UnsupportedFilterableData e)
{
logger_.error("Error evaluating LifetimeFilter", e);
}
}
public void doFilter() throws InterruptedException
{
if (arrayCurrentFilterStage_[0].hasPriorityFilter())
{
updatePriority();
}
if (arrayCurrentFilterStage_[0].hasLifetimeFilter())
{
updateLifetime();
}
boolean _filterMatch = filter();
if (!_filterMatch && arrayCurrentFilterStage_[0].hasInterFilterGroupOperatorOR())
{
if (logger_.isDebugEnabled())
{
logger_.debug("filter failed, but the ProxyConsumer" + arrayCurrentFilterStage_[0]
+ " has InterFilterGroupOperator OR_OP Enabled");
}
// no filter attached to the current ProxyConsumer
// matched. However the ProxyConsumer has
// InterFilterGroupOperator.OR_OP enabled. Therefor we
// have to continue processing because the Filters
// attached to the SupplierAdmin still may match.
addFilterStage(arrayCurrentFilterStage_[0].getSubsequentFilterStages());
}
if (!isFilterStageListEmpty())
{
getTaskFactory().newFilterSupplierAdminTask(this).schedule();
}
}
private boolean filter()
{
boolean _forward = false;
// eval attached filters
// as an Event passes only 1 ProxyConsumer we can assume
// constant array size here
_forward = getMessage().match(arrayCurrentFilterStage_[0]);
if (_forward)
{
addFilterStage(arrayCurrentFilterStage_[0].getSubsequentFilterStages());
}
// check if this destination has OR enabled
// if this is the case the filtering in the next run can be skipped
if (arrayCurrentFilterStage_[0].hasInterFilterGroupOperatorOR())
{
orSemantic_ = true;
}
return _forward;
}
public void schedule()
{
// directRunAllowed is false here
// cause the calling thread is usually created by the ORB.
// exceptions are PullSuppliers.
schedule(false);
}
}