List targets = new ArrayList();
while (iter.hasNext())
{
Queue queue = (Queue)iter.next();
if (trace) { log.trace(this + " considering queue " + queue); }
if (queue.getNodeID() == thisNodeID)
{
if (trace) { log.trace(this + " is a local queue"); }
//Local queue
boolean routeLocal = false;
if (!fromCluster)
{
//Same node
routeLocal = true;
}
else
{
//From the cluster
if (!queue.isRecoverable() && queue.isClustered())
{
//When routing from the cluster we only route to non recoverable queues
//who haven't already been routed to on the sending node (same name)
//Also we don't route to non clustered queues
if (names == null || !names.contains(queue.getName()))
{
routeLocal = true;
}
}
}
if (routeLocal)
{
//If we're not routing from the cluster OR the queue is unreliable then we consider it
//When we route from the cluster we never route to reliable queues
Filter filter = queue.getFilter();
if (filter == null || filter.accept(ref.getMessage()))
{
if (trace) { log.trace(this + " Added queue " + queue + " to list of targets"); }
targets.add(queue);
if (ref.getMessage().isReliable() && queue.isRecoverable())
{
localReliableCount++;
}
}
}
}
else if (!fromCluster)
{
//Remote queue
if (trace) { log.trace(this + " is a remote queue"); }
if (!queue.isRecoverable() && queue.isClustered())
{
//When we send to the cluster we never send to reliable queues
Filter filter = queue.getFilter();
if (filter == null || filter.accept(ref.getMessage()))
{
if (remoteSet == null)
{
remoteSet = new HashSet();
}
remoteSet.add(new Integer(queue.getNodeID()));
if (trace) { log.trace(this + " added it to the remote set for casting"); }
}
}
else
{
if (trace) { log.trace(this + " is recoverable so not casting"); }
}
}
}
//If the ref is reliable and there is more than one reliable local queue that accepts the message then we need
//to route in a transaction to guarantee once and only once reliability guarantee
boolean startedTx = false;
if (tx == null && localReliableCount > 1)
{
if (trace) { log.trace("Starting internal tx, reliableCount = " + localReliableCount); }
tx = tr.createTransaction();
startedTx = true;
}
//Now actually route the ref
iter = targets.iterator();
Set queueNames = null;
while (iter.hasNext())
{
Queue queue = (Queue)iter.next();
if (trace) { log.trace(this + " Routing ref to queue " + queue); }
Delivery del = queue.handle(null, ref, tx);
if (trace) { log.trace("Queue returned " + del); }
if (del != null && del.isSelectorAccepted())
{
routed = true;
if (remoteSet != null)
{
if (queueNames == null)
{
queueNames = new HashSet();
}
//We put the queue name in a set - this is used on other nodes after routing from the cluster so it
//doesn't route to queues with the same name on other nodes
queueNames.add(queue.getName());
}
}
}
if (remoteSet != null)