/******************************************************************************* * Copyright (c) 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.buckminster.osgi.filter.test; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.Dictionary; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.eclipse.buckminster.osgi.filter.Filter; import org.eclipse.buckminster.osgi.filter.FilterFactory; import org.osgi.framework.Bundle; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; @SuppressWarnings("unchecked") public class FilterTests extends TestCase { private static class DictionaryServiceReference implements ServiceReference<Object> { private final Map<String, Object> dictionary; private final String[] keys; DictionaryServiceReference(Map<String, 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<String> i = keyList.iterator(); i.hasNext();) { if(key.equalsIgnoreCase(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<SampleComparable> { private int value = -1; public SampleComparable(String value) { this.value = Integer.parseInt(value); } public int compareTo(SampleComparable o) { return value - 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(FilterTests.class); } public void testComparable() throws Exception { Filter f1 = FilterFactory.newInstance("(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.matches(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.matches(hash)); //$NON-NLS-1$ assertTrue("does not match filter", f1.match(new DictionaryServiceReference(hash))); //$NON-NLS-1$ Filter f2 = null; try { f2 = FilterFactory.newInstance("(comparable=42)"); //$NON-NLS-1$ } catch(InvalidSyntaxException e) { fail("invalid syntax" + e); //$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.matches(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.matches(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() { Dictionary<String,Object> props = new Hashtable<String, Object>(); props.put("room", "bedroom"); //$NON-NLS-1$ //$NON-NLS-2$ props.put("channel", new Object[] { new Integer(34), "101" }); //$NON-NLS-1$//$NON-NLS-2$ props.put("status", "(on\\)*"); //$NON-NLS-1$//$NON-NLS-2$ Vector<Comparable<?>> vec = new Vector<Comparable<?>>(10, 10); vec.addElement(new Long(150)); vec.addElement("100"); //$NON-NLS-1$ props.put("max record time", vec); //$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<String,String>()); //$NON-NLS-1$ props.put("PrimIntArrayValue", new int[] { 1, 2, 3 }); //$NON-NLS-1$ props.put("PrimLongArrayValue", new long[] { 1, 2, 3 }); //$NON-NLS-1$ props.put("PrimByteArrayValue", new byte[] { (byte)1, (byte)2, (byte)3 }); //$NON-NLS-1$ props.put("PrimShortArrayValue", new short[] { (short)1, (short)2, (short)3 }); //$NON-NLS-1$ props.put("PrimFloatArrayValue", new float[] { (float)1.1, (float)2.2, (float)3.3 }); //$NON-NLS-1$ props.put("PrimDoubleArrayValue", new double[] { 1.1, 2.2, 3.3 }); //$NON-NLS-1$ props.put("PrimCharArrayValue", new char[] { 'A', 'b', 'C', 'd' }); //$NON-NLS-1$ props.put("PrimBooleanArrayValue", new boolean[] { false }); //$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("(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=101)) ", 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(" (canRecord =true\\(x\\)) ", props, ISTRUE); //$NON-NLS-1$ testFilter("(max Record Time <=140) ", props, ISTRUE); //$NON-NLS-1$ testFilter("(shortValue >= 100) ", props, ISTRUE); //$NON-NLS-1$ testFilter(" ( & ( byteValue <= 100 ) ( byteValue >= 10 ) ) ", props, ISTRUE); //$NON-NLS-1$ testFilter("(weirdValue = 100) ", props, ISFALSE); //$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("(primIntArrayValue = 1) ", props, ISTRUE); //$NON-NLS-1$ testFilter("(primLongArrayValue = 2) ", props, ISTRUE); //$NON-NLS-1$ testFilter("(primByteArrayValue = 3) ", props, ISTRUE); //$NON-NLS-1$ testFilter("(primShortArrayValue = 1) ", props, ISTRUE); //$NON-NLS-1$ testFilter("(primFloatArrayValue = 1.1) ", props, ISTRUE); //$NON-NLS-1$ testFilter("(primDoubleArrayValue = 2.2) ", props, ISTRUE); //$NON-NLS-1$ testFilter("(primCharArrayValue ~= D) ", props, ISTRUE); //$NON-NLS-1$ testFilter("(primBooleanArrayValue = 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("()", 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 = FilterFactory.newInstance("( a = bedroom )"); //$NON-NLS-1$ Filter f2 = FilterFactory.newInstance(" (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 = FilterFactory.newInstance("(|(a=1)(&(a=1)(b=1)))"); //$NON-NLS-1$ f2 = FilterFactory.newInstance("(a=1)"); //$NON-NLS-1$ System.out.println(f2.toString()); System.out.println(f1.toString()); f1 = FilterFactory.newInstance("(|(&(os=macos)(ws=cocoa)(arch=x86))(&(ws=cocoa)(os=macos)(arch=ppc)))"); //$NON-NLS-1$ f2 = FilterFactory.newInstance("(&(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 = FilterFactory.newInstance("(&(|(x=a)(y=b)(z=a))(|(x=a)(y=b)(z=b)))"); //$NON-NLS-1$ f2 = FilterFactory.newInstance("(|(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 = FilterFactory.newInstance("(&(a=1)(|(a=1)(b=1)))"); //$NON-NLS-1$ f2 = FilterFactory.newInstance("(a=1)"); //$NON-NLS-1$ System.out.println(f2.toString()); System.out.println(f1.toString()); f1 = FilterFactory.newInstance("(|(a=1)(&(a=1)(b=1)))"); //$NON-NLS-1$ f2 = FilterFactory.newInstance("(a=1)"); //$NON-NLS-1$ System.out.println(f2.toString()); System.out.println(f1.toString()); assertEquals("not equal", f1, f2); //$NON-NLS-1$ } catch(InvalidSyntaxException e) { fail("unexpected invalid syntax: " + e); //$NON-NLS-1$ } } private void testFilter(String query, Dictionary<String,Object> props, int expect) { final ServiceReference<Object> ref = new DictionaryServiceReference((Map<String, Object>)props); Filter f1; try { f1 = FilterFactory.newInstance(query); if(expect == ISILLEGAL) { fail("expected exception"); //$NON-NLS-1$ } } catch(InvalidSyntaxException 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$ Filter f2; try { f2 = FilterFactory.newInstance(query); if(expect == ISILLEGAL) { fail("expected exception"); //$NON-NLS-1$ } } catch(InvalidSyntaxException e) { if(expect != ISILLEGAL) { fail("exception: " + e.toString()); //$NON-NLS-1$ } return; } val = f2.match(props); assertEquals("wrong result", expect == ISTRUE, val); //$NON-NLS-1$ val = f2.match(ref); assertEquals("wrong result", expect == ISTRUE, val); //$NON-NLS-1$ assertEquals("not equal", f1, f2); //$NON-NLS-1$ } }