blob: cf3cba55214c04cf4c410e8ab3609c79a90a47bf [file] [log] [blame]
package org.eclipse.equinox.p2.tests.metadata.expression;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import junit.framework.*;
import org.eclipse.equinox.p2.metadata.expression.*;
import org.osgi.framework.*;
public class FilterTest extends TestCase {
private static class DictionaryServiceReference implements ServiceReference {
private final Map<String, ? extends Object> dictionary;
private final String[] keys;
DictionaryServiceReference(Map<String, ? extends Object> dictionary) {
if (dictionary == null) {
this.dictionary = null;
this.keys = new String[] {};
return;
}
this.dictionary = dictionary;
List<String> keyList = new ArrayList<String>(dictionary.size());
for (Iterator<String> e = dictionary.keySet().iterator(); e.hasNext();) {
String key = e.next();
for (Iterator i = keyList.iterator(); i.hasNext();) {
if (key.equalsIgnoreCase((String) i.next())) {
throw new IllegalArgumentException();
}
}
keyList.add(key);
}
this.keys = keyList.toArray(new String[keyList.size()]);
}
public int compareTo(Object reference) {
throw new UnsupportedOperationException();
}
public Bundle getBundle() {
return null;
}
public Object getProperty(String k) {
for (int i = 0, length = keys.length; i < length; i++) {
String key = keys[i];
if (key.equalsIgnoreCase(k)) {
return dictionary.get(key);
}
}
return null;
}
public String[] getPropertyKeys() {
return keys.clone();
}
public Bundle[] getUsingBundles() {
throw new UnsupportedOperationException();
}
public boolean isAssignableTo(Bundle bundle, String className) {
throw new UnsupportedOperationException();
}
}
private static class SampleComparable implements Comparable {
private int value = -1;
public SampleComparable(String value) {
this.value = Integer.parseInt(value);
}
public boolean equals(Object o) {
return o instanceof SampleComparable && value == ((SampleComparable) o).value;
}
public int compareTo(Object o) {
return value - ((SampleComparable) o).value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}
static final int ISTRUE = 1;
static final int ISFALSE = 2;
static final int ISILLEGAL = 3;
public static Test suite() {
return new TestSuite(FilterTest.class);
}
public void testComparable() throws Exception {
IFilterExpression f1 = ExpressionUtil.parseLDAP("(comparable=42)"); //$NON-NLS-1$
Object comp;
Map<String, Object> hash = new HashMap<String, Object>();
comp = new SampleComparable("42"); //$NON-NLS-1$
hash.put("comparable", comp); //$NON-NLS-1$
assertTrue("does not match filter", f1.match(hash)); //$NON-NLS-1$
assertTrue("does not match filter", f1.match(new DictionaryServiceReference(hash))); //$NON-NLS-1$
comp = new Long(42);
hash.put("comparable", comp); //$NON-NLS-1$
assertTrue("does not match filter", f1.match(hash)); //$NON-NLS-1$
assertTrue("does not match filter", f1.match(new DictionaryServiceReference(hash))); //$NON-NLS-1$
IFilterExpression f2 = ExpressionUtil.parseLDAP("(comparable=42)"); //$NON-NLS-1$
hash = new Hashtable<String, Object>();
comp = new SampleComparable("42"); //$NON-NLS-1$
hash.put("comparable", comp); //$NON-NLS-1$
assertTrue("does not match filter", f2.match(hash)); //$NON-NLS-1$
assertTrue("does not match filter", f2.match(new DictionaryServiceReference(hash))); //$NON-NLS-1$
comp = new Long(42);
hash.put("comparable", comp); //$NON-NLS-1$
assertTrue("does not match filter", f2.match(hash)); //$NON-NLS-1$
assertTrue("does not match filter", f2.match(new DictionaryServiceReference(hash))); //$NON-NLS-1$
assertEquals("not equal", f1, f2); //$NON-NLS-1$
}
public void testFilter() {
Properties props = new Properties();
props.put("room", "bedroom"); //$NON-NLS-1$ //$NON-NLS-2$
props.put("channel", new Integer(34)); //$NON-NLS-1$
props.put("status", "(on\\)*"); //$NON-NLS-1$//$NON-NLS-2$
props.put("max record time", new Long(150)); //$NON-NLS-1$
props.put("canrecord", "true(x)"); //$NON-NLS-1$ //$NON-NLS-2$
props.put("shortvalue", new Short((short) 1000)); //$NON-NLS-1$
props.put("bytevalue", new Byte((byte) 10)); //$NON-NLS-1$
props.put("floatvalue", new Float(1.01)); //$NON-NLS-1$
props.put("doublevalue", new Double(2.01)); //$NON-NLS-1$
props.put("charvalue", new Character('A')); //$NON-NLS-1$
props.put("booleanvalue", new Boolean(false)); //$NON-NLS-1$
props.put("weirdvalue", new Hashtable()); //$NON-NLS-1$
try {
props.put("bigintvalue", new BigInteger("4123456")); //$NON-NLS-1$ //$NON-NLS-2$
} catch (NoClassDefFoundError e) {
// ignore
}
try {
props.put("bigdecvalue", new BigDecimal("4.123456")); //$NON-NLS-1$ //$NON-NLS-2$
} catch (NoClassDefFoundError e) {
// ignore
}
testFilter("(room=*)", props, ISTRUE); //$NON-NLS-1$
testFilter("(rooom=*)", props, ISFALSE); //$NON-NLS-1$
testFilter("(room=bedroom)", props, ISTRUE); //$NON-NLS-1$
testFilter("(room~= B E D R O O M )", props, ISTRUE); //$NON-NLS-1$
testFilter("(room=abc)", props, ISFALSE); //$NON-NLS-1$
testFilter(" ( room >=aaaa)", props, ISTRUE); //$NON-NLS-1$
testFilter("(room <=aaaa)", props, ISFALSE); //$NON-NLS-1$
testFilter(" ( room =b*) ", props, ISTRUE); //$NON-NLS-1$
testFilter(" ( room =*m) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(room=bed*room)", props, ISTRUE); //$NON-NLS-1$
testFilter(" ( room =b*oo*m) ", props, ISTRUE); //$NON-NLS-1$
testFilter(" ( room =*b*oo*m*) ", props, ISTRUE); //$NON-NLS-1$
testFilter(" ( room =b*b* *m*) ", props, ISFALSE); //$NON-NLS-1$
testFilter(" (& (room =bedroom) (channel = 34))", props, ISTRUE); //$NON-NLS-1$
testFilter(" (& (room =b*) (room =*x) (channel=34))", props, ISFALSE); //$NON-NLS-1$
testFilter("(| (room =bed*)(channel=222)) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(| (room =boom*)(channel=34)) ", props, ISTRUE); //$NON-NLS-1$
testFilter(" (! (room =ab*b*oo*m*) ) ", props, ISTRUE); //$NON-NLS-1$
testFilter(" (status =\\(o*\\\\\\)\\*) ", props, ISTRUE); //$NON-NLS-1$
testFilter(" (status =\\28o*\\5c\\29\\2a) ", props, ISTRUE); //$NON-NLS-1$
testFilter(" (status =\\28o*\\5C\\29\\2A) ", props, ISTRUE); //$NON-NLS-1$
testFilter(" (canRecord =true\\(x\\)) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(max Record Time <=150) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(shortValue >= 100) ", props, ISTRUE); //$NON-NLS-1$
testFilter(" ( & ( byteValue <= 100 ) ( byteValue >= 10 ) ) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(bigIntValue = 4123456) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(bigDecValue = 4.123456) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(floatValue >= 1.0) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(doubleValue <= 2.011) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(charValue ~= a) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(booleanValue = false) ", props, ISTRUE); //$NON-NLS-1$
testFilter("(& (| (room =d*m) (room =bed*) (room=abc)) (! (channel=999)))", props, ISTRUE); //$NON-NLS-1$
testFilter("(room=bedroom)", null, ISFALSE); //$NON-NLS-1$
testFilter("()", props, ISILLEGAL); //$NON-NLS-1$
testFilter("(=foo)", props, ISILLEGAL); //$NON-NLS-1$
testFilter("(", props, ISILLEGAL); //$NON-NLS-1$
testFilter("(abc = ))", props, ISILLEGAL); //$NON-NLS-1$
testFilter("(& (abc = xyz) (& (345))", props, ISILLEGAL); //$NON-NLS-1$
testFilter(" (room = b**oo!*m*) ) ", props, ISILLEGAL); //$NON-NLS-1$
testFilter(" (room = b**oo)*m*) ) ", props, ISILLEGAL); //$NON-NLS-1$
testFilter(" (room = *=b**oo*m*) ) ", props, ISILLEGAL); //$NON-NLS-1$
testFilter(" (room = =b**oo*m*) ) ", props, ISILLEGAL); //$NON-NLS-1$
try {
Filter f1 = ExpressionUtil.parseLDAP("( a = bedroom )"); //$NON-NLS-1$
Filter f2 = ExpressionUtil.parseLDAP(" (a= bedroom ) "); //$NON-NLS-1$
assertEquals("not equal", "(a= bedroom )", f1.toString()); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals("not equal", "(a= bedroom )", f2.toString()); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals("not equal", f1, f2); //$NON-NLS-1$
assertEquals("not equal", f2, f1); //$NON-NLS-1$
assertEquals("not equal", f1.hashCode(), f2.hashCode()); //$NON-NLS-1$
f1 = ExpressionUtil.parseLDAP("(status =\\28o*\\5c\\29\\2a)");
assertEquals("not equal", "(status=\\28o*\\5c\\29\\2a)", f1.toString()); //$NON-NLS-1$ //$NON-NLS-2$
f1 = ExpressionUtil.parseLDAP("(|(a=1)(&(a=1)(b=1)))"); //$NON-NLS-1$
f2 = ExpressionUtil.parseLDAP("(a=1)"); //$NON-NLS-1$
System.out.println(f2.toString());
System.out.println(f1.toString());
f1 = ExpressionUtil.parseLDAP("(|(&(os=macos)(ws=cocoa)(arch=x86))(&(ws=cocoa)(os=macos)(arch=ppc)))"); //$NON-NLS-1$
f2 = ExpressionUtil.parseLDAP("(&(os=macos)(ws=cocoa)(|(arch=x86)(arch=ppc)))"); //$NON-NLS-1$
System.out.println(f2.toString());
System.out.println(f1.toString());
assertEquals("not equal", f1, f2); //$NON-NLS-1$
f1 = ExpressionUtil.parseLDAP("(&(|(x=a)(y=b)(z=a))(|(x=a)(y=b)(z=b)))"); //$NON-NLS-1$
f2 = ExpressionUtil.parseLDAP("(|(x=a)(y=b)(&(z=a)(z=b)))"); //$NON-NLS-1$
System.out.println(f2.toString());
System.out.println(f1.toString());
assertEquals("not equal", f1, f2); //$NON-NLS-1$
f1 = ExpressionUtil.parseLDAP("(&(a=1)(|(a=1)(b=1)))"); //$NON-NLS-1$
f2 = ExpressionUtil.parseLDAP("(a=1)"); //$NON-NLS-1$
System.out.println(f2.toString());
System.out.println(f1.toString());
f1 = ExpressionUtil.parseLDAP("(|(a=1)(&(a=1)(b=1)))"); //$NON-NLS-1$
f2 = ExpressionUtil.parseLDAP("(a=1)"); //$NON-NLS-1$
System.out.println(f2.toString());
System.out.println(f1.toString());
assertEquals("not equal", f1, f2); //$NON-NLS-1$
} catch (IllegalArgumentException e) {
fail("unexpected invalid syntax: " + e); //$NON-NLS-1$
}
testFilter("(weirdValue = 100) ", props, ISFALSE); //$NON-NLS-1$
}
private void testFilter(String query, Dictionary<?, ?> props, int expect) {
final ServiceReference ref = new DictionaryServiceReference((Map) props);
Filter f1;
try {
f1 = ExpressionUtil.parseLDAP(query);
if (expect == ISILLEGAL) {
fail("expected exception"); //$NON-NLS-1$
}
} catch (ExpressionParseException e) {
System.out.println(e.toString());
if (expect != ISILLEGAL) {
fail("exception: " + e.toString()); //$NON-NLS-1$
}
return;
}
boolean val = f1.match(props);
assertEquals("wrong result", expect == ISTRUE, val); //$NON-NLS-1$
val = f1.match(ref);
assertEquals("wrong result", expect == ISTRUE, val); //$NON-NLS-1$
}
}