throws AmqpErrorException
{
_vhost = vhost;
_destination = destination;
_linkAttachment = linkAttachment;
final Source source = (Source) linkAttachment.getSource();
_durability = source.getDurable();
linkAttachment.setDeliveryStateHandler(this);
QueueDestination qd = null;
AMQQueue queue = null;
boolean noLocal = false;
JMSSelectorFilter messageFilter = null;
if(destination instanceof QueueDestination)
{
queue = ((QueueDestination) _destination).getQueue();
if(queue.getAvailableAttributes().contains("topic"))
{
source.setDistributionMode(StdDistMode.COPY);
}
qd = (QueueDestination) destination;
Map<Symbol,Filter> filters = source.getFilter();
Map<Symbol,Filter> actualFilters = new HashMap<Symbol,Filter>();
if(filters != null)
{
for(Map.Entry<Symbol,Filter> entry : filters.entrySet())
{
if(entry.getValue() instanceof NoLocalFilter)
{
actualFilters.put(entry.getKey(), entry.getValue());
noLocal = true;
}
else if(messageFilter == null && entry.getValue() instanceof org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter)
{
org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter selectorFilter = (org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter) entry.getValue();
try
{
messageFilter = new JMSSelectorFilter(selectorFilter.getValue());
actualFilters.put(entry.getKey(), entry.getValue());
}
catch (ParseException e)
{
Error error = new Error();
error.setCondition(AmqpError.INVALID_FIELD);
error.setDescription("Invalid JMS Selector: " + selectorFilter.getValue());
error.setInfo(Collections.singletonMap(Symbol.valueOf("field"), Symbol.valueOf("filter")));
throw new AmqpErrorException(error);
}
catch (SelectorParsingException e)
{
Error error = new Error();
error.setCondition(AmqpError.INVALID_FIELD);
error.setDescription("Invalid JMS Selector: " + selectorFilter.getValue());
error.setInfo(Collections.singletonMap(Symbol.valueOf("field"), Symbol.valueOf("filter")));
throw new AmqpErrorException(error);
}
}
}
}
source.setFilter(actualFilters.isEmpty() ? null : actualFilters);
_subscription = new Subscription_1_0(this, qd, source.getDistributionMode() != StdDistMode.COPY);
}
else if(destination instanceof ExchangeDestination)
{
try
{
ExchangeDestination exchangeDestination = (ExchangeDestination) destination;
boolean isDurable = exchangeDestination.getDurability() == TerminusDurability.CONFIGURATION
|| exchangeDestination.getDurability() == TerminusDurability.UNSETTLED_STATE;
String name;
if(isDurable)
{
String remoteContainerId = getEndpoint().getSession().getConnection().getRemoteContainerId();
remoteContainerId = remoteContainerId.replace("_","__").replace(".", "_:");
String endpointName = linkAttachment.getEndpoint().getName();
endpointName = endpointName
.replace("_", "__")
.replace(".", "_:")
.replace("(", "_O")
.replace(")", "_C")
.replace("<", "_L")
.replace(">", "_R");
name = "qpid_/" + remoteContainerId + "_/" + endpointName;
}
else
{
name = UUID.randomUUID().toString();
}
queue = _vhost.getQueue(name);
Exchange exchange = exchangeDestination.getExchange();
if(queue == null)
{
queue = _vhost.createQueue(
UUIDGenerator.generateQueueUUID(name, _vhost.getName()),
name,
isDurable,
null,
true,
true,
true,
Collections.EMPTY_MAP);
}
else
{
List<Binding> bindings = queue.getBindings();
List<Binding> bindingsToRemove = new ArrayList<Binding>();
for(Binding existingBinding : bindings)
{
if(existingBinding.getExchange() != _vhost.getDefaultExchange()
&& existingBinding.getExchange() != exchange)
{
bindingsToRemove.add(existingBinding);
}
}
for(Binding existingBinding : bindingsToRemove)
{
existingBinding.getExchange().removeBinding(existingBinding);
}
}
String binding = "";
Map<Symbol,Filter> filters = source.getFilter();
Map<Symbol,Filter> actualFilters = new HashMap<Symbol,Filter>();
boolean hasBindingFilter = false;
if(filters != null && !filters.isEmpty())
{
for(Map.Entry<Symbol,Filter> entry : filters.entrySet())
{
if(!hasBindingFilter
&& entry.getValue() instanceof ExactSubjectFilter
&& exchange.getType() == DirectExchange.TYPE)
{
ExactSubjectFilter filter = (ExactSubjectFilter) filters.values().iterator().next();
source.setFilter(filters);
binding = filter.getValue();
actualFilters.put(entry.getKey(), entry.getValue());
hasBindingFilter = true;
}
else if(!hasBindingFilter
&& entry.getValue() instanceof MatchingSubjectFilter
&& exchange.getType() == TopicExchange.TYPE)
{
MatchingSubjectFilter filter = (MatchingSubjectFilter) filters.values().iterator().next();
source.setFilter(filters);
binding = filter.getValue();
actualFilters.put(entry.getKey(), entry.getValue());
hasBindingFilter = true;
}
else if(entry.getValue() instanceof NoLocalFilter)
{
actualFilters.put(entry.getKey(), entry.getValue());
noLocal = true;
}
else if(messageFilter == null && entry.getValue() instanceof org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter)
{
org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter selectorFilter = (org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter) entry.getValue();
try
{
messageFilter = new JMSSelectorFilter(selectorFilter.getValue());
actualFilters.put(entry.getKey(), entry.getValue());
}
catch (ParseException e)
{
Error error = new Error();
error.setCondition(AmqpError.INVALID_FIELD);
error.setDescription("Invalid JMS Selector: " + selectorFilter.getValue());
error.setInfo(Collections.singletonMap(Symbol.valueOf("field"), Symbol.valueOf("filter")));
throw new AmqpErrorException(error);
}
catch (SelectorParsingException e)
{
Error error = new Error();
error.setCondition(AmqpError.INVALID_FIELD);
error.setDescription("Invalid JMS Selector: " + selectorFilter.getValue());
error.setInfo(Collections.singletonMap(Symbol.valueOf("field"), Symbol.valueOf("filter")));
throw new AmqpErrorException(error);
}
}
}
}
source.setFilter(actualFilters.isEmpty() ? null : actualFilters);
exchange.addBinding(binding,queue,null);
source.setDistributionMode(StdDistMode.COPY);
if(!isDurable)
{
final String queueName = name;
final AMQQueue tempQueue = queue;