diff options
author | Thomas Watson | 2018-02-20 14:30:02 +0000 |
---|---|---|
committer | Thomas Watson | 2018-02-20 14:31:38 +0000 |
commit | 2d6be23f55e3a7e87b18708597c0a0afac8bf2be (patch) | |
tree | 760abad791bc21e6eed61960ec2b13164ce0b69e /bundles | |
parent | 40b6fcec3631651554c6f8a02df558995460d3df (diff) | |
download | rt.equinox.framework-2d6be23f55e3a7e87b18708597c0a0afac8bf2be.tar.gz rt.equinox.framework-2d6be23f55e3a7e87b18708597c0a0afac8bf2be.tar.xz rt.equinox.framework-2d6be23f55e3a7e87b18708597c0a0afac8bf2be.zip |
Bug 510638 - Remove FrameworkUtil implementation of FilterI20180222-2000I20180221-2000I20180220-2000
Change-Id: If925792266cbc58f8ebdd03cc8fa14d7f20ccb65
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
Diffstat (limited to 'bundles')
-rw-r--r-- | bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java | 1495 |
1 files changed, 1 insertions, 1494 deletions
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java index 90d50e4d3..558807664 100644 --- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java +++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java @@ -34,6 +34,7 @@ import java.util.Map; import java.util.Set; import javax.security.auth.x500.X500Principal; +import org.eclipse.osgi.internal.framework.FilterImpl; /** * Framework Utility class. @@ -220,1500 +221,6 @@ public class FrameworkUtil { } /** - * RFC 1960-based Filter. Filter objects can be created by calling the - * constructor with the desired filter string. A Filter object can be called - * numerous times to determine if the match argument matches the filter - * string that was used to create the Filter object. - * - * <p> - * The syntax of a filter string is the string representation of LDAP search - * filters as defined in RFC 1960: <i>A String Representation of LDAP Search - * Filters</i> (available at http://www.ietf.org/rfc/rfc1960.txt). It should - * be noted that RFC 2254: <i>A String Representation of LDAP Search - * Filters</i> (available at http://www.ietf.org/rfc/rfc2254.txt) supersedes - * RFC 1960 but only adds extensible matching and is not applicable for this - * API. - * - * <p> - * The string representation of an LDAP search filter is defined by the - * following grammar. It uses a prefix format. - * - * <pre> - * <filter> ::= '(' <filtercomp> ')' - * <filtercomp> ::= <and> | <or> | <not> | <item> - * <and> ::= '&' <filterlist> - * <or> ::= '|' <filterlist> - * <not> ::= '!' <filter> - * <filterlist> ::= <filter> | <filter> <filterlist> - * <item> ::= <simple> | <present> | <substring> - * <simple> ::= <attr> <filtertype> <value> - * <filtertype> ::= <equal> | <approx> | <greater> | <less> - * <equal> ::= '=' - * <approx> ::= '˜=' - * <greater> ::= '>=' - * <less> ::= '<=' - * <present> ::= <attr> '=*' - * <substring> ::= <attr> '=' <initial> <any> <final> - * <initial> ::= NULL | <value> - * <any> ::= '*' <starval> - * <starval> ::= NULL | <value> '*' <starval> - * <final> ::= NULL | <value> - * </pre> - * - * {@code <attr>} is a string representing an attribute, or key, in - * the properties objects of the registered services. Attribute names are - * not case sensitive; that is cn and CN both refer to the same attribute. - * {@code <value>} is a string representing the value, or part of one, - * of a key in the properties objects of the registered services. If a - * {@code <value>} must contain one of the characters ' {@code *}' or - * '{@code (}' or '{@code )}', these characters should be escaped by - * preceding them with the backslash '{@code \}' character. Note that - * although both the {@code <substring>} and {@code <present>} - * productions can produce the {@code 'attr=*'} construct, this construct is - * used only to denote a presence filter. - * - * <p> - * Examples of LDAP filters are: - * - * <pre> - * "(cn=Babs Jensen)" - * "(!(cn=Tim Howes))" - * "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))" - * "(o=univ*of*mich*)" - * </pre> - * - * <p> - * The approximate match ({@code ~=}) is implementation specific but should - * at least ignore case and white space differences. Optional are codes like - * soundex or other smart "closeness" comparisons. - * - * <p> - * Comparison of values is not straightforward. Strings are compared - * differently than numbers and it is possible for a key to have multiple - * values. Note that that keys in the match argument must always be strings. - * The comparison is defined by the object type of the key's value. The - * following rules apply for comparison: - * - * <blockquote> - * <TABLE BORDER=0> - * <TR> - * <TD><b>Property Value Type </b></TD> - * <TD><b>Comparison Type</b></TD> - * </TR> - * <TR> - * <TD>String</TD> - * <TD>String comparison</TD> - * </TR> - * <TR valign=top> - * <TD>Integer, Long, Float, Double, Byte, Short, BigInteger, BigDecimal</TD> - * <TD>numerical comparison</TD> - * </TR> - * <TR> - * <TD>Character</TD> - * <TD>character comparison</TD> - * </TR> - * <TR> - * <TD>Boolean</TD> - * <TD>equality comparisons only</TD> - * </TR> - * <TR> - * <TD>[] (array)</TD> - * <TD>recursively applied to values</TD> - * </TR> - * <TR> - * <TD>Collection</TD> - * <TD>recursively applied to values</TD> - * </TR> - * </TABLE> - * Note: arrays of primitives are also supported. </blockquote> - * - * A filter matches a key that has multiple values if it matches at least - * one of those values. For example, - * - * <pre> - * Dictionary d = new Hashtable(); - * d.put("cn", new String[] {"a", "b", "c"}); - * </pre> - * - * d will match {@code (cn=a)} and also {@code (cn=b)} - * - * <p> - * A filter component that references a key having an unrecognizable data - * type will evaluate to {@code false} . - */ - static private final class FilterImpl implements Filter { - /* filter operators */ - private static final int EQUAL = 1; - private static final int APPROX = 2; - private static final int GREATER = 3; - private static final int LESS = 4; - private static final int PRESENT = 5; - private static final int SUBSTRING = 6; - private static final int AND = 7; - private static final int OR = 8; - private static final int NOT = 9; - - /** filter operation */ - private final int op; - /** filter attribute or null if operation AND, OR or NOT */ - private final String attr; - /** filter operands */ - private final Object value; - - /* normalized filter string for Filter object */ - private transient String filterString; - - /** - * Constructs a {@link FilterImpl} object. This filter object may be - * used to match a {@link ServiceReference} or a Dictionary. - * - * <p> - * If the filter cannot be parsed, an {@link InvalidSyntaxException} - * will be thrown with a human readable message where the filter became - * unparsable. - * - * @param filterString the filter string. - * @throws InvalidSyntaxException If the filter parameter contains an - * invalid filter string that cannot be parsed. - */ - static FilterImpl newInstance(String filterString) throws InvalidSyntaxException { - return new Parser(filterString).parse(); - } - - FilterImpl(int operation, String attr, Object value) { - this.op = operation; - this.attr = attr; - this.value = value; - filterString = null; - } - - /** - * Filter using a service's properties. - * <p> - * This {@code Filter} is executed using the keys and values of the - * referenced service's properties. The keys are looked up in a case - * insensitive manner. - * - * @param reference The reference to the service whose properties are - * used in the match. - * @return {@code true} if the service's properties match this - * {@code Filter}; {@code false} otherwise. - */ - @Override - public boolean match(ServiceReference<?> reference) { - return matches(new ServiceReferenceMap(reference)); - } - - /** - * Filter using a {@code Dictionary} with case insensitive key lookup. - * This {@code Filter} is executed using the specified - * {@code Dictionary}'s keys and values. The keys are looked up in a - * case insensitive manner. - * - * @param dictionary The {@code Dictionary} whose key/value pairs are - * used in the match. - * @return {@code true} if the {@code Dictionary}'s values match this - * filter; {@code false} otherwise. - * @throws IllegalArgumentException If {@code dictionary} contains case - * variants of the same key name. - */ - @Override - public boolean match(Dictionary<String, ?> dictionary) { - return matches(new CaseInsensitiveMap(dictionary)); - } - - /** - * Filter using a {@code Dictionary}. This {@code Filter} is executed - * using the specified {@code Dictionary}'s keys and values. The keys - * are looked up in a normal manner respecting case. - * - * @param dictionary The {@code Dictionary} whose key/value pairs are - * used in the match. - * @return {@code true} if the {@code Dictionary}'s values match this - * filter; {@code false} otherwise. - * @since 1.3 - */ - @Override - public boolean matchCase(Dictionary<String, ?> dictionary) { - switch (op) { - case AND : { - FilterImpl[] filters = (FilterImpl[]) value; - for (FilterImpl f : filters) { - if (!f.matchCase(dictionary)) { - return false; - } - } - return true; - } - - case OR : { - FilterImpl[] filters = (FilterImpl[]) value; - for (FilterImpl f : filters) { - if (f.matchCase(dictionary)) { - return true; - } - } - return false; - } - - case NOT : { - FilterImpl filter = (FilterImpl) value; - return !filter.matchCase(dictionary); - } - - case SUBSTRING : - case EQUAL : - case GREATER : - case LESS : - case APPROX : { - Object prop = (dictionary == null) ? null : dictionary.get(attr); - return compare(op, prop, value); - } - - case PRESENT : { - Object prop = (dictionary == null) ? null : dictionary.get(attr); - return prop != null; - } - } - - return false; - } - - /** - * Filter using a {@code Map}. This {@code Filter} is executed using the - * specified {@code Map}'s keys and values. The keys are looked up in a - * normal manner respecting case. - * - * @param map The {@code Map} whose key/value pairs are used in the - * match. Maps with {@code null} key or values are not supported. - * A {@code null} value is considered not present to the filter. - * @return {@code true} if the {@code Map}'s values match this filter; - * {@code false} otherwise. - * @since 1.6 - */ - @Override - public boolean matches(Map<String, ?> map) { - switch (op) { - case AND : { - FilterImpl[] filters = (FilterImpl[]) value; - for (FilterImpl f : filters) { - if (!f.matches(map)) { - return false; - } - } - return true; - } - - case OR : { - FilterImpl[] filters = (FilterImpl[]) value; - for (FilterImpl f : filters) { - if (f.matches(map)) { - return true; - } - } - return false; - } - - case NOT : { - FilterImpl filter = (FilterImpl) value; - return !filter.matches(map); - } - - case SUBSTRING : - case EQUAL : - case GREATER : - case LESS : - case APPROX : { - Object prop = (map == null) ? null : map.get(attr); - return compare(op, prop, value); - } - - case PRESENT : { - Object prop = (map == null) ? null : map.get(attr); - return prop != null; - } - } - - return false; - } - - /** - * Returns this {@code Filter}'s filter string. - * <p> - * The filter string is normalized by removing whitespace which does not - * affect the meaning of the filter. - * - * @return This {@code Filter}'s filter string. - */ - @Override - public String toString() { - String result = filterString; - if (result == null) { - filterString = result = normalize().toString(); - } - return result; - } - - /** - * Returns this {@code Filter}'s normalized filter string. - * <p> - * The filter string is normalized by removing whitespace which does not - * affect the meaning of the filter. - * - * @return This {@code Filter}'s filter string. - */ - private StringBuilder normalize() { - StringBuilder sb = new StringBuilder(); - sb.append('('); - - switch (op) { - case AND : { - sb.append('&'); - - FilterImpl[] filters = (FilterImpl[]) value; - for (FilterImpl f : filters) { - sb.append(f.normalize()); - } - - break; - } - - case OR : { - sb.append('|'); - - FilterImpl[] filters = (FilterImpl[]) value; - for (FilterImpl f : filters) { - sb.append(f.normalize()); - } - - break; - } - - case NOT : { - sb.append('!'); - FilterImpl filter = (FilterImpl) value; - sb.append(filter.normalize()); - - break; - } - - case SUBSTRING : { - sb.append(attr); - sb.append('='); - - String[] substrings = (String[]) value; - - for (String substr : substrings) { - if (substr == null) /* * */{ - sb.append('*'); - } else /* xxx */{ - sb.append(encodeValue(substr)); - } - } - - break; - } - case EQUAL : { - sb.append(attr); - sb.append('='); - sb.append(encodeValue((String) value)); - - break; - } - case GREATER : { - sb.append(attr); - sb.append(">="); - sb.append(encodeValue((String) value)); - - break; - } - case LESS : { - sb.append(attr); - sb.append("<="); - sb.append(encodeValue((String) value)); - - break; - } - case APPROX : { - sb.append(attr); - sb.append("~="); - sb.append(encodeValue(approxString((String) value))); - - break; - } - - case PRESENT : { - sb.append(attr); - sb.append("=*"); - - break; - } - } - - sb.append(')'); - - return sb; - } - - /** - * Compares this {@code Filter} to another {@code Filter}. - * - * <p> - * This implementation returns the result of calling - * {@code this.toString().equals(obj.toString()}. - * - * @param obj The object to compare against this {@code Filter}. - * @return If the other object is a {@code Filter} object, then returns - * the result of calling - * {@code this.toString().equals(obj.toString()}; {@code false} - * otherwise. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof Filter)) { - return false; - } - - return this.toString().equals(obj.toString()); - } - - /** - * Returns the hashCode for this {@code Filter}. - * - * <p> - * This implementation returns the result of calling - * {@code this.toString().hashCode()}. - * - * @return The hashCode of this {@code Filter}. - */ - @Override - public int hashCode() { - return this.toString().hashCode(); - } - - /** - * Encode the value string such that '(', '*', ')' and '\' are escaped. - * - * @param value unencoded value string. - * @return encoded value string. - */ - private static String encodeValue(String value) { - boolean encoded = false; - int inlen = value.length(); - int outlen = inlen << 1; /* inlen 2 */ - - char[] output = new char[outlen]; - value.getChars(0, inlen, output, inlen); - - int cursor = 0; - for (int i = inlen; i < outlen; i++) { - char c = output[i]; - - switch (c) { - case '(' : - case '*' : - case ')' : - case '\\' : { - output[cursor] = '\\'; - cursor++; - encoded = true; - - break; - } - } - - output[cursor] = c; - cursor++; - } - - return encoded ? new String(output, 0, cursor) : value; - } - - private boolean compare(int operation, Object value1, Object value2) { - if (value1 == null) { - return false; - } - if (value1 instanceof String) { - return compare_String(operation, (String) value1, value2); - } - if (value1 instanceof Version) { - return compare_Version(operation, (Version) value1, value2); - } - - Class<?> clazz = value1.getClass(); - if (clazz.isArray()) { - Class<?> type = clazz.getComponentType(); - if (type.isPrimitive()) { - return compare_PrimitiveArray(operation, type, value1, value2); - } - return compare_ObjectArray(operation, (Object[]) value1, value2); - } - if (value1 instanceof Collection<?>) { - return compare_Collection(operation, (Collection<?>) value1, value2); - } - if (value1 instanceof Integer) { - return compare_Integer(operation, ((Integer) value1).intValue(), value2); - } - if (value1 instanceof Long) { - return compare_Long(operation, ((Long) value1).longValue(), value2); - } - if (value1 instanceof Byte) { - return compare_Byte(operation, ((Byte) value1).byteValue(), value2); - } - if (value1 instanceof Short) { - return compare_Short(operation, ((Short) value1).shortValue(), value2); - } - if (value1 instanceof Character) { - return compare_Character(operation, ((Character) value1).charValue(), value2); - } - if (value1 instanceof Float) { - return compare_Float(operation, ((Float) value1).floatValue(), value2); - } - if (value1 instanceof Double) { - return compare_Double(operation, ((Double) value1).doubleValue(), value2); - } - if (value1 instanceof Boolean) { - return compare_Boolean(operation, ((Boolean) value1).booleanValue(), value2); - } - if (value1 instanceof Comparable<?>) { - @SuppressWarnings("unchecked") - Comparable<Object> comparable = (Comparable<Object>) value1; - return compare_Comparable(operation, comparable, value2); - } - return compare_Unknown(operation, value1, value2); - } - - private boolean compare_Collection(int operation, Collection<?> collection, Object value2) { - for (Object value1 : collection) { - if (compare(operation, value1, value2)) { - return true; - } - } - return false; - } - - private boolean compare_ObjectArray(int operation, Object[] array, Object value2) { - for (Object value1 : array) { - if (compare(operation, value1, value2)) { - return true; - } - } - return false; - } - - private boolean compare_PrimitiveArray(int operation, Class<?> type, Object primarray, Object value2) { - if (Integer.TYPE.isAssignableFrom(type)) { - int[] array = (int[]) primarray; - for (int value1 : array) { - if (compare_Integer(operation, value1, value2)) { - return true; - } - } - return false; - } - if (Long.TYPE.isAssignableFrom(type)) { - long[] array = (long[]) primarray; - for (long value1 : array) { - if (compare_Long(operation, value1, value2)) { - return true; - } - } - return false; - } - if (Byte.TYPE.isAssignableFrom(type)) { - byte[] array = (byte[]) primarray; - for (byte value1 : array) { - if (compare_Byte(operation, value1, value2)) { - return true; - } - } - return false; - } - if (Short.TYPE.isAssignableFrom(type)) { - short[] array = (short[]) primarray; - for (short value1 : array) { - if (compare_Short(operation, value1, value2)) { - return true; - } - } - return false; - } - if (Character.TYPE.isAssignableFrom(type)) { - char[] array = (char[]) primarray; - for (char value1 : array) { - if (compare_Character(operation, value1, value2)) { - return true; - } - } - return false; - } - if (Float.TYPE.isAssignableFrom(type)) { - float[] array = (float[]) primarray; - for (float value1 : array) { - if (compare_Float(operation, value1, value2)) { - return true; - } - } - return false; - } - if (Double.TYPE.isAssignableFrom(type)) { - double[] array = (double[]) primarray; - for (double value1 : array) { - if (compare_Double(operation, value1, value2)) { - return true; - } - } - return false; - } - if (Boolean.TYPE.isAssignableFrom(type)) { - boolean[] array = (boolean[]) primarray; - for (boolean value1 : array) { - if (compare_Boolean(operation, value1, value2)) { - return true; - } - } - return false; - } - return false; - } - - private boolean compare_String(int operation, String string, Object value2) { - switch (operation) { - case SUBSTRING : { - String[] substrings = (String[]) value2; - int pos = 0; - for (int i = 0, size = substrings.length; i < size; i++) { - String substr = substrings[i]; - - if (i + 1 < size) /* if this is not that last substr */{ - if (substr == null) /* * */{ - String substr2 = substrings[i + 1]; - - if (substr2 == null) /* ** */ - continue; /* ignore first star */ - /* xxx */ - int index = string.indexOf(substr2, pos); - if (index == -1) { - return false; - } - - pos = index + substr2.length(); - if (i + 2 < size) // if there are more - // substrings, increment - // over the string we just - // matched; otherwise need - // to do the last substr - // check - i++; - } else /* xxx */{ - int len = substr.length(); - if (string.regionMatches(pos, substr, 0, len)) { - pos += len; - } else { - return false; - } - } - } else /* last substr */{ - if (substr == null) /* * */{ - return true; - } - /* xxx */ - return string.endsWith(substr); - } - } - - return true; - } - case EQUAL : { - return string.equals(value2); - } - case APPROX : { - string = approxString(string); - String string2 = approxString((String) value2); - - return string.equalsIgnoreCase(string2); - } - case GREATER : { - return string.compareTo((String) value2) >= 0; - } - case LESS : { - return string.compareTo((String) value2) <= 0; - } - } - return false; - } - - private boolean compare_Integer(int operation, int intval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - int intval2; - try { - intval2 = Integer.parseInt(((String) value2).trim()); - } catch (IllegalArgumentException e) { - return false; - } - switch (operation) { - case APPROX : - case EQUAL : { - return intval == intval2; - } - case GREATER : { - return intval >= intval2; - } - case LESS : { - return intval <= intval2; - } - } - return false; - } - - private boolean compare_Long(int operation, long longval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - long longval2; - try { - longval2 = Long.parseLong(((String) value2).trim()); - } catch (IllegalArgumentException e) { - return false; - } - - switch (operation) { - case APPROX : - case EQUAL : { - return longval == longval2; - } - case GREATER : { - return longval >= longval2; - } - case LESS : { - return longval <= longval2; - } - } - return false; - } - - private boolean compare_Byte(int operation, byte byteval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - byte byteval2; - try { - byteval2 = Byte.parseByte(((String) value2).trim()); - } catch (IllegalArgumentException e) { - return false; - } - - switch (operation) { - case APPROX : - case EQUAL : { - return byteval == byteval2; - } - case GREATER : { - return byteval >= byteval2; - } - case LESS : { - return byteval <= byteval2; - } - } - return false; - } - - private boolean compare_Short(int operation, short shortval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - short shortval2; - try { - shortval2 = Short.parseShort(((String) value2).trim()); - } catch (IllegalArgumentException e) { - return false; - } - - switch (operation) { - case APPROX : - case EQUAL : { - return shortval == shortval2; - } - case GREATER : { - return shortval >= shortval2; - } - case LESS : { - return shortval <= shortval2; - } - } - return false; - } - - private boolean compare_Character(int operation, char charval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - char charval2; - try { - charval2 = ((String) value2).charAt(0); - } catch (IndexOutOfBoundsException e) { - return false; - } - - switch (operation) { - case EQUAL : { - return charval == charval2; - } - case APPROX : { - return (charval == charval2) || (Character.toUpperCase(charval) == Character.toUpperCase(charval2)) || (Character.toLowerCase(charval) == Character.toLowerCase(charval2)); - } - case GREATER : { - return charval >= charval2; - } - case LESS : { - return charval <= charval2; - } - } - return false; - } - - private boolean compare_Boolean(int operation, boolean boolval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - boolean boolval2 = Boolean.valueOf(((String) value2).trim()).booleanValue(); - switch (operation) { - case APPROX : - case EQUAL : - case GREATER : - case LESS : { - return boolval == boolval2; - } - } - return false; - } - - private boolean compare_Float(int operation, float floatval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - float floatval2; - try { - floatval2 = Float.parseFloat(((String) value2).trim()); - } catch (IllegalArgumentException e) { - return false; - } - - switch (operation) { - case APPROX : - case EQUAL : { - return Float.compare(floatval, floatval2) == 0; - } - case GREATER : { - return Float.compare(floatval, floatval2) >= 0; - } - case LESS : { - return Float.compare(floatval, floatval2) <= 0; - } - } - return false; - } - - private boolean compare_Double(int operation, double doubleval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - double doubleval2; - try { - doubleval2 = Double.parseDouble(((String) value2).trim()); - } catch (IllegalArgumentException e) { - return false; - } - - switch (operation) { - case APPROX : - case EQUAL : { - return Double.compare(doubleval, doubleval2) == 0; - } - case GREATER : { - return Double.compare(doubleval, doubleval2) >= 0; - } - case LESS : { - return Double.compare(doubleval, doubleval2) <= 0; - } - } - return false; - } - - private static Object valueOf(Class<?> target, String value2) { - do { - Method method; - try { - method = target.getMethod("valueOf", String.class); - } catch (NoSuchMethodException e) { - break; - } - if (Modifier.isStatic(method.getModifiers()) && target.isAssignableFrom(method.getReturnType())) { - setAccessible(method); - try { - return method.invoke(null, value2.trim()); - } catch (IllegalAccessException e) { - return null; - } catch (InvocationTargetException e) { - return null; - } - } - } while (false); - - do { - Constructor<?> constructor; - try { - constructor = target.getConstructor(String.class); - } catch (NoSuchMethodException e) { - break; - } - setAccessible(constructor); - try { - return constructor.newInstance(value2.trim()); - } catch (IllegalAccessException e) { - return null; - } catch (InvocationTargetException e) { - return null; - } catch (InstantiationException e) { - return null; - } - } while (false); - - return null; - } - - private static void setAccessible(AccessibleObject accessible) { - if (!accessible.isAccessible()) { - AccessController.doPrivileged(new SetAccessibleAction(accessible)); - } - } - - private boolean compare_Comparable(int operation, Comparable<Object> value1, Object value2) { - if (operation == SUBSTRING) { - return false; - } - value2 = valueOf(value1.getClass(), (String) value2); - if (value2 == null) { - return false; - } - try { - switch (operation) { - case APPROX : - case EQUAL : { - return value1.compareTo(value2) == 0; - } - case GREATER : { - return value1.compareTo(value2) >= 0; - } - case LESS : { - return value1.compareTo(value2) <= 0; - } - } - } catch (Exception e) { - // if the compareTo method throws an exception; return false - return false; - } - return false; - } - - private boolean compare_Version(int operation, Version value1, Object value2) { - if (operation == SUBSTRING) { - return false; - } - try { - Version version2 = Version.valueOf((String) value2); - switch (operation) { - case APPROX : - case EQUAL : { - return value1.compareTo(version2) == 0; - } - case GREATER : { - return value1.compareTo(version2) >= 0; - } - case LESS : { - return value1.compareTo(version2) <= 0; - } - } - } catch (Exception e) { - // if the valueOf or compareTo method throws an exception - return false; - } - return false; - } - - private boolean compare_Unknown(int operation, Object value1, Object value2) { - if (operation == SUBSTRING) { - return false; - } - value2 = valueOf(value1.getClass(), (String) value2); - if (value2 == null) { - return false; - } - try { - switch (operation) { - case APPROX : - case EQUAL : - case GREATER : - case LESS : { - return value1.equals(value2); - } - } - } catch (Exception e) { - // if the equals method throws an exception; return false - return false; - } - return false; - } - - /** - * Map a string for an APPROX (~=) comparison. - * - * This implementation removes white spaces. This is the minimum - * implementation allowed by the OSGi spec. - * - * @param input Input string. - * @return String ready for APPROX comparison. - */ - private static String approxString(String input) { - boolean changed = false; - char[] output = input.toCharArray(); - int cursor = 0; - for (char c : output) { - if (Character.isWhitespace(c)) { - changed = true; - continue; - } - - output[cursor] = c; - cursor++; - } - - return changed ? new String(output, 0, cursor) : input; - } - - /** - * Parser class for OSGi filter strings. This class parses the complete - * filter string and builds a tree of Filter objects rooted at the - * parent. - */ - static private final class Parser { - private final String filterstring; - private final char[] filterChars; - private int pos; - - Parser(String filterstring) { - this.filterstring = filterstring; - filterChars = filterstring.toCharArray(); - pos = 0; - } - - FilterImpl parse() throws InvalidSyntaxException { - FilterImpl filter; - try { - filter = parse_filter(); - } catch (ArrayIndexOutOfBoundsException e) { - throw new InvalidSyntaxException("Filter ended abruptly", filterstring, e); - } - - if (pos != filterChars.length) { - throw new InvalidSyntaxException("Extraneous trailing characters: " + filterstring.substring(pos), filterstring); - } - return filter; - } - - private FilterImpl parse_filter() throws InvalidSyntaxException { - FilterImpl filter; - skipWhiteSpace(); - - if (filterChars[pos] != '(') { - throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); - } - - pos++; - - filter = parse_filtercomp(); - - skipWhiteSpace(); - - if (filterChars[pos] != ')') { - throw new InvalidSyntaxException("Missing ')': " + filterstring.substring(pos), filterstring); - } - - pos++; - - skipWhiteSpace(); - - return filter; - } - - private FilterImpl parse_filtercomp() throws InvalidSyntaxException { - skipWhiteSpace(); - - char c = filterChars[pos]; - - switch (c) { - case '&' : { - pos++; - return parse_and(); - } - case '|' : { - pos++; - return parse_or(); - } - case '!' : { - pos++; - return parse_not(); - } - } - return parse_item(); - } - - private FilterImpl parse_and() throws InvalidSyntaxException { - int lookahead = pos; - skipWhiteSpace(); - - if (filterChars[pos] != '(') { - pos = lookahead - 1; - return parse_item(); - } - - List<FilterImpl> operands = new ArrayList<FilterImpl>(10); - - while (filterChars[pos] == '(') { - FilterImpl child = parse_filter(); - operands.add(child); - } - - return new FilterImpl(FilterImpl.AND, null, - operands.toArray(new FilterImpl[0])); - } - - private FilterImpl parse_or() throws InvalidSyntaxException { - int lookahead = pos; - skipWhiteSpace(); - - if (filterChars[pos] != '(') { - pos = lookahead - 1; - return parse_item(); - } - - List<FilterImpl> operands = new ArrayList<FilterImpl>(10); - - while (filterChars[pos] == '(') { - FilterImpl child = parse_filter(); - operands.add(child); - } - - return new FilterImpl(FilterImpl.OR, null, - operands.toArray(new FilterImpl[0])); - } - - private FilterImpl parse_not() throws InvalidSyntaxException { - int lookahead = pos; - skipWhiteSpace(); - - if (filterChars[pos] != '(') { - pos = lookahead - 1; - return parse_item(); - } - - FilterImpl child = parse_filter(); - - return new FilterImpl(FilterImpl.NOT, null, child); - } - - private FilterImpl parse_item() throws InvalidSyntaxException { - String attr = parse_attr(); - - skipWhiteSpace(); - - switch (filterChars[pos]) { - case '~' : { - if (filterChars[pos + 1] == '=') { - pos += 2; - return new FilterImpl(FilterImpl.APPROX, attr, parse_value()); - } - break; - } - case '>' : { - if (filterChars[pos + 1] == '=') { - pos += 2; - return new FilterImpl(FilterImpl.GREATER, attr, parse_value()); - } - break; - } - case '<' : { - if (filterChars[pos + 1] == '=') { - pos += 2; - return new FilterImpl(FilterImpl.LESS, attr, parse_value()); - } - break; - } - case '=' : { - if (filterChars[pos + 1] == '*') { - int oldpos = pos; - pos += 2; - skipWhiteSpace(); - if (filterChars[pos] == ')') { - return new FilterImpl(FilterImpl.PRESENT, attr, null); - } - pos = oldpos; - } - - pos++; - Object string = parse_substring(); - - if (string instanceof String) { - return new FilterImpl(FilterImpl.EQUAL, attr, string); - } - return new FilterImpl(FilterImpl.SUBSTRING, attr, string); - } - } - - throw new InvalidSyntaxException("Invalid operator: " + filterstring.substring(pos), filterstring); - } - - private String parse_attr() throws InvalidSyntaxException { - skipWhiteSpace(); - - int begin = pos; - int end = pos; - - char c = filterChars[pos]; - - while (c != '~' && c != '<' && c != '>' && c != '=' && c != '(' && c != ')') { - pos++; - - if (!Character.isWhitespace(c)) { - end = pos; - } - - c = filterChars[pos]; - } - - int length = end - begin; - - if (length == 0) { - throw new InvalidSyntaxException("Missing attr: " + filterstring.substring(pos), filterstring); - } - - return new String(filterChars, begin, length); - } - - private String parse_value() throws InvalidSyntaxException { - StringBuilder sb = new StringBuilder(filterChars.length - pos); - - parseloop: while (true) { - char c = filterChars[pos]; - - switch (c) { - case ')' : { - break parseloop; - } - - case '(' : { - throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), filterstring); - } - - case '\\' : { - pos++; - c = filterChars[pos]; - /* fall through into default */ - } - - default : { - sb.append(c); - pos++; - break; - } - } - } - - if (sb.length() == 0) { - throw new InvalidSyntaxException("Missing value: " + filterstring.substring(pos), filterstring); - } - - return sb.toString(); - } - - private Object parse_substring() throws InvalidSyntaxException { - StringBuilder sb = new StringBuilder(filterChars.length - pos); - - List<String> operands = new ArrayList<String>(10); - - parseloop: while (true) { - char c = filterChars[pos]; - - switch (c) { - case ')' : { - if (sb.length() > 0) { - operands.add(sb.toString()); - } - - break parseloop; - } - - case '(' : { - throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), filterstring); - } - - case '*' : { - if (sb.length() > 0) { - operands.add(sb.toString()); - } - - sb.setLength(0); - - operands.add(null); - pos++; - - break; - } - - case '\\' : { - pos++; - c = filterChars[pos]; - /* fall through into default */ - } - - default : { - sb.append(c); - pos++; - break; - } - } - } - - int size = operands.size(); - - if (size == 0) { - return ""; - } - - if (size == 1) { - Object single = operands.get(0); - - if (single != null) { - return single; - } - } - - return operands.toArray(new String[0]); - } - - private void skipWhiteSpace() { - for (int length = filterChars.length; (pos < length) && Character.isWhitespace(filterChars[pos]);) { - pos++; - } - } - } - } - - /** - * This Map is used for case-insensitive key lookup during filter - * evaluation. This Map implementation only supports the get operation using - * a String key as no other operations are used by the Filter - * implementation. - */ - static private final class CaseInsensitiveMap extends AbstractMap<String, Object> implements Map<String, Object> { - private final Dictionary<String, ?> dictionary; - private final String[] keys; - - /** - * Create a case insensitive map from the specified dictionary. - * - * @param dictionary - * @throws IllegalArgumentException If {@code dictionary} contains case - * variants of the same key name. - */ - CaseInsensitiveMap(Dictionary<String, ?> dictionary) { - if (dictionary == null) { - this.dictionary = null; - this.keys = new String[0]; - return; - } - this.dictionary = dictionary; - List<String> keyList = new ArrayList<String>(dictionary.size()); - for (Enumeration<?> e = dictionary.keys(); e.hasMoreElements();) { - Object k = e.nextElement(); - if (k instanceof String) { - String key = (String) k; - for (String i : keyList) { - if (key.equalsIgnoreCase(i)) { - throw new IllegalArgumentException(); - } - } - keyList.add(key); - } - } - this.keys = keyList.toArray(new String[0]); - } - - @Override - public Object get(Object o) { - String k = (String) o; - for (String key : keys) { - if (key.equalsIgnoreCase(k)) { - return dictionary.get(key); - } - } - return null; - } - - @Override - public Set<java.util.Map.Entry<String, Object>> entrySet() { - throw new UnsupportedOperationException(); - } - } - - /** - * This Map is used for key lookup from a ServiceReference during filter - * evaluation. This Map implementation only supports the get operation using - * a String key as no other operations are used by the Filter - * implementation. - */ - static private final class ServiceReferenceMap extends AbstractMap<String, Object> implements Map<String, Object> { - private final ServiceReference<?> reference; - - ServiceReferenceMap(ServiceReference<?> reference) { - this.reference = reference; - } - - @Override - public Object get(Object key) { - if (reference == null) { - return null; - } - return reference.getProperty((String) key); - } - - @Override - public Set<java.util.Map.Entry<String, Object>> entrySet() { - throw new UnsupportedOperationException(); - } - } - - static private final class SetAccessibleAction implements PrivilegedAction<Void> { - private final AccessibleObject accessible; - - SetAccessibleAction(AccessibleObject accessible) { - this.accessible = accessible; - } - - @Override - public Void run() { - accessible.setAccessible(true); - return null; - } - } - - /** * This class contains a method to match a distinguished name (DN) chain * against and DN chain pattern. * <p> |