[ARTEMIS-1890] Fix any-word wildcard matching in AddressImpl to match zero words
This commit is contained in:
parent
545b82fbd7
commit
0ea84ef9ff
|
@ -24,10 +24,12 @@ import org.apache.activemq.artemis.core.config.WildcardConfiguration;
|
||||||
import org.apache.activemq.artemis.core.postoffice.Address;
|
import org.apache.activemq.artemis.core.postoffice.Address;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* splits an address string into its hierarchical parts split by '.'
|
* Splits an address string into its hierarchical parts using {@link WildcardConfiguration#getDelimiter()} as delimiter.
|
||||||
*/
|
*/
|
||||||
public class AddressImpl implements Address {
|
public class AddressImpl implements Address {
|
||||||
|
|
||||||
|
private static final WildcardConfiguration DEFAULT_WILDCARD_CONFIGURATION = new WildcardConfiguration();
|
||||||
|
|
||||||
private final SimpleString address;
|
private final SimpleString address;
|
||||||
|
|
||||||
private final SimpleString[] addressParts;
|
private final SimpleString[] addressParts;
|
||||||
|
@ -39,10 +41,10 @@ public class AddressImpl implements Address {
|
||||||
private final WildcardConfiguration wildcardConfiguration;
|
private final WildcardConfiguration wildcardConfiguration;
|
||||||
|
|
||||||
public AddressImpl(final SimpleString address) {
|
public AddressImpl(final SimpleString address) {
|
||||||
this(address, new WildcardConfiguration());
|
this(address, DEFAULT_WILDCARD_CONFIGURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddressImpl(final SimpleString address, WildcardConfiguration wildcardConfiguration) {
|
public AddressImpl(final SimpleString address, final WildcardConfiguration wildcardConfiguration) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.wildcardConfiguration = wildcardConfiguration;
|
this.wildcardConfiguration = wildcardConfiguration;
|
||||||
addressParts = address.split(wildcardConfiguration.getDelimiter());
|
addressParts = address.split(wildcardConfiguration.getDelimiter());
|
||||||
|
@ -81,76 +83,113 @@ public class AddressImpl implements Address {
|
||||||
linkedAddresses.remove(actualAddress);
|
linkedAddresses.remove(actualAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should actually be called `isMatchedBy`.
|
||||||
|
*
|
||||||
|
* @return `true` if this equals otherAddr or this address is matched by a pattern represented by otherAddr
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(final Address add) {
|
public boolean matches(final Address otherAddr) {
|
||||||
if (containsWildCard == add.containsWildCard()) {
|
if (otherAddr == null)
|
||||||
return address.equals(add.getAddress());
|
|
||||||
}
|
|
||||||
int pos = 0;
|
|
||||||
int matchPos = 0;
|
|
||||||
|
|
||||||
SimpleString nextToMatch;
|
|
||||||
for (; matchPos < add.getAddressParts().length; ) {
|
|
||||||
if (pos >= addressParts.length) {
|
|
||||||
// test for # as last address part
|
|
||||||
return pos + 1 == add.getAddressParts().length && add.getAddressParts()[pos].equals(new SimpleString(wildcardConfiguration.getAnyWords()));
|
|
||||||
}
|
|
||||||
SimpleString curr = addressParts[pos];
|
|
||||||
SimpleString next = addressParts.length > pos + 1 ? addressParts[pos + 1] : null;
|
|
||||||
SimpleString currMatch = add.getAddressParts()[matchPos];
|
|
||||||
if (currMatch.equals(new SimpleString(wildcardConfiguration.getSingleWord()))) {
|
|
||||||
pos++;
|
|
||||||
matchPos++;
|
|
||||||
} else if (currMatch.equals(new SimpleString(wildcardConfiguration.getAnyWords()))) {
|
|
||||||
if (matchPos == addressParts.length - 1) {
|
|
||||||
pos++;
|
|
||||||
matchPos++;
|
|
||||||
} else if (next == null) {
|
|
||||||
return false;
|
return false;
|
||||||
} else if (matchPos == add.getAddressParts().length - 1) {
|
|
||||||
|
if (address.equals(otherAddr.getAddress()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
final char sepAnyWords = wildcardConfiguration.getAnyWords();
|
||||||
|
final char sepSingleWord = wildcardConfiguration.getSingleWord();
|
||||||
|
|
||||||
|
final int thisAddrPartsLen = addressParts.length;
|
||||||
|
final int thisAddrPartsLastIdx = thisAddrPartsLen - 1;
|
||||||
|
|
||||||
|
final SimpleString[] otherAddrParts = otherAddr.getAddressParts();
|
||||||
|
final int otherAddrPartsLen = otherAddrParts.length;
|
||||||
|
final int otherAddrPartsLastIdx = otherAddrPartsLen - 1;
|
||||||
|
|
||||||
|
int thisIdx = 0;
|
||||||
|
int otherIdx = 0;
|
||||||
|
|
||||||
|
// iterate through all parts of otherAddr
|
||||||
|
while (otherIdx < otherAddrPartsLen) {
|
||||||
|
|
||||||
|
// check if we already tested the last part of this address
|
||||||
|
if (thisIdx > thisAddrPartsLastIdx) {
|
||||||
|
// check if last part of otherAddr is the any-words wildcard and report a match if so
|
||||||
|
if (otherIdx == otherAddrPartsLastIdx) {
|
||||||
|
final SimpleString otherAddrLastPart = otherAddrParts[otherAddrPartsLastIdx];
|
||||||
|
return otherAddrLastPart.length() > 0 && otherAddrLastPart.charAt(0) == sepAnyWords;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleString thisCurr = addressParts[thisIdx];
|
||||||
|
final SimpleString otherCurr = otherAddrParts[otherIdx];
|
||||||
|
final boolean otherCurrPartIsSingleChar = otherCurr.length() == 1;
|
||||||
|
|
||||||
|
// handle single-word wildcard found in otherAddr
|
||||||
|
if (otherCurrPartIsSingleChar && otherCurr.charAt(0) == sepSingleWord) {
|
||||||
|
thisIdx++;
|
||||||
|
otherIdx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle any-words wildcard found in otherAddr
|
||||||
|
if (otherCurrPartIsSingleChar && otherCurr.charAt(0) == sepAnyWords) {
|
||||||
|
|
||||||
|
// if last part of otherAddr is any-words wildcard report a match
|
||||||
|
if (otherIdx == otherAddrPartsLastIdx)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
SimpleString thisNext;
|
||||||
|
// check if this address has more parts to check
|
||||||
|
if (thisIdx < thisAddrPartsLastIdx) {
|
||||||
|
thisNext = addressParts[thisIdx + 1];
|
||||||
} else {
|
} else {
|
||||||
nextToMatch = add.getAddressParts()[matchPos + 1];
|
// no more parts to check, thus check the current part against the next part of otherAddr
|
||||||
while (curr != null) {
|
thisNext = thisCurr;
|
||||||
if (curr.equals(nextToMatch)) {
|
}
|
||||||
|
|
||||||
|
final SimpleString otherNext = otherAddrParts[otherIdx + 1];
|
||||||
|
// iterate through the remaining parts of this address until the part after the any-words wildcard of otherAddr is matched
|
||||||
|
while (thisCurr != null) {
|
||||||
|
if (thisCurr.equals(otherNext)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pos++;
|
thisIdx++;
|
||||||
curr = next;
|
thisCurr = thisNext;
|
||||||
next = addressParts.length > pos + 1 ? addressParts[pos + 1] : null;
|
thisNext = thisAddrPartsLastIdx > thisIdx ? addressParts[thisIdx + 1] : null;
|
||||||
}
|
}
|
||||||
if (curr == null) {
|
// if no further part in this address matched the next part in otherAddr report a mismatch
|
||||||
|
if (thisCurr == null)
|
||||||
return false;
|
return false;
|
||||||
|
otherIdx++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
matchPos++;
|
|
||||||
}
|
// compare current parts of bothaddresses and report mismatch if they differ
|
||||||
} else {
|
if (!thisCurr.equals(otherCurr))
|
||||||
if (!curr.equals(currMatch)) {
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
thisIdx++;
|
||||||
|
otherIdx++;
|
||||||
}
|
}
|
||||||
pos++;
|
|
||||||
matchPos++;
|
// report match if all parts of this address were checked
|
||||||
}
|
return thisIdx == thisAddrPartsLen;
|
||||||
}
|
|
||||||
return pos == addressParts.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o) {
|
public boolean equals(final Object o) {
|
||||||
if (this == o) {
|
if (this == o)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
if (o == null || getClass() != o.getClass())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
AddressImpl address1 = (AddressImpl) o;
|
|
||||||
|
|
||||||
if (!address.equals(address1.address)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (address.equals(((AddressImpl) o).address))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -274,4 +274,15 @@ public class AddressImplTest extends ActiveMQTestBase {
|
||||||
Assert.assertFalse(a1.matches(w));
|
Assert.assertFalse(a1.matches(w));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://issues.apache.org/jira/browse/ARTEMIS-1890
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testV() {
|
||||||
|
final SimpleString s1 = new SimpleString("a.b.d");
|
||||||
|
final SimpleString s3 = new SimpleString("a.b.#.d");
|
||||||
|
final Address a1 = new AddressImpl(s1);
|
||||||
|
final Address w = new AddressImpl(s3);
|
||||||
|
Assert.assertTrue(a1.matches(w));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue